48char *MSLGeneratorInterface::msl_patch_default =
nullptr;
51#define FRAGMENT_OUT_STRUCT_NAME "FragmentOut"
52#define FRAGMENT_TILE_IN_STRUCT_NAME "FragmentTileIn"
54#define ATOMIC_DEFINE_STR "#define MTL_SUPPORTS_TEXTURE_ATOMICS 1\n"
142 char *current_str_begin = &*vertex_source.begin();
143 char *current_str_end = &*vertex_source.end();
145 for (
char *c = current_str_begin + 2; c < current_str_end - 18; c++) {
146 char *base_search = strstr(c,
"gl_ClipDistance[");
147 if (base_search ==
nullptr) {
151 c = base_search + 16;
154 if (*(c + 1) !=
']') {
159 if ((*c >=
'0') && (*c <=
'9')) {
160 char clip_distance_id = ((*c) -
'0');
161 auto found = std::find(
168 *(base_search + 15) =
'_';
169 *(base_search + 17) =
' ';
189 if (array_offset == -1) {
203 os <<
"constant " << res.
uniformbuf.type_name <<
" *" << name_no_array <<
";\n";
211 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
212 if (array_offset == -1) {
227 os << memory_scope << res.
storagebuf.type_name <<
" *" << name_no_array <<
";\n";
242 std::stringstream ss;
245 ss <<
"\n/* Pass Resources. */\n";
249 ss <<
"\n/* Batch Resources. */\n";
253 ss <<
"\n/* Geometry Resources. */\n";
271 std::stringstream ss;
272 ss <<
"\n/* Vertex Inputs. */\n";
289 std::stringstream ss;
290 ss <<
"\n/* Fragment Outputs. */\n";
296 ss <<
"\n/* Fragment Tile inputs. */\n";
305std::string MTLShader::MTLShader::geometry_interface_declare(
335 if (msl_patch_default !=
nullptr) {
337 return msl_patch_default;
340 std::stringstream ss_patch;
343 size_t len = strlen(ss_patch.str().c_str()) + 1;
345 msl_patch_default = (
char *)malloc(
len *
sizeof(
char));
346 memcpy(msl_patch_default, ss_patch.str().c_str(),
len *
sizeof(
char));
348 return msl_patch_default;
353 std::stringstream &ss)
358 ss <<
"constant " << sc.
type <<
" " << sc.
name <<
" [[function_constant(" << index <<
")]];\n";
364 std::stringstream &ss)
368 std::string value_define;
371 value = std::to_string(cc.
value.
u);
374 value = std::to_string(cc.
value.
i);
377 value = cc.
value.
u ?
"true" :
"false";
378 value_define = std::to_string(cc.
value.
u);
383 ss <<
"constant " << cc.
type <<
" " << cc.
name <<
" = " << value <<
";\n";
393 bool uses_create_info = info !=
nullptr;
394 if (!uses_create_info) {
395 MTL_LOG_WARNING(
"Unable to compile shader %p '%s' as no create-info was provided!",
404 return this->generate_msl_from_glsl_compute(info);
410 MSLGeneratorInterface msl_iface(*
this);
416 msl_iface.prepare_from_createinfo(info);
419 BLI_assert(shd_builder_->glsl_vertex_source_.empty() ==
false);
420 BLI_assert(shd_builder_->glsl_fragment_source_.empty() ==
false);
425 std::string msl_defines_string =
"#define GPU_ARB_shader_draw_parameters 1\n";
426 msl_defines_string +=
"#define GPU_ARB_clip_control 1\n";
432 msl_defines_string +=
"#define GPU_ARB_texture_gather 1\n";
435 shd_builder_->glsl_vertex_source_ = msl_defines_string + shd_builder_->glsl_vertex_source_;
436 shd_builder_->glsl_fragment_source_ = msl_defines_string + shd_builder_->glsl_fragment_source_;
446 msl_iface.uses_gl_VertexID = bool(info->
builtins_ & BuiltinBits::VERTEX_ID) ||
447 shd_builder_->glsl_vertex_source_.find(
"gl_VertexID") !=
449 msl_iface.uses_gl_InstanceID = bool(info->
builtins_ & BuiltinBits::INSTANCE_ID) ||
450 shd_builder_->glsl_vertex_source_.find(
"gl_InstanceID") !=
452 shd_builder_->glsl_vertex_source_.find(
"gpu_InstanceIndex") !=
459 msl_iface.uses_gl_BaseInstanceARB = msl_iface.uses_gl_InstanceID ||
460 shd_builder_->glsl_vertex_source_.find(
461 "gl_BaseInstanceARB") != std::string::npos ||
462 shd_builder_->glsl_vertex_source_.find(
"gpu_BaseInstance") !=
464 msl_iface.uses_gl_Position = shd_builder_->glsl_vertex_source_.find(
"gl_Position") !=
466 msl_iface.uses_gl_PointSize = shd_builder_->glsl_vertex_source_.find(
"gl_PointSize") !=
468 msl_iface.uses_gpu_layer = bool(info->
builtins_ & BuiltinBits::LAYER);
469 msl_iface.uses_gpu_viewport_index = bool(info->
builtins_ & BuiltinBits::VIEWPORT_INDEX);
473 std::smatch gl_special_cases;
474 msl_iface.uses_gl_PointCoord = bool(info->
builtins_ & BuiltinBits::POINT_COORD) ||
475 shd_builder_->glsl_fragment_source_.find(
"gl_PointCoord") !=
477 msl_iface.uses_barycentrics = bool(info->
builtins_ & BuiltinBits::BARYCENTRIC_COORD);
478 msl_iface.uses_gl_FrontFacing = bool(info->
builtins_ & BuiltinBits::FRONT_FACING) ||
479 shd_builder_->glsl_fragment_source_.find(
"gl_FrontFacing") !=
481 msl_iface.uses_gl_PrimitiveID = bool(info->
builtins_ & BuiltinBits::PRIMITIVE_ID) ||
482 shd_builder_->glsl_fragment_source_.find(
"gl_PrimitiveID") !=
487 msl_iface.uses_gl_FragColor = shd_builder_->glsl_fragment_source_.find(
"gl_FragColor") !=
492 msl_iface.uses_gl_FragDepth = (info->
depth_write_ != DepthWrite::UNCHANGED) &&
493 shd_builder_->glsl_fragment_source_.find(
"gl_FragDepth") !=
497 msl_iface.uses_gl_FragStencilRefARB = shd_builder_->glsl_fragment_source_.find(
498 "gl_FragStencilRefARB") != std::string::npos;
511 std::stringstream ss_vertex;
512 std::stringstream ss_fragment;
513 ss_vertex <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
514 ss_fragment <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
516 if (
bool(info->
builtins_ & BuiltinBits::TEXTURE_ATOMIC) &&
533 if (msl_iface.use_argument_buffer_for_samplers()) {
534 ss_vertex <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
535 ss_vertex <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
540 ss_vertex << msl_iface.msl_patch_default_get() << std::endl << std::endl;
547 ss_vertex <<
"struct " << iface->
name <<
" {" << std::endl;
548 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
552 ss_vertex <<
"};" << std::endl;
560 ss_vertex <<
"public:" << std::endl;
565 bool is_inside_struct =
false;
571 is_inside_struct =
true;
575 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
578 if (!is_inside_struct) {
582 const char *arraystart = strchr(
inout.name.c_str(),
'[');
583 bool is_array = (arraystart !=
nullptr);
584 int array_len = (is_array) ? std::stoi(std::regex_replace(
589 std::string out_name =
inout.name.c_str();
590 std::size_t
pos = out_name.find(
'[');
591 if (is_array &&
pos != std::string::npos) {
592 out_name.resize(
pos);
596 msl_iface.vertex_output_varyings.append(
605 msl_iface.fragment_input_varyings.append(
617 ss_vertex << msl_iface.generate_msl_vertex_in_struct();
622 if (msl_iface.uses_gl_Position) {
623 ss_vertex <<
"float4 gl_Position;" << std::endl;
625 if (msl_iface.uses_gl_PointSize) {
626 ss_vertex <<
"float gl_PointSize = 1.0;" << std::endl;
628 if (msl_iface.uses_gl_VertexID) {
629 ss_vertex <<
"int gl_VertexID;" << std::endl;
631 if (msl_iface.uses_gl_InstanceID) {
632 ss_vertex <<
"int gl_InstanceID;" << std::endl;
634 if (msl_iface.uses_gl_BaseInstanceARB) {
635 ss_vertex <<
"int gl_BaseInstanceARB;" << std::endl;
637 for (
const int cd : IndexRange(msl_iface.clip_distances.size())) {
638 ss_vertex <<
"float gl_ClipDistance_" << cd <<
";" << std::endl;
642 if (msl_iface.uses_gpu_layer) {
643 ss_vertex <<
"int gpu_Layer = 0;" << std::endl;
645 if (msl_iface.uses_gpu_viewport_index) {
646 ss_vertex <<
"int gpu_ViewportIndex = 0;" << std::endl;
654 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
659 ss_vertex << std::endl;
662 ss_vertex << shd_builder_->glsl_vertex_source_ << std::endl;
663 ss_vertex <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
669 ss_vertex <<
"};" << std::endl;
672 ss_vertex << msl_iface.generate_msl_vertex_entry_stub();
678 if (msl_iface.use_argument_buffer_for_samplers()) {
679 ss_fragment <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
680 ss_fragment <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
685 ss_fragment << msl_iface.msl_patch_default_get() << std::endl << std::endl;
692 ss_fragment <<
"struct " << iface->
name <<
" {" << std::endl;
693 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
697 ss_fragment <<
"};" << std::endl;
704 ss_fragment <<
"public:" << std::endl;
709 bool is_inside_struct =
false;
713 is_inside_struct =
true;
717 for (
const StageInterfaceInfo::InOut &
inout : iface->
inouts) {
720 if (!is_inside_struct) {
728 if (msl_iface.fragment_tile_inputs.is_empty() ==
false) {
729 ss_fragment << msl_iface.generate_msl_fragment_struct(
true);
731 ss_fragment << msl_iface.generate_msl_fragment_struct(
false);
736 ss_fragment <<
"float4 gl_FragCoord;" << std::endl;
737 if (msl_iface.uses_gl_FragColor) {
738 ss_fragment <<
"float4 gl_FragColor;" << std::endl;
740 if (msl_iface.uses_gl_FragDepth) {
741 ss_fragment <<
"float gl_FragDepth;" << std::endl;
743 if (msl_iface.uses_gl_FragStencilRefARB) {
744 ss_fragment <<
"int gl_FragStencilRefARB;" << std::endl;
746 if (msl_iface.uses_gl_PointCoord) {
747 ss_fragment <<
"float2 gl_PointCoord;" << std::endl;
749 if (msl_iface.uses_gl_FrontFacing) {
750 ss_fragment <<
"bool gl_FrontFacing;" << std::endl;
752 if (msl_iface.uses_gl_PrimitiveID) {
753 ss_fragment <<
"uint gl_PrimitiveID;" << std::endl;
757 if (msl_iface.uses_barycentrics) {
758 ss_fragment <<
"vec3 gpu_BaryCoord;\n";
762 if (msl_iface.uses_gpu_layer) {
763 ss_fragment <<
"int gpu_Layer = 0;" << std::endl;
765 if (msl_iface.uses_gpu_viewport_index) {
766 ss_fragment <<
"int gpu_ViewportIndex = 0;" << std::endl;
770 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
777 ss_fragment << shd_builder_->glsl_fragment_source_ << std::endl;
778 ss_fragment <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
781 ss_fragment <<
"};" << std::endl;
784 ss_fragment << msl_iface.generate_msl_fragment_entry_stub();
788#if MTL_SHADER_DEBUG_EXPORT_SOURCE
789 NSFileManager *sharedFM = [NSFileManager defaultManager];
790 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
791 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
792 URLByAppendingPathComponent:
@"Shaders/"
794 [sharedFM createDirectoryAtURL:shader_dir
795 withIntermediateDirectories:YES
798 const char *path_cstr = [shader_dir fileSystemRepresentation];
800 std::ofstream vertex_fs;
802 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedVertexShader.msl")
804 vertex_fs << ss_vertex.str();
807 std::ofstream fragment_fs;
809 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedFragmentShader.msl")
811 fragment_fs << ss_fragment.str();
815 "Vertex Shader Saved to: %s\n",
816 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedFragmentShader.msl").c_str());
820 NSString *msl_final_vert = [NSString stringWithUTF8String:ss_vertex.str().c_str()];
821 NSString *msl_final_frag = [NSString stringWithUTF8String:ss_fragment.str().c_str()];
829 [[NSString stringWithFormat:
@"vertex_function_entry_%s", this->
name] retain]);
831 [[NSString stringWithFormat:
@"fragment_function_entry_%s", this->
name] retain]);
841 uses_gpu_layer = msl_iface.uses_gpu_layer;
842 uses_gpu_viewport_index = msl_iface.uses_gpu_viewport_index;
853 MSLGeneratorInterface msl_iface(*
this);
859 msl_iface.prepare_from_createinfo(info);
862 BLI_assert(shd_builder_->glsl_compute_source_.empty() ==
false);
872 msl_iface.uses_gl_GlobalInvocationID =
873 bool(info->
builtins_ & BuiltinBits::GLOBAL_INVOCATION_ID) ||
874 shd_builder_->glsl_compute_source_.find(
"gl_GlobalInvocationID") != std::string::npos;
876 msl_iface.uses_gl_WorkGroupSize = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_SIZE) ||
877 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupSize") !=
880 msl_iface.uses_gl_WorkGroupID = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_ID) ||
881 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupID") !=
884 msl_iface.uses_gl_NumWorkGroups = bool(info->
builtins_ & BuiltinBits::NUM_WORK_GROUP) ||
885 shd_builder_->glsl_compute_source_.find(
"gl_NumWorkGroups") !=
888 msl_iface.uses_gl_LocalInvocationIndex =
889 bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_INDEX) ||
890 shd_builder_->glsl_compute_source_.find(
"gl_LocalInvocationIndex") != std::string::npos;
892 msl_iface.uses_gl_LocalInvocationID = bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_ID) ||
893 shd_builder_->glsl_compute_source_.find(
894 "gl_LocalInvocationID") != std::string::npos;
897 std::stringstream ss_compute;
898 ss_compute <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
900 ss_compute <<
"#define GPU_ARB_shader_draw_parameters 1\n";
901 ss_compute <<
"#define GPU_ARB_clip_control 1\n";
902 if (
bool(info->
builtins_ & BuiltinBits::TEXTURE_ATOMIC) &&
912 if (msl_iface.use_argument_buffer_for_samplers()) {
913 ss_compute <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
914 ss_compute <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
919 if (msl_iface.uses_gl_WorkGroupSize) {
923 if (msl_iface.uses_gl_WorkGroupSize) {
924 ss_compute <<
"#define MTL_USE_WORKGROUP_SIZE 1" << std::endl;
934 ss_compute << msl_iface.msl_patch_default_get() << std::endl << std::endl;
940 ss_compute <<
"public:" << std::endl;
950 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
955 ss_compute << std::endl;
958 if (msl_iface.uses_gl_GlobalInvocationID) {
959 ss_compute <<
"uint3 gl_GlobalInvocationID;" << std::endl;
961 if (msl_iface.uses_gl_WorkGroupID) {
962 ss_compute <<
"uint3 gl_WorkGroupID;" << std::endl;
964 if (msl_iface.uses_gl_NumWorkGroups) {
965 ss_compute <<
"uint3 gl_NumWorkGroups;" << std::endl;
967 if (msl_iface.uses_gl_LocalInvocationIndex) {
968 ss_compute <<
"uint gl_LocalInvocationIndex;" << std::endl;
970 if (msl_iface.uses_gl_LocalInvocationID) {
971 ss_compute <<
"uint3 gl_LocalInvocationID;" << std::endl;
975 ss_compute << shd_builder_->glsl_compute_source_ << std::endl;
976 ss_compute <<
"#line " STRINGIFY(__LINE__)
" \"" __FILE__
"\"" << std::endl;
982 <<
"(MSL_SHARED_VARS_ARGS) MSL_SHARED_VARS_ASSIGN {}\n";
985 ss_compute <<
"};" << std::endl;
988 ss_compute << msl_iface.generate_msl_compute_entry_stub();
994 [[NSString stringWithFormat:
@"compute_function_entry_%s", this->
name] retain]);
1000#if MTL_SHADER_DEBUG_EXPORT_SOURCE
1001 NSFileManager *sharedFM = [NSFileManager defaultManager];
1002 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
1003 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
1004 URLByAppendingPathComponent:
@"Shaders/"
1006 [sharedFM createDirectoryAtURL:shader_dir
1007 withIntermediateDirectories:YES
1010 const char *path_cstr = [shader_dir fileSystemRepresentation];
1012 std::ofstream compute_fs;
1014 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedComputeShader.msl")
1016 compute_fs << ss_compute.str();
1020 "Compute Shader Saved to: %s\n",
1021 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedComputeShader.msl").c_str());
1024 NSString *msl_final_compute = [NSString stringWithUTF8String:ss_compute.str().c_str()];
1031 this->compute_pso_common_state_.set_compute_workgroup_size(
1048 create_info_ = info;
1060 for (
const auto &constant : create_info_->specialization_constants_) {
1072 int texture_slot_id = 0;
1073 int ubo_buffer_slot_id_ = 0;
1074 int storage_buffer_slot_id_ = 0;
1076 uint max_storage_buffer_location = 0;
1082 int max_sampler_slot = 0;
1083 if (!create_info_->auto_resource_location_) {
1086 max_sampler_slot =
max_ii(res.slot, max_sampler_slot);
1094 switch (res.bind_type) {
1100 if (res.sampler.type == ImageType::FloatBuffer ||
1101 res.sampler.type == ImageType::IntBuffer || res.sampler.type == ImageType::UintBuffer)
1108 msl_tex.
type = res.sampler.type;
1109 msl_tex.
name = res.sampler.name;
1111 msl_tex.
slot = texture_slot_id++;
1112 msl_tex.
location = (create_info_->auto_resource_location_) ? msl_tex.
slot : res.slot;
1136 msl_image.
type = res.image.type;
1137 msl_image.
name = res.image.name;
1138 msl_image.
access = access;
1139 msl_image.
slot = texture_slot_id++;
1140 msl_image.
location = (create_info_->auto_resource_location_) ? msl_image.
slot : res.slot;
1150 BLI_assert(res.uniformbuf.type_name.is_empty() ==
false);
1151 BLI_assert(res.uniformbuf.name.is_empty() ==
false);
1152 int64_t array_offset = res.uniformbuf.name.find_first_of(
"[");
1159 ubo.
slot = 1 + (ubo_buffer_slot_id_++);
1160 ubo.
location = (create_info_->auto_resource_location_) ? ubo.
slot : res.slot;
1165 ubo.
type_name = res.uniformbuf.type_name;
1167 ubo.
is_array = (array_offset > -1);
1171 ubo.
name = name_no_array;
1174 ubo.
name = res.uniformbuf.name;
1182 BLI_assert(res.storagebuf.type_name.is_empty() ==
false);
1183 BLI_assert(res.storagebuf.name.is_empty() ==
false);
1184 int64_t array_offset = res.storagebuf.name.find_first_of(
"[");
1189 ssbo.
slot = storage_buffer_slot_id_++;
1190 ssbo.
location = (create_info_->auto_resource_location_) ? ssbo.
slot : res.slot;
1192 max_storage_buffer_location =
max_uu(max_storage_buffer_location, ssbo.
location);
1197 ssbo.
type_name = res.storagebuf.type_name;
1199 ssbo.
is_array = (array_offset > -1);
1203 ssbo.
name = name_no_array;
1206 ssbo.
name = res.storagebuf.name;
1217 uint atomic_fallback_buffer_count = 0;
1220 ImageType::AtomicUint2D,
1221 ImageType::AtomicUint2DArray,
1222 ImageType::AtomicUint3D,
1223 ImageType::AtomicInt2D,
1224 ImageType::AtomicInt2DArray,
1225 ImageType::AtomicInt3D))
1235 ssbo.
slot = storage_buffer_slot_id_++;
1236 ssbo.
location = max_storage_buffer_location + 1 + atomic_fallback_buffer_count;
1249 ssbo.
name = tex.
name +
"_storagebuf";
1258 atomic_fallback_buffer_count++;
1267 bool all_attr_location_assigned =
true;
1276 bool attr_location_assigned = (attr.
index >= 0);
1277 all_attr_location_assigned = all_attr_location_assigned && attr_location_assigned;
1285 if (!all_attr_location_assigned) {
1319 mtl_frag_in.
type = frag_tile_in.
type;
1320 mtl_frag_in.
name = frag_tile_in.
name;
1323 ImageType::Uint2DArray,
1324 ImageType::Int2DArray,
1325 ImageType::Float2DArray);
1335 msl_image.
name = frag_tile_in.
name +
"_subpass_img";
1337 msl_image.
slot = texture_slot_id++;
1372 "Compiled Shader '%s' is falling back to bindless via argument buffers due to having a "
1373 "texture sampler of Index: %u Which exceeds the limit of 15+1. However shader only uses "
1374 "%d textures. Consider optimising bind points with .auto_resource_location(true).",
1375 parent_shader_.name_get().c_str(),
1381 return use_argument_buffer;
1417 std::stringstream
out;
1418 out << std::endl <<
"/*** AUTO-GENERATED MSL VERETX SHADER STUB. ***/" << std::endl;
1421 out <<
"#undef texture" << std::endl;
1422 out <<
"#undef textureLod" << std::endl;
1425 out <<
"#undef bool" << std::endl;
1434 out <<
"vertex_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
1436 out <<
"vertex_function_entry(\n\t";
1440 out <<
") {" << std::endl << std::endl;
1447 out << shader_stage_inst_name <<
".gl_VertexID = gl_VertexID;" << std::endl;
1450 out << shader_stage_inst_name <<
".gl_InstanceID = gl_InstanceID-gl_BaseInstanceARB;"
1454 out << shader_stage_inst_name <<
".gl_BaseInstanceARB = gl_BaseInstanceARB;" << std::endl;
1466 out <<
"\t/* Execute Vertex main function */\t" << std::endl
1467 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1477 out <<
"if(is_function_constant_defined(MTL_global_pointsize)){ output.pointsize = "
1478 "(MTL_global_pointsize > 0.0)?MTL_global_pointsize:output.pointsize; }"
1480 out <<
"\treturn output;" << std::endl;
1489 std::stringstream
out;
1490 out << std::endl <<
"/*** AUTO-GENERATED MSL FRAGMENT SHADER STUB. ***/" << std::endl;
1493 out <<
"#undef texture" << std::endl;
1494 out <<
"#undef textureLod" << std::endl;
1497 out <<
"#undef bool" << std::endl;
1504 out <<
"[[early_fragment_tests]]" << std::endl;
1517 out <<
") {" << std::endl << std::endl;
1521 <<
";" << std::endl;
1525 out << shader_stage_inst_name <<
".gl_PointCoord = gl_PointCoord;" << std::endl;
1528 out << shader_stage_inst_name <<
".gl_FrontFacing = gl_FrontFacing;" << std::endl;
1531 out <<
"fragment_shader_instance.gl_PrimitiveID = gl_PrimitiveID;" << std::endl;
1539 out << shader_stage_inst_name <<
".gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl;
1553 out <<
"\t/* Execute Fragment main function */\t" << std::endl
1554 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1559 out <<
" return output;" << std::endl <<
"}";
1567 std::stringstream
out;
1568 out << std::endl <<
"/*** AUTO-GENERATED MSL COMPUTE SHADER STUB. ***/" << std::endl;
1571 out <<
"#undef texture" << std::endl;
1572 out <<
"#undef textureLod" << std::endl;
1575 out <<
"#undef bool" << std::endl;
1581 out <<
"kernel void ";
1583 out <<
"compute_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
1585 out <<
"compute_function_entry(\n\t";
1589 out <<
") {" << std::endl << std::endl;
1590 out <<
"MSL_SHARED_VARS_DECLARE\n";
1592 <<
" MSL_SHARED_VARS_PASS;\n";
1597 out << shader_stage_inst_name <<
".gl_GlobalInvocationID = gl_GlobalInvocationID;"
1601 out << shader_stage_inst_name <<
".gl_WorkGroupID = gl_WorkGroupID;" << std::endl;
1604 out << shader_stage_inst_name <<
".gl_NumWorkGroups = gl_NumWorkGroups;" << std::endl;
1607 out << shader_stage_inst_name <<
".gl_LocalInvocationIndex = gl_LocalInvocationIndex;"
1611 out << shader_stage_inst_name <<
".gl_LocalInvocationID = gl_LocalInvocationID;" << std::endl;
1620 out <<
"\t/* Execute Compute main function */\t" << std::endl
1621 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
1632 if (is_first_parameter) {
1633 is_first_parameter =
false;
1641 bool &is_first_parameter)
1650 if (
bool(tex.
stage & stage)) {
1652 <<
" [[texture(" << tex.
slot <<
")]]";
1663 <<
"\n\tconstant SStruct& samplers [[buffer(MTL_uniform_buffer_base_index+"
1671 if (
bool(tex.
stage & stage)) {
1673 <<
"_sampler [[sampler(" << tex.
slot <<
")]]";
1678 if (this->texture_samplers.size() > 16) {
1680 "[Metal] Warning: Shader exceeds limit of %u samplers on current hardware\n",
1688 bool &is_first_parameter)
1691 if (
bool(ubo.stage & stage)) {
1701 out << ubo.type_name <<
"* " << ubo.name <<
"[[buffer(MTL_uniform_buffer_base_index+"
1702 << ubo.slot <<
")]]";
1708 if (
bool(ssbo.stage & stage)) {
1715 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
1716 out << memory_scope;
1725 out << ssbo.type_name <<
"* " << ssbo.name <<
"[[buffer(MTL_storage_buffer_base_index+"
1726 << (ssbo.slot) <<
")]]";
1733 std::stringstream
out;
1734 bool is_first_parameter =
true;
1739 is_first_parameter =
false;
1742 if (this->
uniforms.is_empty() ==
false) {
1745 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1746 is_first_parameter =
false;
1757 <<
"\n\tconst uint32_t gl_VertexID [[vertex_id]]";
1761 <<
"\n\tconst uint32_t gl_InstanceID [[instance_id]]";
1765 <<
"\n\tconst uint32_t gl_BaseInstanceARB [[base_instance]]";
1772 bool is_first_parameter =
true;
1773 std::stringstream
out;
1775 <<
"::VertexOut v_in [[stage_in]]";
1777 if (this->
uniforms.is_empty() ==
false) {
1780 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1790 <<
"\n\tconst float2 gl_PointCoord [[point_coord]]";
1794 <<
"\n\tconst bool gl_FrontFacing [[front_facing]]";
1798 <<
"\n\tconst uint gl_PrimitiveID [[primitive_id]]";
1804 <<
"\n\tconst float3 mtl_barycentric_coord [[barycentric_coord]]";
1818 bool is_first_parameter =
true;
1819 std::stringstream
out;
1820 if (this->
uniforms.is_empty() ==
false) {
1823 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
1834 <<
"\n\tconst uint3 gl_GlobalInvocationID [[thread_position_in_grid]]";
1838 <<
"\n\tconst uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]";
1842 <<
"\n\tconst uint3 gl_NumWorkGroups [[threadgroups_per_grid]]";
1846 <<
"\n\tconst uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]";
1850 <<
"\n\tconst uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]";
1864 std::stringstream
out;
1867 out <<
"typedef struct {" << std::endl;
1870 if (uniform.is_array) {
1871 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
"[" << uniform.array_elems
1872 <<
"];" << std::endl;
1875 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
";" << std::endl;
1878 out <<
"} PushConstantBlock;\n\n";
1881 out << std::endl <<
"const constant PushConstantBlock *global_uniforms;" << std::endl;
1886 for (
const MSLUniform &uniform : this->uniforms) {
1887 out <<
"#define " << uniform.name <<
" global_uniforms->" << uniform.name << std::endl;
1896 std::stringstream
out;
1900 out <<
"#undef " << uniform.name << std::endl;
1904 out <<
"#undef " << ubo.name << std::endl;
1908 out <<
"#undef " << ssbo.name << std::endl;
1915 std::stringstream
out;
1923 out <<
"typedef struct {" << std::endl;
1939 <<
" [[attribute(" << (in_attr.layout_location + elem) <<
")]];" << std::endl;
1943 out <<
"\t" << in_attr.type <<
" " << in_attr.name <<
" [[attribute("
1944 << in_attr.layout_location <<
")]];" << std::endl;
1948 out <<
"} VertexIn;" << std::endl << std::endl;
1956 std::stringstream
out;
1959 out <<
"typedef struct {" << std::endl;
1963 bool first_attr_is_position =
false;
1969 out <<
"\tfloat4 _default_position_ [[position]]";
1970 out <<
" [[invariant]]";
1971 out <<
";" << std::endl;
1980 out <<
" [[invariant]]";
1981 out <<
";" << std::endl;
1982 first_attr_is_position =
true;
1986 bool skip_first_index = first_attr_is_position;
1990 if (skip_first_index) {
1991 skip_first_index =
false;
1995 if (v_out.is_array) {
2002 for (
int i = 0;
i < v_out.array_elems;
i++) {
2003 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name <<
i
2004 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2010 BLI_assert(v_out.get_mtl_interpolation_qualifier() ==
" [[flat]]" &&
2011 "Matrix varying types must have [[flat]] interpolation");
2014 out <<
"\t" << subtype << v_out.instance_name <<
" __matrix_" << v_out.name << elem
2015 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2019 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name
2020 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2032 out <<
"\tfloat pointsize [[point_size]];" << std::endl;
2039 out <<
"\tfloat pointsize [[point_size, function_constant(MTL_global_pointsize)]];"
2046 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl;
2049 out <<
"\tfloat clipdistance [[clip_distance, "
2050 "function_constant(MTL_clip_distances_enabled)]] ["
2054 out <<
"\tfloat clipdistance [[clip_distance, "
2055 "function_constant(MTL_clip_distances_enabled)]];"
2058 out <<
"#endif" << std::endl;
2063 out <<
"\tuint gpu_Layer [[render_target_array_index]];" << std::endl;
2068 out <<
"\tuint gpu_ViewportIndex [[viewport_array_index]];" << std::endl;
2071 out <<
"} VertexOut;" << std::endl << std::endl;
2078 std::stringstream
out;
2083 out <<
"typedef struct {" << std::endl;
2084 for (
int f_output = 0; f_output < fragment_interface_src.size(); f_output++) {
2085 out <<
"\t" <<
to_string(fragment_interface_src[f_output].type) <<
" "
2086 << fragment_interface_src[f_output].name <<
" [[color("
2087 << fragment_interface_src[f_output].layout_location <<
")";
2088 if (fragment_interface_src[f_output].layout_index >= 0) {
2089 out <<
", index(" << fragment_interface_src[f_output].layout_index <<
")";
2091 if (fragment_interface_src[f_output].raster_order_group >= 0) {
2092 out <<
", raster_order_group(" << fragment_interface_src[f_output].raster_order_group <<
")";
2095 <<
";" << std::endl;
2103 out <<
"\tfloat fragdepth [[depth(" << out_depth_argument <<
")]];" << std::endl;
2107 out <<
"\tuint fragstencil [[stencil]];" << std::endl;
2125 std::stringstream
out;
2128 out <<
"\t/* Copy Uniform block member reference */" << std::endl;
2130 <<
"global_uniforms = uniforms;" << std::endl;
2137 std::stringstream
out;
2143 << tile_input.name <<
" = "
2144 <<
"fragment_tile_in." << tile_input.name <<
";" << std::endl;
2150 char swizzle[] =
"xyzw";
2154 std::string texel_co =
2155 (tile_input.is_layered_input) ?
2156 ((is_layered_fb) ?
"ivec3(ivec2(v_in._default_position_.xy), int(v_in.gpu_Layer))" :
2160 "ivec3(ivec2(v_in._default_position_.xy), 0)") :
2161 "ivec2(v_in._default_position_.xy)";
2164 << tile_input.name <<
" = imageLoad("
2166 <<
"_subpass_img, " << texel_co <<
")." << swizzle <<
";\n";
2175 std::stringstream
out;
2176 out <<
"\t/* Copy UBO block references into local class variables */" << std::endl;
2180 if (
bool(ubo.stage & stage)) {
2187 if (!ubo.is_array) {
2190 out <<
" = " << ubo.name <<
";" << std::endl;
2195 out <<
"\t/* Copy SSBO block references into local class variables */" << std::endl;
2199 if (
bool(ssbo.stage & stage) && !ssbo.is_texture_buffer) {
2206 if (!ssbo.is_array) {
2213 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
2215 out <<
"const_cast<" << memory_scope;
2220 out << ssbo.type_name <<
"*>(";
2226 out <<
";" << std::endl;
2240 std::stringstream
out;
2241 out <<
"\t/* Copy Vertex Stage-in attributes into local variables */" << std::endl;
2278 bool do_attribute_conversion_on_read =
false;
2282 if (do_attribute_conversion_on_read) {
2284 out <<
"\t" << attribute_conversion_func_name <<
"(MTL_AttributeConvert"
2290 out <<
"\t" << shader_stage_inst_name <<
"."
2304 std::stringstream
out;
2305 out <<
"\t/* Copy Vertex Outputs into output struct */" << std::endl;
2309 out <<
"\toutput._default_position_ = " << shader_stage_inst_name <<
".gl_Position;"
2314 out <<
"\toutput._default_position_.y = -output._default_position_.y;" << std::endl;
2315 out <<
"\toutput._default_position_.z = "
2316 "(output._default_position_.z+output._default_position_.w)/2.0;"
2322 out <<
"\toutput.pointsize = " << shader_stage_inst_name <<
".gl_PointSize;" << std::endl;
2327 out <<
"\toutput.gpu_Layer = " << shader_stage_inst_name <<
".gpu_Layer;" << std::endl;
2332 out <<
"\toutput.gpu_ViewportIndex = " << shader_stage_inst_name <<
".gpu_ViewportIndex;"
2340 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl
2341 <<
"if(MTL_clip_distances_enabled) {" << std::endl;
2345 out <<
"\toutput.clipdistance[" << cd
2346 <<
"] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd <<
"))?"
2347 << shader_stage_inst_name <<
".gl_ClipDistance_" << cd <<
":1.0;" << std::endl;
2351 out <<
"\toutput.clipdistance = " << shader_stage_inst_name <<
".gl_ClipDistance_0;"
2354 out <<
"}" << std::endl <<
"#endif" << std::endl;
2359 if (v_out.is_array) {
2361 for (
int i = 0;
i < v_out.array_elems;
i++) {
2362 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
i <<
" = "
2363 << shader_stage_inst_name <<
".";
2365 if (v_out.instance_name.empty() ==
false) {
2366 out << v_out.instance_name <<
".";
2369 out << v_out.name <<
"[" <<
i <<
"]"
2370 <<
";" << std::endl;
2377 out <<
"\toutput." << v_out.instance_name <<
"__matrix_" << v_out.name << elem <<
" = "
2378 << shader_stage_inst_name <<
".";
2380 if (v_out.instance_name.empty() ==
false) {
2381 out << v_out.instance_name <<
".";
2384 out << v_out.name <<
"[" << elem <<
"];" << std::endl;
2391 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = to_vec4("
2392 << shader_stage_inst_name <<
"." << v_out.name <<
");" << std::endl;
2395 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
".y = -output."
2396 << v_out.name <<
".y;" << std::endl;
2400 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = "
2401 << shader_stage_inst_name <<
".";
2403 if (v_out.instance_name.empty() ==
false) {
2404 out << v_out.instance_name <<
".";
2407 out << v_out.name <<
";" << std::endl;
2423 std::stringstream
out;
2424 out <<
"\t/* Copy Fragment input into local variables. */" << std::endl;
2428 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in._default_position_;"
2433 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in."
2441 out <<
"\t" << shader_stage_inst_name <<
".gl_FragDepth = " << shader_stage_inst_name
2442 <<
".gl_FragCoord.z;" << std::endl;
2447 out <<
"\t" << shader_stage_inst_name <<
".gpu_Layer = v_in.gpu_Layer;" << std::endl;
2452 out <<
"\t" << shader_stage_inst_name <<
".gpu_ViewportIndex = v_in.gpu_ViewportIndex;"
2468 bool exists_in_vertex_output =
false;
2472 exists_in_vertex_output =
true;
2475 if (!exists_in_vertex_output) {
2477 "[Warning] Fragment shader expects varying input '%s', but this is not passed from "
2485 out <<
"\t" << shader_stage_inst_name <<
".";
2499 out <<
"\t" << shader_stage_inst_name <<
".";
2508 for (
int elem = 0; elem <
count; elem++) {
2509 out << ((elem == 0) ?
"(" :
"") <<
"v_in."
2512 << ((elem <
count - 1) ?
",\n" :
"");
2514 out <<
");" << std::endl;
2517 out <<
"\t" << shader_stage_inst_name <<
".";
2539 std::stringstream
out;
2540 out <<
"\t/* Copy Fragment Outputs into output struct. */" << std::endl;
2544 out <<
"\toutput.fragdepth = " << shader_stage_inst_name <<
".gl_FragDepth;" << std::endl;
2549 out <<
"\toutput.fragstencil = uint(" << shader_stage_inst_name <<
".gl_FragStencilRefARB);"
2554 for (
int f_output = 0; f_output < this->
fragment_outputs.size(); f_output++) {
2556 out <<
"\toutput." << this->
fragment_outputs[f_output].name <<
" = " << shader_stage_inst_name
2570 std::stringstream
out;
2571 out <<
"\t/* Populate local texture and sampler members */" << std::endl;
2578 <<
";" << std::endl;
2589 <<
"_sampler;" << std::endl;
2594 if (tex_buf_id != -1) {
2601 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
2603 out <<
"const_cast<" << memory_scope;
2614 out <<
";" << std::endl;
2623 ImageType::AtomicUint2DArray,
2624 ImageType::AtomicUint3D,
2625 ImageType::AtomicInt2DArray,
2626 ImageType::AtomicInt3D))
2629 << this->
texture_samplers[
i].name <<
".atomic.texture_size = ushort3(uniforms->"
2642 uint32_t used_locations = 0;
2644 if (attr.layout_location >= 0) {
2647 for (uint32_t
i = 1;
i <= location_element_count;
i++) {
2649 uint32_t location_mask = (
i << attr.layout_location);
2650 BLI_assert((used_locations & location_mask) == 0);
2651 used_locations = used_locations | location_mask;
2658 if (attr.layout_location == -1) {
2668 uint32_t location_mask = (1 << loc);
2674 uint32_t location_slot_mask = (1 << required_attr_slot_count) - 1;
2675 uint32_t sliding_location_slot_mask = location_slot_mask << location_mask;
2676 if ((used_locations & sliding_location_slot_mask) == 0) {
2678 attr.layout_location = loc;
2679 used_locations = used_locations | location_slot_mask;
2685 MTL_LOG_ERROR(
"Could not assign attribute location to attribute %s for shader %s",
2687 this->parent_shader_.name_get().c_str());
2694 int running_location_ind = 0;
2700 ((running_location_ind > 0) ? (this->
fragment_outputs[
i].layout_location == -1) :
true),
2701 "Error: Mismatched input attributes, some with location specified, some without");
2704 running_location_ind++;
2714 const char *str_to_copy,
2715 uint32_t &name_buffer_size,
2716 uint32_t &name_buffer_offset)
2722 uint32_t ret_len = strlen(str_to_copy);
2726 if (name_buffer_offset + ret_len + 1 > name_buffer_size) {
2727 name_buffer_size = name_buffer_offset +
max_ii(128, ret_len + 1);
2728 *name_buffer_ptr = (
char *)
MEM_reallocN(*name_buffer_ptr, name_buffer_size);
2732 uint32_t insert_offset = name_buffer_offset;
2733 char *current_offset = (*name_buffer_ptr) + insert_offset;
2734 memcpy(current_offset, str_to_copy, (ret_len + 1) *
sizeof(
char));
2737 name_buffer_offset += ret_len + 1;
2740 return insert_offset;
2751 uint32_t name_buffer_size = 256;
2752 uint32_t name_buffer_offset = 0;
2772 std::string _internal_name = (elem == 0) ?
2776 std::to_string(elem);
2780 _internal_name.c_str(),
2782 name_buffer_offset),
2783 this->vertex_input_attributes[attribute].layout_location + elem,
2794 "[Note] Matrix Type '%s' added to shader interface as vertex attribute. (Elem Count: "
2806 this->vertex_input_attributes[attribute].name.c_str(),
2808 name_buffer_offset),
2809 this->vertex_input_attributes[attribute].layout_location,
2824 &
interface->name_buffer_,
"PushConstantBlock", name_buffer_size, name_buffer_offset));
2826 for (
int uniform = 0; uniform < this->
uniforms.size(); uniform++) {
2829 this->uniforms[uniform].name.c_str(),
2831 name_buffer_offset),
2833 (this->
uniforms[uniform].is_array) ? this->
uniforms[uniform].array_elems : 1);
2837 for (
int uniform_block = 0; uniform_block < this->
uniform_blocks.size(); uniform_block++) {
2840 this->uniform_blocks[uniform_block].name.c_str(),
2842 name_buffer_offset),
2843 this->uniform_blocks[uniform_block].slot,
2844 this->uniform_blocks[uniform_block].location,
2846 this->uniform_blocks[uniform_block].stage);
2850 for (
int storage_block = 0; storage_block < this->
storage_blocks.size(); storage_block++) {
2853 this->storage_blocks[storage_block].name.c_str(),
2855 name_buffer_offset),
2856 this->storage_blocks[storage_block].slot,
2857 this->storage_blocks[storage_block].location,
2859 this->storage_blocks[storage_block].stage);
2865 uint tex_buf_ssbo_location = -1;
2866 uint tex_buf_ssbo_id = input_texture.atomic_fallback_buffer_ssbo_id;
2867 if (tex_buf_ssbo_id != -1) {
2868 tex_buf_ssbo_location = this->
storage_blocks[tex_buf_ssbo_id].location;
2872 input_texture.name.c_str(),
2874 name_buffer_offset),
2876 input_texture.location,
2877 input_texture.get_texture_binding_type(),
2878 input_texture.get_sampler_format(),
2879 input_texture.is_texture_sampler,
2880 input_texture.stage,
2881 tex_buf_ssbo_location);
2887 &
interface->name_buffer_, constant.name.c_str(), name_buffer_size, name_buffer_offset));
2898 interface->prepare_common_shader_inputs(info);
2901 if (name_buffer_offset < name_buffer_size) {
2912 switch (this->
type) {
2913 case ImageType::Float1D: {
2916 case ImageType::Float2D: {
2919 case ImageType::Float3D: {
2922 case ImageType::FloatCube: {
2923 return "texturecube";
2925 case ImageType::Float1DArray: {
2926 return "texture1d_array";
2928 case ImageType::Float2DArray: {
2929 return "texture2d_array";
2931 case ImageType::FloatCubeArray: {
2932 return "texturecube_array";
2934 case ImageType::FloatBuffer: {
2935 return "texture_buffer";
2937 case ImageType::Depth2D: {
2940 case ImageType::Shadow2D: {
2943 case ImageType::Depth2DArray: {
2944 return "depth2d_array";
2946 case ImageType::Shadow2DArray: {
2947 return "depth2d_array";
2949 case ImageType::DepthCube: {
2952 case ImageType::ShadowCube: {
2955 case ImageType::DepthCubeArray: {
2956 return "depthcube_array";
2958 case ImageType::ShadowCubeArray: {
2959 return "depthcube_array";
2961 case ImageType::Int1D: {
2964 case ImageType::Int2D: {
2967 case ImageType::Int3D: {
2970 case ImageType::IntCube: {
2971 return "texturecube";
2973 case ImageType::Int1DArray: {
2974 return "texture1d_array";
2976 case ImageType::Int2DArray: {
2977 return "texture2d_array";
2979 case ImageType::IntCubeArray: {
2980 return "texturecube_array";
2982 case ImageType::IntBuffer: {
2983 return "texture_buffer";
2985 case ImageType::Uint1D: {
2988 case ImageType::Uint2D: {
2991 case ImageType::Uint3D: {
2994 case ImageType::UintCube: {
2995 return "texturecube";
2997 case ImageType::Uint1DArray: {
2998 return "texture1d_array";
3000 case ImageType::Uint2DArray: {
3001 return "texture2d_array";
3003 case ImageType::UintCubeArray: {
3004 return "texturecube_array";
3006 case ImageType::UintBuffer: {
3007 return "texture_buffer";
3011 case ImageType::AtomicInt2D:
3012 case ImageType::AtomicUint2D: {
3015 case ImageType::AtomicInt2DArray:
3016 case ImageType::AtomicUint2DArray: {
3017 if (supports_native_atomics) {
3018 return "texture2d_array";
3024 case ImageType::AtomicInt3D:
3025 case ImageType::AtomicUint3D: {
3026 if (supports_native_atomics) {
3046 switch (this->
type) {
3047 case ImageType::Float1D: {
3048 return "_mtl_sampler_1d";
3050 case ImageType::Float2D: {
3051 return "_mtl_sampler_2d";
3053 case ImageType::Float3D: {
3054 return "_mtl_sampler_3d";
3056 case ImageType::FloatCube: {
3057 return "_mtl_sampler_cube";
3059 case ImageType::Float1DArray: {
3060 return "_mtl_sampler_1d_array";
3062 case ImageType::Float2DArray: {
3063 return "_mtl_sampler_2d_array";
3065 case ImageType::FloatCubeArray: {
3066 return "_mtl_sampler_cube_array";
3068 case ImageType::FloatBuffer: {
3069 return "_mtl_sampler_buffer";
3071 case ImageType::Depth2D: {
3072 return "_mtl_sampler_depth_2d";
3074 case ImageType::Shadow2D: {
3075 return "_mtl_sampler_depth_2d";
3077 case ImageType::Depth2DArray: {
3078 return "_mtl_sampler_depth_2d_array";
3080 case ImageType::Shadow2DArray: {
3081 return "_mtl_sampler_depth_2d_array";
3083 case ImageType::DepthCube: {
3084 return "_mtl_sampler_depth_cube";
3086 case ImageType::ShadowCube: {
3087 return "_mtl_sampler_depth_cube";
3089 case ImageType::DepthCubeArray: {
3090 return "_mtl_sampler_depth_cube_array";
3092 case ImageType::ShadowCubeArray: {
3093 return "_mtl_sampler_depth_cube_array";
3095 case ImageType::Int1D: {
3096 return "_mtl_sampler_1d";
3098 case ImageType::Int2D: {
3099 return "_mtl_sampler_2d";
3101 case ImageType::Int3D: {
3102 return "_mtl_sampler_3d";
3104 case ImageType::IntCube: {
3105 return "_mtl_sampler_cube";
3107 case ImageType::Int1DArray: {
3108 return "_mtl_sampler_1d_array";
3110 case ImageType::Int2DArray: {
3111 return "_mtl_sampler_2d_array";
3113 case ImageType::IntCubeArray: {
3114 return "_mtl_sampler_cube_array";
3116 case ImageType::IntBuffer: {
3117 return "_mtl_sampler_buffer";
3119 case ImageType::Uint1D: {
3120 return "_mtl_sampler_1d";
3122 case ImageType::Uint2D: {
3123 return "_mtl_sampler_2d";
3125 case ImageType::Uint3D: {
3126 return "_mtl_sampler_3d";
3128 case ImageType::UintCube: {
3129 return "_mtl_sampler_cube";
3131 case ImageType::Uint1DArray: {
3132 return "_mtl_sampler_1d_array";
3134 case ImageType::Uint2DArray: {
3135 return "_mtl_sampler_2d_array";
3137 case ImageType::UintCubeArray: {
3138 return "_mtl_sampler_cube_array";
3140 case ImageType::UintBuffer: {
3141 return "_mtl_sampler_buffer";
3145 case ImageType::AtomicInt2D:
3146 case ImageType::AtomicUint2D: {
3147 if (supports_native_atomics) {
3148 return "_mtl_sampler_2d";
3151 return "_mtl_sampler_2d_atomic";
3154 case ImageType::AtomicInt3D:
3155 case ImageType::AtomicUint3D: {
3156 if (supports_native_atomics) {
3157 return "_mtl_sampler_3d";
3160 return "_mtl_sampler_3d_atomic";
3163 case ImageType::AtomicInt2DArray:
3164 case ImageType::AtomicUint2DArray: {
3165 if (supports_native_atomics) {
3166 return "_mtl_sampler_2d_array";
3169 return "_mtl_sampler_2d_array_atomic";
3183 switch (this->
type) {
3185 case ImageType::Float1D:
3186 case ImageType::Float2D:
3187 case ImageType::Float3D:
3188 case ImageType::FloatCube:
3189 case ImageType::Float1DArray:
3190 case ImageType::Float2DArray:
3191 case ImageType::FloatCubeArray:
3192 case ImageType::FloatBuffer:
3193 case ImageType::Depth2D:
3194 case ImageType::Shadow2D:
3195 case ImageType::Depth2DArray:
3196 case ImageType::Shadow2DArray:
3197 case ImageType::DepthCube:
3198 case ImageType::ShadowCube:
3199 case ImageType::DepthCubeArray:
3200 case ImageType::ShadowCubeArray: {
3204 case ImageType::Int1D:
3205 case ImageType::Int2D:
3206 case ImageType::Int3D:
3207 case ImageType::IntCube:
3208 case ImageType::Int1DArray:
3209 case ImageType::Int2DArray:
3210 case ImageType::IntCubeArray:
3211 case ImageType::IntBuffer:
3212 case ImageType::AtomicInt2D:
3213 case ImageType::AtomicInt2DArray:
3214 case ImageType::AtomicInt3D: {
3219 case ImageType::Uint1D:
3220 case ImageType::Uint2D:
3221 case ImageType::Uint3D:
3222 case ImageType::UintCube:
3223 case ImageType::Uint1DArray:
3224 case ImageType::Uint2DArray:
3225 case ImageType::UintCubeArray:
3226 case ImageType::UintBuffer:
3227 case ImageType::AtomicUint2D:
3228 case ImageType::AtomicUint2DArray:
3229 case ImageType::AtomicUint3D: {
3244 switch (this->
type) {
3245 case ImageType::Float1D: {
3248 case ImageType::Float2D: {
3251 case ImageType::Float3D: {
3254 case ImageType::FloatCube: {
3257 case ImageType::Float1DArray: {
3260 case ImageType::Float2DArray: {
3263 case ImageType::FloatCubeArray: {
3266 case ImageType::FloatBuffer: {
3269 case ImageType::Depth2D: {
3272 case ImageType::Shadow2D: {
3275 case ImageType::Depth2DArray: {
3278 case ImageType::Shadow2DArray: {
3281 case ImageType::DepthCube: {
3284 case ImageType::ShadowCube: {
3287 case ImageType::DepthCubeArray: {
3290 case ImageType::ShadowCubeArray: {
3293 case ImageType::Int1D: {
3296 case ImageType::Int2D: {
3299 case ImageType::Int3D: {
3302 case ImageType::IntCube: {
3305 case ImageType::Int1DArray: {
3308 case ImageType::Int2DArray: {
3311 case ImageType::IntCubeArray: {
3314 case ImageType::IntBuffer: {
3317 case ImageType::Uint1D: {
3320 case ImageType::Uint2D:
3321 case ImageType::AtomicUint2D:
3322 case ImageType::AtomicInt2D: {
3325 case ImageType::Uint3D:
3326 case ImageType::AtomicUint3D:
3327 case ImageType::AtomicInt3D: {
3330 case ImageType::UintCube: {
3333 case ImageType::Uint1DArray: {
3336 case ImageType::Uint2DArray:
3337 case ImageType::AtomicUint2DArray:
3338 case ImageType::AtomicInt2DArray: {
3341 case ImageType::UintCubeArray: {
3344 case ImageType::UintBuffer: {
3356 switch (this->
type) {
3357 case ImageType::FloatBuffer:
3358 case ImageType::Float1D:
3359 case ImageType::Float1DArray:
3360 case ImageType::Float2D:
3361 case ImageType::Float2DArray:
3362 case ImageType::Float3D:
3363 case ImageType::FloatCube:
3364 case ImageType::FloatCubeArray:
3366 case ImageType::IntBuffer:
3367 case ImageType::Int1D:
3368 case ImageType::Int1DArray:
3369 case ImageType::Int2D:
3370 case ImageType::Int2DArray:
3371 case ImageType::Int3D:
3372 case ImageType::IntCube:
3373 case ImageType::IntCubeArray:
3374 case ImageType::AtomicInt2D:
3375 case ImageType::AtomicInt3D:
3376 case ImageType::AtomicInt2DArray:
3378 case ImageType::UintBuffer:
3379 case ImageType::Uint1D:
3380 case ImageType::Uint1DArray:
3381 case ImageType::Uint2D:
3382 case ImageType::Uint2DArray:
3383 case ImageType::Uint3D:
3384 case ImageType::UintCube:
3385 case ImageType::UintCubeArray:
3386 case ImageType::AtomicUint2D:
3387 case ImageType::AtomicUint3D:
3388 case ImageType::AtomicUint2DArray:
3390 case ImageType::Shadow2D:
3391 case ImageType::Shadow2DArray:
3392 case ImageType::ShadowCube:
3393 case ImageType::ShadowCubeArray:
3394 case ImageType::Depth2D:
3395 case ImageType::Depth2DArray:
3396 case ImageType::DepthCube:
3397 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()
for(;discarded_id_iter !=nullptr;discarded_id_iter=static_cast< ID * >(discarded_id_iter->next))
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
std::string generate_msl_compute_entry_stub()
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_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
#define MEM_reallocN(vmemh, len)
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_defines_msl[]
char datatoc_mtl_shader_shared_hh[]
#define ATOMIC_DEFINE_STR
#define FRAGMENT_OUT_STRUCT_NAME
@ MTL_DATATYPE_INT1010102_NORM
uint mtl_get_data_type_size(eMTLDataType 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 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)
const char * to_string_msl(const shader::Interpolation &interp)
static char parameter_delimiter(bool &is_first_parameter)
const char * get_stage_class_name(ShaderStage stage)
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)
MTLVertexFormat mtl_datatype_to_vertex_type(eMTLDataType type)
shader::Qualifier qualifiers
eGPUSamplerFormat get_sampler_format() const
std::string get_msl_return_type_str() const
MSLTextureSamplerAccess access
std::string get_msl_typestring_wrapper(bool is_addr) const
std::string get_msl_texture_type_str() const
int atomic_fallback_buffer_ssbo_id
eGPUTextureType get_texture_binding_type() 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
ComputeStageLayout compute_layout_
Vector< SpecializationConstant > specialization_constants_
Vector< FragOut > fragment_outputs_
StringRefNull instance_name