47char *MSLGeneratorInterface::msl_patch_default =
nullptr;
50#define FRAGMENT_OUT_STRUCT_NAME "FragmentOut"
51#define FRAGMENT_TILE_IN_STRUCT_NAME "FragmentTileIn"
59 size_t array_start =
input.find(
'[');
60 if (array_start != std::string::npos) {
61 r_name =
input.substr(0, array_start);
62 r_array =
input.substr(array_start);
152 char *current_str_begin = &*vertex_source.begin();
153 char *current_str_end = &*vertex_source.end();
155 for (
char *c = current_str_begin + 2; c < current_str_end - 18; c++) {
156 char *base_search = strstr(c,
"gl_ClipDistance[");
157 if (base_search ==
nullptr) {
161 c = base_search + 16;
164 if (*(c + 1) !=
']') {
169 if ((*c >=
'0') && (*c <=
'9')) {
170 char clip_distance_id = ((*c) -
'0');
171 auto found = std::find(
178 *(base_search + 15) =
'_';
179 *(base_search + 17) =
' ';
199 if (array_offset == -1) {
213 os <<
"constant " << res.
uniformbuf.type_name <<
" *" << name_no_array <<
";\n";
221 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
222 if (array_offset == -1) {
237 os << memory_scope << res.
storagebuf.type_name <<
" *" << name_no_array <<
";\n";
252 std::stringstream ss;
254 ss <<
"\n/* Shared Variables. */\n";
261 ss <<
"\n/* Pass Resources. */\n";
265 ss <<
"\n/* Batch Resources. */\n";
269 ss <<
"\n/* Geometry Resources. */\n";
287 std::stringstream ss;
288 ss <<
"\n/* Vertex Inputs. */\n";
305 std::stringstream ss;
306 ss <<
"\n/* Fragment Outputs. */\n";
312 ss <<
"\n/* Fragment Tile inputs. */\n";
321std::string MTLShader::MTLShader::geometry_interface_declare(
351 if (msl_patch_default !=
nullptr) {
353 return msl_patch_default;
356 std::stringstream ss_patch;
358 size_t len = strlen(ss_patch.str().c_str()) + 1;
360 msl_patch_default = (
char *)malloc(
len *
sizeof(
char));
361 memcpy(msl_patch_default, ss_patch.str().c_str(),
len *
sizeof(
char));
363 return msl_patch_default;
372 ss << (first ?
' ' :
',') <<
"threadgroup " <<
to_string(var.
type) <<
"(&_" <<
name <<
")"
384 ss << (first ?
':' :
',') <<
name <<
"(_" <<
name <<
")";
408 ss << (first ?
' ' :
',') <<
name;
416 std::stringstream &ss)
421 ss <<
"constant " << sc.
type <<
" " << sc.
name <<
" [[function_constant(" << index <<
")]];\n";
427 std::stringstream &ss)
431 std::string value_define;
434 value = std::to_string(cc.
value.
u);
437 value = std::to_string(cc.
value.
i);
440 value = cc.
value.
u ?
"true" :
"false";
441 value_define = std::to_string(cc.
value.
u);
446 ss <<
"constant " << cc.
type <<
" " << cc.
name <<
" = " << value <<
";\n";
456 bool uses_create_info = info !=
nullptr;
457 if (!uses_create_info) {
458 MTL_LOG_WARNING(
"Unable to compile shader %p '%s' as no create-info was provided!",
467 return this->generate_msl_from_glsl_compute(info);
473 MSLGeneratorInterface msl_iface(*
this);
479 msl_iface.prepare_from_createinfo(info);
482 BLI_assert(shd_builder_->glsl_vertex_source_.empty() ==
false);
483 BLI_assert(shd_builder_->glsl_fragment_source_.empty() ==
false);
488 std::string msl_defines_string =
"#define GPU_ARB_shader_draw_parameters 1\n";
489 msl_defines_string +=
"#define GPU_ARB_clip_control 1\n";
495 msl_defines_string +=
"#define GPU_ARB_texture_gather 1\n";
498 shd_builder_->glsl_vertex_source_ = msl_defines_string + shd_builder_->glsl_vertex_source_;
499 shd_builder_->glsl_fragment_source_ = msl_defines_string + shd_builder_->glsl_fragment_source_;
509 msl_iface.uses_gl_VertexID = bool(info->
builtins_ & BuiltinBits::VERTEX_ID) ||
510 shd_builder_->glsl_vertex_source_.find(
"gl_VertexID") !=
512 msl_iface.uses_gl_InstanceID = bool(info->
builtins_ & BuiltinBits::INSTANCE_ID) ||
513 shd_builder_->glsl_vertex_source_.find(
"gl_InstanceID") !=
515 shd_builder_->glsl_vertex_source_.find(
"gpu_InstanceIndex") !=
522 msl_iface.uses_gl_BaseInstanceARB = msl_iface.uses_gl_InstanceID ||
523 shd_builder_->glsl_vertex_source_.find(
524 "gl_BaseInstanceARB") != std::string::npos ||
525 shd_builder_->glsl_vertex_source_.find(
"gpu_BaseInstance") !=
527 msl_iface.uses_gl_Position = shd_builder_->glsl_vertex_source_.find(
"gl_Position") !=
529 msl_iface.uses_gl_PointSize = shd_builder_->glsl_vertex_source_.find(
"gl_PointSize") !=
531 msl_iface.uses_gpu_layer = bool(info->
builtins_ & BuiltinBits::LAYER);
532 msl_iface.uses_gpu_viewport_index = bool(info->
builtins_ & BuiltinBits::VIEWPORT_INDEX);
536 std::smatch gl_special_cases;
537 msl_iface.uses_gl_PointCoord = bool(info->
builtins_ & BuiltinBits::POINT_COORD) ||
538 shd_builder_->glsl_fragment_source_.find(
"gl_PointCoord") !=
540 msl_iface.uses_barycentrics = bool(info->
builtins_ & BuiltinBits::BARYCENTRIC_COORD);
541 msl_iface.uses_gl_FrontFacing = bool(info->
builtins_ & BuiltinBits::FRONT_FACING) ||
542 shd_builder_->glsl_fragment_source_.find(
"gl_FrontFacing") !=
544 msl_iface.uses_gl_PrimitiveID = bool(info->
builtins_ & BuiltinBits::PRIMITIVE_ID) ||
545 shd_builder_->glsl_fragment_source_.find(
"gl_PrimitiveID") !=
550 msl_iface.uses_gl_FragColor = shd_builder_->glsl_fragment_source_.find(
"gl_FragColor") !=
555 msl_iface.uses_gl_FragDepth = (info->
depth_write_ != DepthWrite::UNCHANGED) &&
556 shd_builder_->glsl_fragment_source_.find(
"gl_FragDepth") !=
559 msl_iface.uses_gl_FragStencilRefARB = bool(info->
builtins_ & BuiltinBits::STENCIL_REF);
572 std::stringstream ss_vertex;
573 std::stringstream ss_fragment;
574 ss_vertex <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
575 ss_fragment <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
587 arg_buf_samplers_vert_ = msl_iface.use_argument_buffer_for_samplers() ?
592 ss_vertex << msl_iface.msl_patch_default_get() << std::endl << std::endl;
599 ss_vertex <<
"struct " << iface->
name <<
" {" << std::endl;
600 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
604 ss_vertex <<
"};" << std::endl;
612 ss_vertex <<
"public:" << std::endl;
617 bool is_inside_struct =
false;
623 is_inside_struct =
true;
627 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
630 if (!is_inside_struct) {
634 const char *arraystart = strchr(
inout.name.c_str(),
'[');
635 bool is_array = (arraystart !=
nullptr);
636 int array_len = (is_array) ? std::stoi(std::regex_replace(
641 std::string out_name =
inout.name.c_str();
642 std::size_t
pos = out_name.find(
'[');
643 if (is_array &&
pos != std::string::npos) {
644 out_name.resize(
pos);
648 msl_iface.vertex_output_varyings.append(
657 msl_iface.fragment_input_varyings.append(
669 ss_vertex << msl_iface.generate_msl_vertex_in_struct();
674 if (msl_iface.uses_gl_Position) {
675 ss_vertex <<
"float4 gl_Position;" << std::endl;
677 if (msl_iface.uses_gl_PointSize) {
678 ss_vertex <<
"float gl_PointSize = 1.0;" << std::endl;
680 if (msl_iface.uses_gl_VertexID) {
681 ss_vertex <<
"int gl_VertexID;" << std::endl;
683 if (msl_iface.uses_gl_InstanceID) {
684 ss_vertex <<
"int gl_InstanceID;" << std::endl;
686 if (msl_iface.uses_gl_BaseInstanceARB) {
687 ss_vertex <<
"int gl_BaseInstanceARB;" << std::endl;
689 for (
const int cd : IndexRange(msl_iface.clip_distances.size())) {
690 ss_vertex <<
"float gl_ClipDistance_" << cd <<
";" << std::endl;
694 if (msl_iface.uses_gpu_layer) {
695 ss_vertex <<
"int gpu_Layer = 0;" << std::endl;
697 if (msl_iface.uses_gpu_viewport_index) {
698 ss_vertex <<
"int gpu_ViewportIndex = 0;" << std::endl;
706 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
711 ss_vertex << std::endl;
714 ss_vertex << shd_builder_->glsl_vertex_source_ << std::endl;
715 ss_vertex <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
721 ss_vertex <<
"};" << std::endl;
724 ss_vertex << msl_iface.generate_msl_vertex_entry_stub();
730 arg_buf_samplers_frag_ = msl_iface.use_argument_buffer_for_samplers() ?
735 ss_fragment << msl_iface.msl_patch_default_get() << std::endl << std::endl;
742 ss_fragment <<
"struct " << iface->
name <<
" {" << std::endl;
743 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
747 ss_fragment <<
"};" << std::endl;
754 ss_fragment <<
"public:" << std::endl;
759 bool is_inside_struct =
false;
763 is_inside_struct =
true;
767 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
770 if (!is_inside_struct) {
778 if (msl_iface.fragment_tile_inputs.is_empty() ==
false) {
779 ss_fragment << msl_iface.generate_msl_fragment_struct(
true);
781 ss_fragment << msl_iface.generate_msl_fragment_struct(
false);
786 ss_fragment <<
"float4 gl_FragCoord;" << std::endl;
787 if (msl_iface.uses_gl_FragColor) {
788 ss_fragment <<
"float4 gl_FragColor;" << std::endl;
790 if (msl_iface.uses_gl_FragDepth) {
791 ss_fragment <<
"float gl_FragDepth;" << std::endl;
793 if (msl_iface.uses_gl_FragStencilRefARB) {
794 ss_fragment <<
"int gl_FragStencilRefARB;" << std::endl;
796 if (msl_iface.uses_gl_PointCoord) {
797 ss_fragment <<
"float2 gl_PointCoord;" << std::endl;
799 if (msl_iface.uses_gl_FrontFacing) {
800 ss_fragment <<
"bool gl_FrontFacing;" << std::endl;
802 if (msl_iface.uses_gl_PrimitiveID) {
803 ss_fragment <<
"uint gl_PrimitiveID;" << std::endl;
807 if (msl_iface.uses_barycentrics) {
808 ss_fragment <<
"vec3 gpu_BaryCoord;\n";
812 if (msl_iface.uses_gpu_layer) {
813 ss_fragment <<
"int gpu_Layer = 0;" << std::endl;
815 if (msl_iface.uses_gpu_viewport_index) {
816 ss_fragment <<
"int gpu_ViewportIndex = 0;" << std::endl;
820 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
827 ss_fragment << shd_builder_->glsl_fragment_source_ << std::endl;
828 ss_fragment <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
831 ss_fragment <<
"};" << std::endl;
834 ss_fragment << msl_iface.generate_msl_fragment_entry_stub();
838#if MTL_SHADER_DEBUG_EXPORT_SOURCE
839 NSFileManager *sharedFM = [NSFileManager defaultManager];
840 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
841 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
842 URLByAppendingPathComponent:
@"Shaders/"
844 [sharedFM createDirectoryAtURL:shader_dir
845 withIntermediateDirectories:YES
848 const char *path_cstr = [shader_dir fileSystemRepresentation];
850 std::ofstream vertex_fs;
852 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedVertexShader.msl")
854 vertex_fs << ss_vertex.str();
857 std::ofstream fragment_fs;
859 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedFragmentShader.msl")
861 fragment_fs << ss_fragment.str();
865 "Vertex Shader Saved to: %s\n",
866 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedFragmentShader.msl").c_str());
870 NSString *msl_final_vert = [NSString stringWithUTF8String:ss_vertex.str().c_str()];
871 NSString *msl_final_frag = [NSString stringWithUTF8String:ss_fragment.str().c_str()];
879 [[NSString stringWithFormat:
@"vertex_function_entry_%s", this->
name] retain]);
881 [[NSString stringWithFormat:
@"fragment_function_entry_%s", this->
name] retain]);
888 this->
set_interface(msl_iface.bake_shader_interface(this->name, info));
891 uses_gpu_layer = msl_iface.uses_gpu_layer;
892 uses_gpu_viewport_index = msl_iface.uses_gpu_viewport_index;
903 MSLGeneratorInterface msl_iface(*
this);
909 msl_iface.prepare_from_createinfo(info);
912 BLI_assert(shd_builder_->glsl_compute_source_.empty() ==
false);
922 msl_iface.uses_gl_GlobalInvocationID =
923 bool(info->
builtins_ & BuiltinBits::GLOBAL_INVOCATION_ID) ||
924 shd_builder_->glsl_compute_source_.find(
"gl_GlobalInvocationID") != std::string::npos;
926 msl_iface.uses_gl_WorkGroupSize = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_SIZE) ||
927 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupSize") !=
930 msl_iface.uses_gl_WorkGroupID = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_ID) ||
931 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupID") !=
934 msl_iface.uses_gl_NumWorkGroups = bool(info->
builtins_ & BuiltinBits::NUM_WORK_GROUP) ||
935 shd_builder_->glsl_compute_source_.find(
"gl_NumWorkGroups") !=
938 msl_iface.uses_gl_LocalInvocationIndex =
939 bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_INDEX) ||
940 shd_builder_->glsl_compute_source_.find(
"gl_LocalInvocationIndex") != std::string::npos;
942 msl_iface.uses_gl_LocalInvocationID = bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_ID) ||
943 shd_builder_->glsl_compute_source_.find(
944 "gl_LocalInvocationID") != std::string::npos;
947 std::stringstream ss_compute;
948 ss_compute <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
950 ss_compute <<
"#define GPU_ARB_shader_draw_parameters 1\n";
951 ss_compute <<
"#define GPU_ARB_clip_control 1\n";
957 arg_buf_samplers_comp_ = msl_iface.use_argument_buffer_for_samplers() ?
962 ss_compute << msl_iface.msl_patch_default_get() << std::endl << std::endl;
968 ss_compute <<
"public:" << std::endl;
978 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
983 ss_compute << std::endl;
986 if (msl_iface.uses_gl_GlobalInvocationID) {
987 ss_compute <<
"uint3 gl_GlobalInvocationID;" << std::endl;
989 if (msl_iface.uses_gl_WorkGroupID) {
990 ss_compute <<
"uint3 gl_WorkGroupID;" << std::endl;
992 if (msl_iface.uses_gl_NumWorkGroups) {
993 ss_compute <<
"uint3 gl_NumWorkGroups;" << std::endl;
995 if (msl_iface.uses_gl_LocalInvocationIndex) {
996 ss_compute <<
"uint gl_LocalInvocationIndex;" << std::endl;
998 if (msl_iface.uses_gl_LocalInvocationID) {
999 ss_compute <<
"uint3 gl_LocalInvocationID;" << std::endl;
1003 ss_compute << shd_builder_->glsl_compute_source_ << std::endl;
1004 ss_compute <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
1014 ss_compute <<
"MSL_SHARED_VARS_ARGS";
1021 ss_compute <<
" MSL_SHARED_VARS_ASSIGN ";
1023 ss_compute <<
"{}\n";
1026 ss_compute <<
"};" << std::endl;
1029 ss_compute << msl_iface.generate_msl_compute_entry_stub(*info);
1035 [[NSString stringWithFormat:
@"compute_function_entry_%s", this->
name] retain]);
1041#if MTL_SHADER_DEBUG_EXPORT_SOURCE
1042 NSFileManager *sharedFM = [NSFileManager defaultManager];
1043 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
1044 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
1045 URLByAppendingPathComponent:
@"Shaders/"
1047 [sharedFM createDirectoryAtURL:shader_dir
1048 withIntermediateDirectories:YES
1051 const char *path_cstr = [shader_dir fileSystemRepresentation];
1053 std::ofstream compute_fs;
1055 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedComputeShader.msl")
1057 compute_fs << ss_compute.str();
1061 "Compute Shader Saved to: %s\n",
1062 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedComputeShader.msl").c_str());
1065 NSString *msl_final_compute = [NSString stringWithUTF8String:ss_compute.str().c_str()];
1069 this->
set_interface(msl_iface.bake_shader_interface(this->name, info));
1072 this->compute_pso_common_state_.set_compute_workgroup_size(
1089 create_info_ = info;
1101 for (
const auto &constant : create_info_->specialization_constants_) {
1113 int texture_slot_id = 0;
1114 int ubo_buffer_slot_id_ = 0;
1115 int storage_buffer_slot_id_ = 0;
1117 uint max_storage_buffer_location = 0;
1123 int max_sampler_slot = 0;
1124 if (!create_info_->auto_resource_location_) {
1127 max_sampler_slot =
max_ii(res.slot, max_sampler_slot);
1135 switch (res.bind_type) {
1141 if (res.sampler.type == ImageType::FloatBuffer ||
1142 res.sampler.type == ImageType::IntBuffer || res.sampler.type == ImageType::UintBuffer)
1149 msl_tex.
type = res.sampler.type;
1150 msl_tex.
name = res.sampler.name;
1152 msl_tex.
slot = texture_slot_id++;
1153 msl_tex.
location = (create_info_->auto_resource_location_) ? msl_tex.
slot : res.slot;
1177 msl_image.
type = res.image.type;
1178 msl_image.
name = res.image.name;
1179 msl_image.
access = access;
1180 msl_image.
slot = texture_slot_id++;
1181 msl_image.
location = (create_info_->auto_resource_location_) ? msl_image.
slot : res.slot;
1191 BLI_assert(res.uniformbuf.type_name.is_empty() ==
false);
1192 BLI_assert(res.uniformbuf.name.is_empty() ==
false);
1193 int64_t array_offset = res.uniformbuf.name.find_first_of(
"[");
1200 ubo.
slot = 1 + (ubo_buffer_slot_id_++);
1201 ubo.
location = (create_info_->auto_resource_location_) ? ubo.
slot : res.slot;
1206 ubo.
type_name = res.uniformbuf.type_name;
1208 ubo.
is_array = (array_offset > -1);
1212 ubo.
name = name_no_array;
1215 ubo.
name = res.uniformbuf.name;
1223 BLI_assert(res.storagebuf.type_name.is_empty() ==
false);
1224 BLI_assert(res.storagebuf.name.is_empty() ==
false);
1225 int64_t array_offset = res.storagebuf.name.find_first_of(
"[");
1230 ssbo.
slot = storage_buffer_slot_id_++;
1231 ssbo.
location = (create_info_->auto_resource_location_) ? ssbo.
slot : res.slot;
1233 max_storage_buffer_location =
max_uu(max_storage_buffer_location, ssbo.
location);
1238 ssbo.
type_name = res.storagebuf.type_name;
1240 ssbo.
is_array = (array_offset > -1);
1244 ssbo.
name = name_no_array;
1247 ssbo.
name = res.storagebuf.name;
1258 uint atomic_fallback_buffer_count = 0;
1261 ImageType::AtomicUint2D,
1262 ImageType::AtomicUint2DArray,
1263 ImageType::AtomicUint3D,
1264 ImageType::AtomicInt2D,
1265 ImageType::AtomicInt2DArray,
1266 ImageType::AtomicInt3D))
1276 ssbo.
slot = storage_buffer_slot_id_++;
1277 ssbo.
location = max_storage_buffer_location + 1 + atomic_fallback_buffer_count;
1290 ssbo.
name = tex.
name +
"_storagebuf";
1299 atomic_fallback_buffer_count++;
1308 bool all_attr_location_assigned =
true;
1317 bool attr_location_assigned = (attr.
index >= 0);
1318 all_attr_location_assigned = all_attr_location_assigned && attr_location_assigned;
1326 if (!all_attr_location_assigned) {
1360 mtl_frag_in.
type = frag_tile_in.
type;
1361 mtl_frag_in.
name = frag_tile_in.
name;
1364 ImageType::Uint2DArray,
1365 ImageType::Int2DArray,
1366 ImageType::Float2DArray);
1376 msl_image.
name = frag_tile_in.
name +
"_subpass_img";
1378 msl_image.
slot = texture_slot_id++;
1413 "Compiled Shader '%s' is falling back to bindless via argument buffers due to having a "
1414 "texture sampler of Index: %u Which exceeds the limit of 15+1. However shader only uses "
1415 "%d textures. Consider optimising bind points with .auto_resource_location(true).",
1416 parent_shader_.name_get().c_str(),
1422 return use_argument_buffer;
1458 std::stringstream
out;
1459 out << std::endl <<
"/*** AUTO-GENERATED MSL VERETX SHADER STUB. ***/" << std::endl;
1462 out <<
"#undef texture" << std::endl;
1463 out <<
"#undef textureLod" << std::endl;
1466 out <<
"#undef bool" << std::endl;
1475 out <<
"vertex_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
1477 out <<
"vertex_function_entry(\n\t";
1481 out <<
") {" << std::endl << std::endl;
1488 out << shader_stage_inst_name <<
".gl_VertexID = gl_VertexID;" << std::endl;
1491 out << shader_stage_inst_name <<
".gl_InstanceID = gl_InstanceID-gl_BaseInstanceARB;"
1495 out << shader_stage_inst_name <<
".gl_BaseInstanceARB = gl_BaseInstanceARB;" << std::endl;
1507 out <<
"\t/* Execute Vertex main function */\t" << std::endl
1508 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1518 out <<
"if(is_function_constant_defined(MTL_global_pointsize)){ output.pointsize = "
1519 "(MTL_global_pointsize > 0.0)?MTL_global_pointsize:output.pointsize; }"
1521 out <<
"\treturn output;" << std::endl;
1530 std::stringstream
out;
1531 out << std::endl <<
"/*** AUTO-GENERATED MSL FRAGMENT SHADER STUB. ***/" << std::endl;
1534 out <<
"#undef texture" << std::endl;
1535 out <<
"#undef textureLod" << std::endl;
1538 out <<
"#undef bool" << std::endl;
1545 out <<
"[[early_fragment_tests]]" << std::endl;
1558 out <<
") {" << std::endl << std::endl;
1562 <<
";" << std::endl;
1566 out << shader_stage_inst_name <<
".gl_PointCoord = gl_PointCoord;" << std::endl;
1569 out << shader_stage_inst_name <<
".gl_FrontFacing = gl_FrontFacing;" << std::endl;
1572 out <<
"fragment_shader_instance.gl_PrimitiveID = gl_PrimitiveID;" << std::endl;
1580 out << shader_stage_inst_name <<
".gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl;
1594 out <<
"\t/* Execute Fragment main function */\t" << std::endl
1595 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1600 out <<
" return output;" << std::endl <<
"}";
1609 std::stringstream
out;
1610 out << std::endl <<
"/*** AUTO-GENERATED MSL COMPUTE SHADER STUB. ***/" << std::endl;
1613 out <<
"#undef texture" << std::endl;
1614 out <<
"#undef textureLod" << std::endl;
1617 out <<
"#undef bool" << std::endl;
1623 out <<
"kernel void ";
1625 out <<
"compute_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
1627 out <<
"compute_function_entry(\n\t";
1631 out <<
") {" << std::endl << std::endl;
1636 out <<
"MSL_SHARED_VARS_DECLARE\n";
1646 out <<
" MSL_SHARED_VARS_PASS ";
1653 out << shader_stage_inst_name <<
".gl_GlobalInvocationID = gl_GlobalInvocationID;"
1657 out << shader_stage_inst_name <<
".gl_WorkGroupID = gl_WorkGroupID;" << std::endl;
1660 out << shader_stage_inst_name <<
".gl_NumWorkGroups = gl_NumWorkGroups;" << std::endl;
1663 out << shader_stage_inst_name <<
".gl_LocalInvocationIndex = gl_LocalInvocationIndex;"
1667 out << shader_stage_inst_name <<
".gl_LocalInvocationID = gl_LocalInvocationID;" << std::endl;
1676 out <<
"\t/* Execute Compute main function */\t" << std::endl
1677 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1688 if (is_first_parameter) {
1689 is_first_parameter =
false;
1697 bool &is_first_parameter)
1706 if (
bool(tex.
stage & stage)) {
1708 <<
" [[texture(" << tex.
slot <<
")]]";
1719 <<
"\n\tconstant SStruct& samplers [[buffer(MTL_uniform_buffer_base_index+"
1727 if (
bool(tex.
stage & stage)) {
1729 <<
"_sampler [[sampler(" << tex.
slot <<
")]]";
1734 if (this->texture_samplers.size() > 16) {
1736 "[Metal] Warning: Shader exceeds limit of %u samplers on current hardware\n",
1744 bool &is_first_parameter)
1747 if (
bool(ubo.stage & stage)) {
1757 out << ubo.type_name <<
"* " << ubo.name <<
"[[buffer(MTL_uniform_buffer_base_index+"
1758 << ubo.slot <<
")]]";
1764 if (
bool(ssbo.stage & stage)) {
1771 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
1772 out << memory_scope;
1781 out << ssbo.type_name <<
"* " << ssbo.name <<
"[[buffer(MTL_storage_buffer_base_index+"
1782 << (ssbo.slot) <<
")]]";
1789 std::stringstream
out;
1790 bool is_first_parameter =
true;
1795 is_first_parameter =
false;
1798 if (this->
uniforms.is_empty() ==
false) {
1801 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1802 is_first_parameter =
false;
1813 <<
"\n\tconst uint32_t gl_VertexID [[vertex_id]]";
1817 <<
"\n\tconst uint32_t gl_InstanceID [[instance_id]]";
1821 <<
"\n\tconst uint32_t gl_BaseInstanceARB [[base_instance]]";
1828 bool is_first_parameter =
true;
1829 std::stringstream
out;
1831 <<
"::VertexOut v_in [[stage_in]]";
1833 if (this->
uniforms.is_empty() ==
false) {
1836 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1846 <<
"\n\tconst float2 gl_PointCoord [[point_coord]]";
1850 <<
"\n\tconst bool gl_FrontFacing [[front_facing]]";
1854 <<
"\n\tconst uint gl_PrimitiveID [[primitive_id]]";
1860 <<
"\n\tconst float3 mtl_barycentric_coord [[barycentric_coord]]";
1874 bool is_first_parameter =
true;
1875 std::stringstream
out;
1876 if (this->
uniforms.is_empty() ==
false) {
1879 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1890 <<
"\n\tconst uint3 gl_GlobalInvocationID [[thread_position_in_grid]]";
1894 <<
"\n\tconst uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]";
1898 <<
"\n\tconst uint3 gl_NumWorkGroups [[threadgroups_per_grid]]";
1902 <<
"\n\tconst uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]";
1906 <<
"\n\tconst uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]";
1920 std::stringstream
out;
1923 out <<
"typedef struct {" << std::endl;
1926 if (uniform.is_array) {
1927 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
"[" << uniform.array_elems
1928 <<
"];" << std::endl;
1931 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
";" << std::endl;
1934 out <<
"} PushConstantBlock;\n\n";
1937 out << std::endl <<
"const constant PushConstantBlock *global_uniforms;" << std::endl;
1942 for (
const MSLUniform &uniform : this->uniforms) {
1943 out <<
"#define " << uniform.name <<
" global_uniforms->" << uniform.name << std::endl;
1952 std::stringstream
out;
1956 out <<
"#undef " << uniform.name << std::endl;
1960 out <<
"#undef " << ubo.name << std::endl;
1964 out <<
"#undef " << ssbo.name << std::endl;
1971 std::stringstream
out;
1979 out <<
"typedef struct {" << std::endl;
1995 <<
" [[attribute(" << (in_attr.layout_location + elem) <<
")]];" << std::endl;
1999 out <<
"\t" << in_attr.type <<
" " << in_attr.name <<
" [[attribute("
2000 << in_attr.layout_location <<
")]];" << std::endl;
2004 out <<
"} VertexIn;" << std::endl << std::endl;
2012 std::stringstream
out;
2015 out <<
"typedef struct {" << std::endl;
2019 bool first_attr_is_position =
false;
2025 out <<
"\tfloat4 _default_position_ [[position]]";
2026 out <<
" [[invariant]]";
2027 out <<
";" << std::endl;
2036 out <<
" [[invariant]]";
2037 out <<
";" << std::endl;
2038 first_attr_is_position =
true;
2042 bool skip_first_index = first_attr_is_position;
2046 if (skip_first_index) {
2047 skip_first_index =
false;
2051 if (v_out.is_array) {
2058 for (
int i = 0;
i < v_out.array_elems;
i++) {
2059 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name <<
i
2060 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2066 BLI_assert(v_out.get_mtl_interpolation_qualifier() ==
" [[flat]]" &&
2067 "Matrix varying types must have [[flat]] interpolation");
2070 out <<
"\t" << subtype << v_out.instance_name <<
" __matrix_" << v_out.name << elem
2071 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2075 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name
2076 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2088 out <<
"\tfloat pointsize [[point_size]];" << std::endl;
2095 out <<
"\tfloat pointsize [[point_size, function_constant(MTL_global_pointsize)]];"
2102 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl;
2105 out <<
"\tfloat clipdistance [[clip_distance, "
2106 "function_constant(MTL_clip_distances_enabled)]] ["
2110 out <<
"\tfloat clipdistance [[clip_distance, "
2111 "function_constant(MTL_clip_distances_enabled)]];"
2114 out <<
"#endif" << std::endl;
2119 out <<
"\tuint gpu_Layer [[render_target_array_index]];" << std::endl;
2124 out <<
"\tuint gpu_ViewportIndex [[viewport_array_index]];" << std::endl;
2127 out <<
"} VertexOut;" << std::endl << std::endl;
2134 std::stringstream
out;
2139 out <<
"typedef struct {" << std::endl;
2140 for (
int f_output = 0; f_output < fragment_interface_src.size(); f_output++) {
2141 out <<
"\t" <<
to_string(fragment_interface_src[f_output].type) <<
" "
2142 << fragment_interface_src[f_output].name <<
" [[color("
2143 << fragment_interface_src[f_output].layout_location <<
")";
2144 if (fragment_interface_src[f_output].layout_index >= 0) {
2145 out <<
", index(" << fragment_interface_src[f_output].layout_index <<
")";
2147 if (fragment_interface_src[f_output].raster_order_group >= 0) {
2148 out <<
", raster_order_group(" << fragment_interface_src[f_output].raster_order_group <<
")";
2151 <<
";" << std::endl;
2159 out <<
"\tfloat fragdepth [[depth(" << out_depth_argument <<
")]];" << std::endl;
2163 out <<
"\tuint fragstencil [[stencil]];" << std::endl;
2181 std::stringstream
out;
2184 out <<
"\t/* Copy Uniform block member reference */" << std::endl;
2186 <<
"global_uniforms = uniforms;" << std::endl;
2193 std::stringstream
out;
2199 << tile_input.name <<
" = "
2200 <<
"fragment_tile_in." << tile_input.name <<
";" << std::endl;
2206 char swizzle[] =
"xyzw";
2210 std::string texel_co =
2211 (tile_input.is_layered_input) ?
2212 ((is_layered_fb) ?
"ivec3(ivec2(v_in._default_position_.xy), int(v_in.gpu_Layer))" :
2216 "ivec3(ivec2(v_in._default_position_.xy), 0)") :
2217 "ivec2(v_in._default_position_.xy)";
2220 << tile_input.name <<
" = imageLoad("
2222 <<
"_subpass_img, " << texel_co <<
")." << swizzle <<
";\n";
2231 std::stringstream
out;
2232 out <<
"\t/* Copy UBO block references into local class variables */" << std::endl;
2236 if (
bool(ubo.stage & stage)) {
2243 if (!ubo.is_array) {
2246 out <<
" = " << ubo.name <<
";" << std::endl;
2251 out <<
"\t/* Copy SSBO block references into local class variables */" << std::endl;
2255 if (
bool(ssbo.stage & stage) && !ssbo.is_texture_buffer) {
2262 if (!ssbo.is_array) {
2269 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
2271 out <<
"const_cast<" << memory_scope;
2276 out << ssbo.type_name <<
"*>(";
2282 out <<
";" << std::endl;
2296 std::stringstream
out;
2297 out <<
"\t/* Copy Vertex Stage-in attributes into local variables */" << std::endl;
2334 bool do_attribute_conversion_on_read =
false;
2338 if (do_attribute_conversion_on_read) {
2340 out <<
"\t" << attribute_conversion_func_name <<
"(MTL_AttributeConvert"
2346 out <<
"\t" << shader_stage_inst_name <<
"."
2360 std::stringstream
out;
2361 out <<
"\t/* Copy Vertex Outputs into output struct */" << std::endl;
2365 out <<
"\toutput._default_position_ = " << shader_stage_inst_name <<
".gl_Position;"
2370 out <<
"\toutput._default_position_.y = -output._default_position_.y;" << std::endl;
2371 out <<
"\toutput._default_position_.z = "
2372 "(output._default_position_.z+output._default_position_.w)/2.0;"
2378 out <<
"\toutput.pointsize = " << shader_stage_inst_name <<
".gl_PointSize;" << std::endl;
2383 out <<
"\toutput.gpu_Layer = " << shader_stage_inst_name <<
".gpu_Layer;" << std::endl;
2388 out <<
"\toutput.gpu_ViewportIndex = " << shader_stage_inst_name <<
".gpu_ViewportIndex;"
2396 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl
2397 <<
"if(MTL_clip_distances_enabled) {" << std::endl;
2401 out <<
"\toutput.clipdistance[" << cd
2402 <<
"] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd <<
"))?"
2403 << shader_stage_inst_name <<
".gl_ClipDistance_" << cd <<
":1.0;" << std::endl;
2407 out <<
"\toutput.clipdistance = " << shader_stage_inst_name <<
".gl_ClipDistance_0;"
2410 out <<
"}" << std::endl <<
"#endif" << std::endl;
2415 if (v_out.is_array) {
2417 for (
int i = 0;
i < v_out.array_elems;
i++) {
2418 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
i <<
" = "
2419 << shader_stage_inst_name <<
".";
2421 if (v_out.instance_name.empty() ==
false) {
2422 out << v_out.instance_name <<
".";
2425 out << v_out.name <<
"[" <<
i <<
"]"
2426 <<
";" << std::endl;
2433 out <<
"\toutput." << v_out.instance_name <<
"__matrix_" << v_out.name << elem <<
" = "
2434 << shader_stage_inst_name <<
".";
2436 if (v_out.instance_name.empty() ==
false) {
2437 out << v_out.instance_name <<
".";
2440 out << v_out.name <<
"[" << elem <<
"];" << std::endl;
2447 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = to_vec4("
2448 << shader_stage_inst_name <<
"." << v_out.name <<
");" << std::endl;
2451 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
".y = -output."
2452 << v_out.name <<
".y;" << std::endl;
2456 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = "
2457 << shader_stage_inst_name <<
".";
2459 if (v_out.instance_name.empty() ==
false) {
2460 out << v_out.instance_name <<
".";
2463 out << v_out.name <<
";" << std::endl;
2479 std::stringstream
out;
2480 out <<
"\t/* Copy Fragment input into local variables. */" << std::endl;
2484 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in._default_position_;"
2489 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in."
2497 out <<
"\t" << shader_stage_inst_name <<
".gl_FragDepth = " << shader_stage_inst_name
2498 <<
".gl_FragCoord.z;" << std::endl;
2503 out <<
"\t" << shader_stage_inst_name <<
".gpu_Layer = v_in.gpu_Layer;" << std::endl;
2508 out <<
"\t" << shader_stage_inst_name <<
".gpu_ViewportIndex = v_in.gpu_ViewportIndex;"
2524 bool exists_in_vertex_output =
false;
2528 exists_in_vertex_output =
true;
2531 if (!exists_in_vertex_output) {
2533 "[Warning] Fragment shader expects varying input '%s', but this is not passed from "
2541 out <<
"\t" << shader_stage_inst_name <<
".";
2555 out <<
"\t" << shader_stage_inst_name <<
".";
2564 for (
int elem = 0; elem <
count; elem++) {
2565 out << ((elem == 0) ?
"(" :
"") <<
"v_in."
2568 << ((elem <
count - 1) ?
",\n" :
"");
2570 out <<
");" << std::endl;
2573 out <<
"\t" << shader_stage_inst_name <<
".";
2595 std::stringstream
out;
2596 out <<
"\t/* Copy Fragment Outputs into output struct. */" << std::endl;
2600 out <<
"\toutput.fragdepth = " << shader_stage_inst_name <<
".gl_FragDepth;" << std::endl;
2605 out <<
"\toutput.fragstencil = uint(" << shader_stage_inst_name <<
".gl_FragStencilRefARB);"
2610 for (
int f_output = 0; f_output < this->
fragment_outputs.size(); f_output++) {
2612 out <<
"\toutput." << this->
fragment_outputs[f_output].name <<
" = " << shader_stage_inst_name
2626 std::stringstream
out;
2627 out <<
"\t/* Populate local texture and sampler members */" << std::endl;
2634 <<
";" << std::endl;
2645 <<
"_sampler;" << std::endl;
2650 if (tex_buf_id != -1) {
2657 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
2659 out <<
"const_cast<" << memory_scope;
2670 out <<
";" << std::endl;
2679 ImageType::AtomicUint2DArray,
2680 ImageType::AtomicUint3D,
2681 ImageType::AtomicInt2DArray,
2682 ImageType::AtomicInt3D))
2685 << this->
texture_samplers[
i].name <<
".atomic.texture_size = ushort3(uniforms->"
2698 uint32_t used_locations = 0;
2700 if (attr.layout_location >= 0) {
2703 for (uint32_t
i = 1;
i <= location_element_count;
i++) {
2705 uint32_t location_mask = (
i << attr.layout_location);
2706 BLI_assert((used_locations & location_mask) == 0);
2707 used_locations = used_locations | location_mask;
2714 if (attr.layout_location == -1) {
2724 uint32_t location_mask = (1 << loc);
2730 uint32_t location_slot_mask = (1 << required_attr_slot_count) - 1;
2731 uint32_t sliding_location_slot_mask = location_slot_mask << location_mask;
2732 if ((used_locations & sliding_location_slot_mask) == 0) {
2734 attr.layout_location = loc;
2735 used_locations = used_locations | location_slot_mask;
2741 MTL_LOG_ERROR(
"Could not assign attribute location to attribute %s for shader %s",
2743 this->parent_shader_.name_get().c_str());
2750 int running_location_ind = 0;
2756 ((running_location_ind > 0) ? (this->
fragment_outputs[
i].layout_location == -1) :
true),
2757 "Error: Mismatched input attributes, some with location specified, some without");
2760 running_location_ind++;
2770 const char *str_to_copy,
2771 uint32_t &name_buffer_size,
2772 uint32_t &name_buffer_offset)
2778 uint32_t ret_len = strlen(str_to_copy);
2782 if (name_buffer_offset + ret_len + 1 > name_buffer_size) {
2783 name_buffer_size = name_buffer_offset +
max_ii(128, ret_len + 1);
2784 *name_buffer_ptr = (
char *)
MEM_reallocN(*name_buffer_ptr, name_buffer_size);
2788 uint32_t insert_offset = name_buffer_offset;
2789 char *current_offset = (*name_buffer_ptr) + insert_offset;
2790 memcpy(current_offset, str_to_copy, (ret_len + 1) *
sizeof(
char));
2793 name_buffer_offset += ret_len + 1;
2796 return insert_offset;
2807 uint32_t name_buffer_size = 256;
2808 uint32_t name_buffer_offset = 0;
2828 std::string _internal_name = (elem == 0) ?
2832 std::to_string(elem);
2836 _internal_name.c_str(),
2838 name_buffer_offset),
2839 this->vertex_input_attributes[attribute].layout_location + elem,
2850 "[Note] Matrix Type '%s' added to shader interface as vertex attribute. (Elem Count: "
2862 this->vertex_input_attributes[attribute].name.c_str(),
2864 name_buffer_offset),
2865 this->vertex_input_attributes[attribute].layout_location,
2880 &
interface->name_buffer_,
"PushConstantBlock", name_buffer_size, name_buffer_offset));
2882 for (
int uniform = 0; uniform < this->
uniforms.size(); uniform++) {
2885 this->uniforms[uniform].name.c_str(),
2887 name_buffer_offset),
2889 (this->
uniforms[uniform].is_array) ? this->
uniforms[uniform].array_elems : 1);
2893 for (
int uniform_block = 0; uniform_block < this->
uniform_blocks.size(); uniform_block++) {
2896 this->uniform_blocks[uniform_block].name.c_str(),
2898 name_buffer_offset),
2899 this->uniform_blocks[uniform_block].slot,
2900 this->uniform_blocks[uniform_block].location,
2902 this->uniform_blocks[uniform_block].stage);
2906 for (
int storage_block = 0; storage_block < this->
storage_blocks.size(); storage_block++) {
2909 this->storage_blocks[storage_block].name.c_str(),
2911 name_buffer_offset),
2912 this->storage_blocks[storage_block].slot,
2913 this->storage_blocks[storage_block].location,
2915 this->storage_blocks[storage_block].stage);
2921 uint tex_buf_ssbo_location = -1;
2922 uint tex_buf_ssbo_id = input_texture.atomic_fallback_buffer_ssbo_id;
2923 if (tex_buf_ssbo_id != -1) {
2924 tex_buf_ssbo_location = this->
storage_blocks[tex_buf_ssbo_id].location;
2928 input_texture.name.c_str(),
2930 name_buffer_offset),
2932 input_texture.location,
2933 input_texture.get_texture_binding_type(),
2934 input_texture.get_sampler_format(),
2935 input_texture.is_texture_sampler,
2936 input_texture.stage,
2937 tex_buf_ssbo_location);
2943 &
interface->name_buffer_, constant.name.c_str(), name_buffer_size, name_buffer_offset));
2954 interface->prepare_common_shader_inputs(info);
2957 if (name_buffer_offset < name_buffer_size) {
2968 switch (this->
type) {
2969 case ImageType::Float1D: {
2972 case ImageType::Float2D: {
2975 case ImageType::Float3D: {
2978 case ImageType::FloatCube: {
2979 return "texturecube";
2981 case ImageType::Float1DArray: {
2982 return "texture1d_array";
2984 case ImageType::Float2DArray: {
2985 return "texture2d_array";
2987 case ImageType::FloatCubeArray: {
2988 return "texturecube_array";
2990 case ImageType::FloatBuffer: {
2991 return "texture_buffer";
2993 case ImageType::Depth2D: {
2996 case ImageType::Shadow2D: {
2999 case ImageType::Depth2DArray: {
3000 return "depth2d_array";
3002 case ImageType::Shadow2DArray: {
3003 return "depth2d_array";
3005 case ImageType::DepthCube: {
3008 case ImageType::ShadowCube: {
3011 case ImageType::DepthCubeArray: {
3012 return "depthcube_array";
3014 case ImageType::ShadowCubeArray: {
3015 return "depthcube_array";
3017 case ImageType::Int1D: {
3020 case ImageType::Int2D: {
3023 case ImageType::Int3D: {
3026 case ImageType::IntCube: {
3027 return "texturecube";
3029 case ImageType::Int1DArray: {
3030 return "texture1d_array";
3032 case ImageType::Int2DArray: {
3033 return "texture2d_array";
3035 case ImageType::IntCubeArray: {
3036 return "texturecube_array";
3038 case ImageType::IntBuffer: {
3039 return "texture_buffer";
3041 case ImageType::Uint1D: {
3044 case ImageType::Uint2D: {
3047 case ImageType::Uint3D: {
3050 case ImageType::UintCube: {
3051 return "texturecube";
3053 case ImageType::Uint1DArray: {
3054 return "texture1d_array";
3056 case ImageType::Uint2DArray: {
3057 return "texture2d_array";
3059 case ImageType::UintCubeArray: {
3060 return "texturecube_array";
3062 case ImageType::UintBuffer: {
3063 return "texture_buffer";
3067 case ImageType::AtomicInt2D:
3068 case ImageType::AtomicUint2D: {
3071 case ImageType::AtomicInt2DArray:
3072 case ImageType::AtomicUint2DArray: {
3073 if (supports_native_atomics) {
3074 return "texture2d_array";
3080 case ImageType::AtomicInt3D:
3081 case ImageType::AtomicUint3D: {
3082 if (supports_native_atomics) {
3102 switch (this->
type) {
3103 case ImageType::Float1D: {
3104 return "_mtl_sampler_1d";
3106 case ImageType::Float2D: {
3107 return "_mtl_sampler_2d";
3109 case ImageType::Float3D: {
3110 return "_mtl_sampler_3d";
3112 case ImageType::FloatCube: {
3113 return "_mtl_sampler_cube";
3115 case ImageType::Float1DArray: {
3116 return "_mtl_sampler_1d_array";
3118 case ImageType::Float2DArray: {
3119 return "_mtl_sampler_2d_array";
3121 case ImageType::FloatCubeArray: {
3122 return "_mtl_sampler_cube_array";
3124 case ImageType::FloatBuffer: {
3125 return "_mtl_sampler_buffer";
3127 case ImageType::Depth2D: {
3128 return "_mtl_sampler_depth_2d";
3130 case ImageType::Shadow2D: {
3131 return "_mtl_sampler_depth_2d";
3133 case ImageType::Depth2DArray: {
3134 return "_mtl_sampler_depth_2d_array";
3136 case ImageType::Shadow2DArray: {
3137 return "_mtl_sampler_depth_2d_array";
3139 case ImageType::DepthCube: {
3140 return "_mtl_sampler_depth_cube";
3142 case ImageType::ShadowCube: {
3143 return "_mtl_sampler_depth_cube";
3145 case ImageType::DepthCubeArray: {
3146 return "_mtl_sampler_depth_cube_array";
3148 case ImageType::ShadowCubeArray: {
3149 return "_mtl_sampler_depth_cube_array";
3151 case ImageType::Int1D: {
3152 return "_mtl_sampler_1d";
3154 case ImageType::Int2D: {
3155 return "_mtl_sampler_2d";
3157 case ImageType::Int3D: {
3158 return "_mtl_sampler_3d";
3160 case ImageType::IntCube: {
3161 return "_mtl_sampler_cube";
3163 case ImageType::Int1DArray: {
3164 return "_mtl_sampler_1d_array";
3166 case ImageType::Int2DArray: {
3167 return "_mtl_sampler_2d_array";
3169 case ImageType::IntCubeArray: {
3170 return "_mtl_sampler_cube_array";
3172 case ImageType::IntBuffer: {
3173 return "_mtl_sampler_buffer";
3175 case ImageType::Uint1D: {
3176 return "_mtl_sampler_1d";
3178 case ImageType::Uint2D: {
3179 return "_mtl_sampler_2d";
3181 case ImageType::Uint3D: {
3182 return "_mtl_sampler_3d";
3184 case ImageType::UintCube: {
3185 return "_mtl_sampler_cube";
3187 case ImageType::Uint1DArray: {
3188 return "_mtl_sampler_1d_array";
3190 case ImageType::Uint2DArray: {
3191 return "_mtl_sampler_2d_array";
3193 case ImageType::UintCubeArray: {
3194 return "_mtl_sampler_cube_array";
3196 case ImageType::UintBuffer: {
3197 return "_mtl_sampler_buffer";
3201 case ImageType::AtomicInt2D:
3202 case ImageType::AtomicUint2D: {
3203 if (supports_native_atomics) {
3204 return "_mtl_sampler_2d";
3207 return "_mtl_sampler_2d_atomic";
3210 case ImageType::AtomicInt3D:
3211 case ImageType::AtomicUint3D: {
3212 if (supports_native_atomics) {
3213 return "_mtl_sampler_3d";
3216 return "_mtl_sampler_3d_atomic";
3219 case ImageType::AtomicInt2DArray:
3220 case ImageType::AtomicUint2DArray: {
3221 if (supports_native_atomics) {
3222 return "_mtl_sampler_2d_array";
3225 return "_mtl_sampler_2d_array_atomic";
3239 switch (this->
type) {
3241 case ImageType::Float1D:
3242 case ImageType::Float2D:
3243 case ImageType::Float3D:
3244 case ImageType::FloatCube:
3245 case ImageType::Float1DArray:
3246 case ImageType::Float2DArray:
3247 case ImageType::FloatCubeArray:
3248 case ImageType::FloatBuffer:
3249 case ImageType::Depth2D:
3250 case ImageType::Shadow2D:
3251 case ImageType::Depth2DArray:
3252 case ImageType::Shadow2DArray:
3253 case ImageType::DepthCube:
3254 case ImageType::ShadowCube:
3255 case ImageType::DepthCubeArray:
3256 case ImageType::ShadowCubeArray: {
3260 case ImageType::Int1D:
3261 case ImageType::Int2D:
3262 case ImageType::Int3D:
3263 case ImageType::IntCube:
3264 case ImageType::Int1DArray:
3265 case ImageType::Int2DArray:
3266 case ImageType::IntCubeArray:
3267 case ImageType::IntBuffer:
3268 case ImageType::AtomicInt2D:
3269 case ImageType::AtomicInt2DArray:
3270 case ImageType::AtomicInt3D: {
3275 case ImageType::Uint1D:
3276 case ImageType::Uint2D:
3277 case ImageType::Uint3D:
3278 case ImageType::UintCube:
3279 case ImageType::Uint1DArray:
3280 case ImageType::Uint2DArray:
3281 case ImageType::UintCubeArray:
3282 case ImageType::UintBuffer:
3283 case ImageType::AtomicUint2D:
3284 case ImageType::AtomicUint2DArray:
3285 case ImageType::AtomicUint3D: {
3300 switch (this->
type) {
3301 case ImageType::Float1D: {
3304 case ImageType::Float2D: {
3307 case ImageType::Float3D: {
3310 case ImageType::FloatCube: {
3313 case ImageType::Float1DArray: {
3316 case ImageType::Float2DArray: {
3319 case ImageType::FloatCubeArray: {
3322 case ImageType::FloatBuffer: {
3325 case ImageType::Depth2D: {
3328 case ImageType::Shadow2D: {
3331 case ImageType::Depth2DArray: {
3334 case ImageType::Shadow2DArray: {
3337 case ImageType::DepthCube: {
3340 case ImageType::ShadowCube: {
3343 case ImageType::DepthCubeArray: {
3346 case ImageType::ShadowCubeArray: {
3349 case ImageType::Int1D: {
3352 case ImageType::Int2D: {
3355 case ImageType::Int3D: {
3358 case ImageType::IntCube: {
3361 case ImageType::Int1DArray: {
3364 case ImageType::Int2DArray: {
3367 case ImageType::IntCubeArray: {
3370 case ImageType::IntBuffer: {
3373 case ImageType::Uint1D: {
3376 case ImageType::Uint2D:
3377 case ImageType::AtomicUint2D:
3378 case ImageType::AtomicInt2D: {
3381 case ImageType::Uint3D:
3382 case ImageType::AtomicUint3D:
3383 case ImageType::AtomicInt3D: {
3386 case ImageType::UintCube: {
3389 case ImageType::Uint1DArray: {
3392 case ImageType::Uint2DArray:
3393 case ImageType::AtomicUint2DArray:
3394 case ImageType::AtomicInt2DArray: {
3397 case ImageType::UintCubeArray: {
3400 case ImageType::UintBuffer: {
3412 switch (this->
type) {
3413 case ImageType::FloatBuffer:
3414 case ImageType::Float1D:
3415 case ImageType::Float1DArray:
3416 case ImageType::Float2D:
3417 case ImageType::Float2DArray:
3418 case ImageType::Float3D:
3419 case ImageType::FloatCube:
3420 case ImageType::FloatCubeArray:
3422 case ImageType::IntBuffer:
3423 case ImageType::Int1D:
3424 case ImageType::Int1DArray:
3425 case ImageType::Int2D:
3426 case ImageType::Int2DArray:
3427 case ImageType::Int3D:
3428 case ImageType::IntCube:
3429 case ImageType::IntCubeArray:
3430 case ImageType::AtomicInt2D:
3431 case ImageType::AtomicInt3D:
3432 case ImageType::AtomicInt2DArray:
3434 case ImageType::UintBuffer:
3435 case ImageType::Uint1D:
3436 case ImageType::Uint1DArray:
3437 case ImageType::Uint2D:
3438 case ImageType::Uint2DArray:
3439 case ImageType::Uint3D:
3440 case ImageType::UintCube:
3441 case ImageType::UintCubeArray:
3442 case ImageType::AtomicUint2D:
3443 case ImageType::AtomicUint3D:
3444 case ImageType::AtomicUint2DArray:
3446 case ImageType::Shadow2D:
3447 case ImageType::Shadow2DArray:
3448 case ImageType::ShadowCube:
3449 case ImageType::ShadowCubeArray:
3450 case ImageType::Depth2D:
3451 case ImageType::Depth2DArray:
3452 case ImageType::DepthCube:
3453 case ImageType::DepthCubeArray:
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
KDTree *BLI_kdtree_nd_ new(unsigned int nodes_len_capacity)
MINLINE uint max_uu(uint a, uint b)
MINLINE int max_ii(int a, int b)
#define UNUSED_VARS_NDEBUG(...)
int GPU_max_textures_vert()
#define MEM_reallocN(vmemh, len)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
std::string generate_msl_texture_vars(ShaderStage shader_stage)
std::string generate_msl_uniform_structs(ShaderStage shader_stage)
std::string generate_msl_global_uniform_population(ShaderStage stage)
void resolve_input_attribute_locations()
std::string generate_msl_vertex_entry_stub()
blender::Vector< MSLBufferBlock > uniform_blocks
bool uses_gpu_viewport_index
blender::Vector< MSLBufferBlock > storage_blocks
std::string generate_msl_vertex_output_population()
shader::DepthWrite depth_write
std::string generate_msl_vertex_in_struct()
std::string generate_msl_uniform_block_population(ShaderStage stage)
bool uses_gl_GlobalInvocationID
void resolve_fragment_output_locations()
blender::Vector< MSLFragmentTileInputAttribute > fragment_tile_inputs
bool use_argument_buffer_for_samplers() const
bool uses_gl_NumWorkGroups
blender::Vector< MSLVertexOutputAttribute > fragment_input_varyings
std::string generate_msl_fragment_input_population()
blender::Vector< MSLVertexOutputAttribute > vertex_output_varyings
uint32_t get_sampler_argument_buffer_bind_index(ShaderStage stage)
bool uses_gl_LocalInvocationID
std::string generate_msl_fragment_inputs_string()
blender::Vector< MSLTextureResource > texture_samplers
bool uses_early_fragment_test
blender::Vector< MSLVertexInputAttribute > vertex_input_attributes
std::string generate_msl_fragment_struct(bool is_input)
std::string generate_msl_uniform_undefs(ShaderStage stage)
std::string generate_msl_compute_inputs_string()
std::string generate_msl_fragment_tile_input_population()
void prepare_from_createinfo(const shader::ShaderCreateInfo *info)
std::string generate_msl_fragment_output_population()
uint32_t max_sampler_index_for_stage(ShaderStage stage) const
blender::Vector< MSLConstant > constants
std::string generate_msl_vertex_out_struct(ShaderStage shader_stage)
uint32_t num_samplers_for_stage(ShaderStage stage) const
std::string generate_msl_fragment_entry_stub()
void generate_msl_uniforms_input_string(std::stringstream &out, ShaderStage stage, bool &is_first_parameter)
blender::Vector< char > clip_distances
blender::Vector< MSLFragmentOutputAttribute > fragment_outputs
MTLShaderInterface * bake_shader_interface(const char *name, const shader::ShaderCreateInfo *info=nullptr)
void generate_msl_textures_input_string(std::stringstream &out, ShaderStage stage, bool &is_first_parameter)
std::string generate_msl_vertex_inputs_string()
bool uses_gl_BaseInstanceARB
int sampler_argument_buffer_bind_index[3]
bool uses_gl_FragStencilRefARB
blender::Vector< MSLUniform > uniforms
std::string generate_msl_compute_entry_stub(const shader::ShaderCreateInfo &info)
std::string generate_msl_vertex_attribute_input_population()
bool uses_gl_LocalInvocationIndex
char * msl_patch_default_get()
static MTLCapabilities & get_capabilities()
static MTLCapabilities capabilities
void set_fragment_function_name(NSString *fragment_function_name)
std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override
void shader_compute_source_from_msl(NSString *input_compute_source)
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override
std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override
void set_vertex_function_name(NSString *vetex_function_name)
void shader_source_from_msl(NSString *input_vertex_source, NSString *input_fragment_source)
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override
std::string resources_declare(const shader::ShaderCreateInfo &info) const override
void set_interface(MTLShaderInterface *interface)
void set_compute_function_name(NSString *compute_function_name)
StringRefNull name_get() const
void * MEM_mallocN(size_t len, const char *str)
static void error(const char *str)
#define MTL_MAX_BUFFER_BINDINGS
#define MTL_MAX_TEXTURE_SLOTS
#define MTL_MAX_DEFAULT_SAMPLERS
#define MTL_LOG_WARNING(info,...)
#define MTL_LOG_ERROR(info,...)
#define shader_debug_printf(...)
#define MTL_SHADER_SPECIALIZATION_CONSTANT_BASE_ID
#define FRAGMENT_TILE_IN_STRUCT_NAME
char datatoc_mtl_shader_shared_hh[]
#define FRAGMENT_OUT_STRUCT_NAME
@ MTL_DATATYPE_INT1010102_NORM
uint mtl_get_data_type_size(MTLInterfaceDataType type)
BLI_INLINE int to_component_count(const Type &type)
@ TEXTURE_ACCESS_READWRITE
uint get_shader_stage_index(ShaderStage stage)
std::mutex msl_patch_default_lock
const char * to_string(ShaderStage stage)
bool is_matrix_type(const std::string &type)
static uint32_t name_buffer_copystr(char **name_buffer_ptr, const char *str_to_copy, uint32_t &name_buffer_size, uint32_t &name_buffer_offset)
MSLFragmentOutputAttribute MSLFragmentTileInputAttribute
constexpr size_t const_strlen(const char *str)
static void shared_variable_assign(const shader::ShaderCreateInfo &info, std::stringstream &ss)
static void extract_and_replace_clipping_distances(std::string &vertex_source, MSLGeneratorInterface &msl_iface)
static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res)
const char * get_shader_stage_instance_name(ShaderStage stage)
static void generate_compilation_constant_declarations(const shader::ShaderCreateInfo *info, std::stringstream &ss)
MTLVertexFormat mtl_datatype_to_vertex_type(MTLInterfaceDataType type)
const char * to_string_msl(const shader::Interpolation &interp)
static char parameter_delimiter(bool &is_first_parameter)
static void split_array(StringRefNull input, std::string &r_name, std::string &r_array)
const char * get_stage_class_name(ShaderStage stage)
static void shared_variable_args(const shader::ShaderCreateInfo &info, std::stringstream &ss)
static std::regex remove_non_numeric_characters("[^0-9]")
int get_matrix_location_count(const std::string &type)
static MTLSamplerAddressMode to_mtl_type(GPUSamplerExtendMode wrap_mode)
std::string get_matrix_subtype(const std::string &type)
std::string get_attribute_conversion_function(bool *uses_conversion, const shader::Type &type)
bool is_builtin_type(std::string type)
static void generate_specialization_constant_declarations(const shader::ShaderCreateInfo *info, std::stringstream &ss)
static void shared_variable_declare(const shader::ShaderCreateInfo &info, std::stringstream &ss)
static void shared_variable_pass(const shader::ShaderCreateInfo &info, std::stringstream &ss)
shader::Qualifier qualifiers
std::string get_msl_return_type_str() const
MSLTextureSamplerAccess access
std::string get_msl_typestring_wrapper(bool is_addr) const
GPUTextureType get_texture_binding_type() const
std::string get_msl_texture_type_str() const
int atomic_fallback_buffer_ssbo_id
GPUSamplerFormat get_sampler_format() const
std::string get_msl_typestring(bool is_addr) const
std::string get_msl_wrapper_type_str() const
bool supports_texture_atomics
std::string glsl_compute_source_
SpecializationConstant::Value value
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< StageInterfaceInfo * > vertex_out_interfaces_
Vector< SubpassIn > subpass_inputs_
Vector< Resource > geometry_resources_
Vector< CompilationConstant, 0 > compilation_constants_
Vector< VertIn > vertex_inputs_
bool early_fragment_test_
Vector< Resource > batch_resources_
Vector< Resource > pass_resources_
Vector< Resource > resources_get_all_() const
Vector< SharedVariable, 0 > shared_variables_
ComputeStageLayout compute_layout_
Vector< SpecializationConstant > specialization_constants_
Vector< FragOut > fragment_outputs_
StringRefNull instance_name