47char *MSLGeneratorInterface::msl_patch_default =
nullptr;
50#define FRAGMENT_OUT_STRUCT_NAME "FragmentOut"
51#define FRAGMENT_TILE_IN_STRUCT_NAME "FragmentTileIn"
53#define ATOMIC_DEFINE_STR "#define MTL_SUPPORTS_TEXTURE_ATOMICS 1\n"
137 char *current_str_begin = &*
str.begin();
138 char *current_str_end = &*
str.end();
140 bool is_inside_comment =
false;
141 for (
char *c = current_str_begin; c < current_str_end; c++) {
142 if (is_inside_comment) {
143 if ((*c ==
'*') && (c < current_str_end - 1) && (*(c + 1) ==
'/')) {
144 is_inside_comment =
false;
153 if ((*c ==
'/') && (c < current_str_end - 1) && (*(c + 1) ==
'*')) {
154 is_inside_comment =
true;
163 char *current_str_begin = &*
str.begin();
164 char *current_str_end = &*
str.end();
166 bool is_inside_comment =
false;
167 for (
char *c = current_str_begin; c < current_str_end; c++) {
168 if (is_inside_comment) {
170 is_inside_comment =
false;
177 if ((*c ==
'/') && (c < current_str_end - 1) && (*(c + 1) ==
'/')) {
178 is_inside_comment =
true;
188 for (
const char *c = chr; *c !=
'\0'; c++) {
191 if ((ch >=
'a' && ch <=
'z') || (ch >=
'A' && ch <=
'Z') ||
192 (numchars > 0 && ch >=
'0' && ch <=
'9') || ch ==
'_' || ch ==
'#')
198 return (numchars > 0);
208 char last_char =
' ';
210 for (start = array_loc - 1; (start >=
min) && (*start !=
'\0'); start--) {
212 if ((ch >=
'a' && ch <=
'z') || (ch >=
'A' && ch <=
'Z') || (ch >=
'0' && ch <=
'9') ||
213 ch ==
'_' || ch ==
'#')
225 if ((last_char >=
'0' && last_char <=
'9')) {
241 for (
char *c = current_str_begin + 2; c < current_str_end - 18; c++) {
242 char *base_search = strstr(c,
"gl_ClipDistance[");
243 if (base_search ==
nullptr) {
247 c = base_search + 16;
250 if (*(c + 1) !=
']') {
255 if ((*c >=
'0') && (*c <=
'9')) {
256 char clip_distance_id = ((*c) -
'0');
257 auto found = std::find(
264 *(base_search + 15) =
'_';
265 *(base_search + 17) =
' ';
278 char *current_str_begin = &*
str.begin();
279 char *current_str_end = &*
str.end();
281 for (
char *c = current_str_begin + 2; c < current_str_end - 6; c++) {
282 char *start = strstr(c,
"out ");
283 if (start ==
nullptr) {
288 if (strncmp(c - 2,
"in", 2) == 0) {
294 char *word_base1 = c + 4;
295 char *word_base2 = word_base1;
297 if (
is_program_word(word_base1, &len1) && (*(word_base1 + len1) ==
' ')) {
298 word_base2 = word_base1 + len1 + 1;
301 bool is_array = (*(word_base2 + len2) ==
'[');
307 char *array_end = strchr(word_base2 + len2,
']');
308 if (array_end !=
nullptr) {
316 *(word_base2 - 1) =
',';
317 *(word_base2 + len2) =
',';
330 *(word_base2 - 1) =
'&';
346 char *current_str_begin = &*
str.begin();
347 char *current_str_end = &*
str.end();
349 for (
char *c = current_str_begin; c < current_str_end - 10; c++) {
350 char *base_scan = strstr(c,
"mat");
351 if (base_scan ==
nullptr) {
355 char *constructor_end =
nullptr;
359 if (!(*c ==
'2' || *c ==
'3' || *c ==
'4')) {
368 if (*c ==
'2' || *c ==
'3' || *c ==
'4') {
387 if (constructor_end !=
nullptr) {
396 char *current_str_begin = &*
str.begin();
397 char *current_str_end = &*
str.end();
399 for (
char *c = current_str_begin; c < current_str_end - 6; c++) {
405 char *array_scan = strchr(c,
'[');
406 if (array_scan ==
nullptr) {
410 char *base_type_name = array_scan - 1 - typelen;
416 char *closing_square_brace = strchr(c,
']');
417 if (closing_square_brace !=
nullptr) {
418 c = closing_square_brace;
419 char *first_bracket = c + 1;
420 if (*first_bracket ==
'(') {
422 char *semi_colon = strchr(c,
';');
423 if (semi_colon !=
nullptr && *(semi_colon - 1) ==
')') {
424 char *closing_bracket = semi_colon - 1;
427 *first_bracket =
'{';
428 *closing_bracket =
'}';
429 for (
char *
clear = base_type_name;
clear <= closing_square_brace;
clear++) {
451 int nested_bracket_depth = 0;
452 for (
char *c = current_str_begin; c < current_str_end; c++) {
454 if (*c ==
'{' || *c ==
'[' || *c ==
'(') {
455 nested_bracket_depth++;
458 if (*c ==
'}' || *c ==
']' || *c ==
')') {
459 nested_bracket_depth--;
463 return (nested_bracket_depth == 0);
476 std::stringstream & )
478 char *current_str_begin = &*
str.begin();
479 char *current_str_end = &*
str.end();
481 int nested_bracket_depth = 0;
482 for (
char *c = current_str_begin; c < current_str_end - 6; c++) {
484 if (*c ==
'{' || *c ==
'[' || *c ==
'(') {
485 nested_bracket_depth++;
488 if (*c ==
'}' || *c ==
']' || *c ==
')') {
489 nested_bracket_depth--;
495 if (nested_bracket_depth == 0 && strncmp(c,
"const ", 6) == 0 &&
496 strncmp(c,
"const constant ", 15) != 0)
498 char *c_expr_end = strchr(c,
';');
501 "[PERFORMANCE WARNING] Global scope constant expression found - These get allocated "
502 "per-thread in METAL - Best to use Macro's or uniforms to avoid overhead: '%.*s'",
503 (
int)(c_expr_end + 1 - c),
517 const std::string &in_vertex_src,
518 MTLPrimitiveType &out_prim_tye,
522 static std::regex use_ssbo_fetch_mode_find(
524 "USE_SSBO_VERTEX_FETCH\\(\\s*(TriangleList|LineList|TriangleStrip|\\w+)\\s*,\\s*([0-9]+)\\s*"
528 std::smatch vertex_shader_ssbo_flags;
529 bool uses_ssbo_fetch =
false;
530 if (in_vertex_src.find(
"#pragma USE_SSBO_VERTEX_FETCH") != std::string::npos) {
531 uses_ssbo_fetch = std::regex_search(
532 in_vertex_src, vertex_shader_ssbo_flags, use_ssbo_fetch_mode_find);
534 if (uses_ssbo_fetch) {
545 std::string str_output_primitive_type = vertex_shader_ssbo_flags[1].str();
546 std::string str_output_prim_count_per_vertex = vertex_shader_ssbo_flags[2].str();
549 if (str_output_primitive_type ==
"TriangleList") {
550 out_prim_tye = MTLPrimitiveTypeTriangle;
552 else if (str_output_primitive_type ==
"LineList") {
553 out_prim_tye = MTLPrimitiveTypeLine;
555 else if (str_output_primitive_type ==
"TriangleStrip") {
556 out_prim_tye = MTLPrimitiveTypeTriangleStrip;
559 MTL_LOG_ERROR(
"Unsupported output primitive type for SSBO VERTEX FETCH MODE. Shader: %s",
565 out_num_output_verts = std::stoi(
583 std::string &glsl_compute_source)
586 char *current_str_begin = &*glsl_compute_source.begin();
587 char *current_str_end = &*glsl_compute_source.end();
589 for (
char *c = current_str_begin; c < current_str_end - 6; c++) {
591 char *c_expr_start = strstr(c,
"shared ");
592 if (c_expr_start ==
nullptr) {
603 char *c_expr_end = strstr(c,
";");
604 if (c_expr_end ==
nullptr) {
621 if (c_next_space ==
nullptr) {
625 int len = c_next_space - c;
628 new_shared_block.
type_name = std::string(buf);
634 c = c_next_space + 1;
644 char *varname_end =
nullptr;
645 if (c_array_begin !=
nullptr) {
647 if (c_next_space !=
nullptr) {
648 varname_end = (c_next_space < c_array_begin) ? c_next_space : c_array_begin;
651 varname_end = c_array_begin;
657 if (c_next_space !=
nullptr) {
658 varname_end = (c_next_space < c_expr_end) ? c_next_space : c_expr_end;
661 varname_end = c_expr_end;
665 len = varname_end - c;
668 new_shared_block.
varname = std::string(buf);
672 int len = c_expr_end - c_array_begin;
674 new_shared_block.
array_decl = std::string(buf);
684 for (
char *c = c_expr_start; c <= c_expr_end; c++) {
687 std::string out_str =
"TG ";
689 out_str += (new_shared_block.
is_array) ?
"(&" :
"&";
690 out_str += new_shared_block.
varname;
695 memcpy(c_expr_start, out_str.c_str(), (out_str.length() - 1) *
sizeof(
char));
719 if (array_offset == -1) {
733 os <<
"constant " << res.
uniformbuf.type_name <<
" *" << name_no_array <<
";\n";
741 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
742 if (array_offset == -1) {
757 os << memory_scope << res.
storagebuf.type_name <<
" *" << name_no_array <<
";\n";
772 std::stringstream ss;
775 ss <<
"\n/* Pass Resources. */\n";
779 ss <<
"\n/* Batch Resources. */\n";
783 ss <<
"\n/* Geometry Resources. */\n";
801 std::stringstream ss;
802 ss <<
"\n/* Vertex Inputs. */\n";
819 std::stringstream ss;
820 ss <<
"\n/* Fragment Outputs. */\n";
826 ss <<
"\n/* Fragment Tile inputs. */\n";
835std::string MTLShader::MTLShader::geometry_interface_declare(
864 if (msl_patch_default !=
nullptr) {
865 return msl_patch_default;
868 std::stringstream ss_patch;
871 size_t len = strlen(ss_patch.str().c_str()) + 1;
873 msl_patch_default = (
char *)malloc(
len *
sizeof(
char));
874 memcpy(msl_patch_default, ss_patch.str().c_str(),
len *
sizeof(
char));
875 return msl_patch_default;
880 std::stringstream &ss)
885 ss <<
"constant " << sc.
type <<
" " << sc.
name <<
" [[function_constant(" << index <<
")]];\n";
896 bool uses_create_info = info !=
nullptr;
897 if (!uses_create_info) {
898 MTL_LOG_WARNING(
"Unable to compile shader %p '%s' as no create-info was provided!",
907 return this->generate_msl_from_glsl_compute(info);
913 MSLGeneratorInterface msl_iface(*
this);
919 msl_iface.prepare_from_createinfo(info);
922 BLI_assert(shd_builder_->glsl_vertex_source_.size() > 0);
923 if (!msl_iface.uses_transform_feedback) {
924 BLI_assert(shd_builder_->glsl_fragment_source_.size() > 0);
930 msl_iface.uses_transform_feedback =
true;
936 std::string msl_defines_string =
"#define GPU_ARB_shader_draw_parameters 1\n";
942 msl_defines_string +=
"#define GPU_ARB_texture_gather 1\n";
945 shd_builder_->glsl_vertex_source_ = msl_defines_string + shd_builder_->glsl_vertex_source_;
946 if (!msl_iface.uses_transform_feedback) {
947 shd_builder_->glsl_fragment_source_ = msl_defines_string + shd_builder_->glsl_fragment_source_;
957 MTLPrimitiveType vertex_fetch_ssbo_output_prim_type = MTLPrimitiveTypeTriangle;
958 uint32_t vertex_fetch_ssbo_num_output_verts = 0;
962 shd_builder_->glsl_vertex_source_,
963 vertex_fetch_ssbo_output_prim_type,
964 vertex_fetch_ssbo_num_output_verts);
966 if (msl_iface.uses_ssbo_vertex_fetch_mode) {
968 "[Shader] SSBO VERTEX FETCH Enabled for Shader '%s' With Output primitive type: %s, "
969 "vertex count: %u\n",
971 output_primitive_type.c_str(),
972 vertex_fetch_ssbo_num_output_verts);
979 if (!msl_iface.uses_transform_feedback) {
992 msl_iface.uses_gl_VertexID = bool(info->
builtins_ & BuiltinBits::VERTEX_ID) ||
993 shd_builder_->glsl_vertex_source_.find(
"gl_VertexID") !=
995 msl_iface.uses_gl_InstanceID = bool(info->
builtins_ & BuiltinBits::INSTANCE_ID) ||
996 shd_builder_->glsl_vertex_source_.find(
"gl_InstanceID") !=
998 shd_builder_->glsl_vertex_source_.find(
"gpu_InstanceIndex") !=
1000 msl_iface.uses_ssbo_vertex_fetch_mode;
1006 msl_iface.uses_gl_BaseInstanceARB = msl_iface.uses_gl_InstanceID ||
1007 shd_builder_->glsl_vertex_source_.find(
1008 "gl_BaseInstanceARB") != std::string::npos ||
1009 shd_builder_->glsl_vertex_source_.find(
"gpu_BaseInstance") !=
1011 msl_iface.uses_gl_Position = shd_builder_->glsl_vertex_source_.find(
"gl_Position") !=
1013 msl_iface.uses_gl_PointSize = shd_builder_->glsl_vertex_source_.find(
"gl_PointSize") !=
1015 msl_iface.uses_gpu_layer = bool(info->
builtins_ & BuiltinBits::LAYER);
1016 msl_iface.uses_gpu_viewport_index = bool(info->
builtins_ & BuiltinBits::VIEWPORT_INDEX);
1019 if (!msl_iface.uses_transform_feedback) {
1020 std::smatch gl_special_cases;
1021 msl_iface.uses_gl_PointCoord = bool(info->
builtins_ & BuiltinBits::POINT_COORD) ||
1022 shd_builder_->glsl_fragment_source_.find(
"gl_PointCoord") !=
1024 msl_iface.uses_barycentrics = bool(info->
builtins_ & BuiltinBits::BARYCENTRIC_COORD);
1025 msl_iface.uses_gl_FrontFacing = bool(info->
builtins_ & BuiltinBits::FRONT_FACING) ||
1026 shd_builder_->glsl_fragment_source_.find(
"gl_FrontFacing") !=
1028 msl_iface.uses_gl_PrimitiveID = bool(info->
builtins_ & BuiltinBits::PRIMITIVE_ID) ||
1029 shd_builder_->glsl_fragment_source_.find(
"gl_PrimitiveID") !=
1034 msl_iface.uses_gl_FragColor = shd_builder_->glsl_fragment_source_.find(
"gl_FragColor") !=
1039 msl_iface.uses_gl_FragDepth = (info->
depth_write_ != DepthWrite::UNCHANGED) &&
1040 shd_builder_->glsl_fragment_source_.find(
"gl_FragDepth") !=
1044 msl_iface.uses_gl_FragStencilRefARB = shd_builder_->glsl_fragment_source_.find(
1045 "gl_FragStencilRefARB") != std::string::npos;
1054 if (msl_iface.uses_ssbo_vertex_fetch_mode) {
1055 msl_iface.prepare_ssbo_vertex_fetch_uniforms();
1063 if (!msl_iface.uses_transform_feedback) {
1069 std::stringstream ss_vertex;
1070 std::stringstream ss_fragment;
1071 ss_vertex <<
"#line 1 \"msl_wrapper_code\"\n";
1072 ss_fragment <<
"#line 1 \"msl_wrapper_code\"\n";
1074 if (
bool(info->
builtins_ & BuiltinBits::TEXTURE_ATOMIC) &&
1087 if (msl_iface.use_argument_buffer_for_samplers()) {
1088 ss_vertex <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
1089 ss_vertex <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
1092 if (msl_iface.uses_ssbo_vertex_fetch_mode) {
1093 ss_vertex <<
"#define MTL_SSBO_VERTEX_FETCH 1" << std::endl;
1094 for (
const MSLVertexInputAttribute &attr : msl_iface.vertex_input_attributes) {
1095 ss_vertex <<
"#define SSBO_ATTR_TYPE_" << attr.
name <<
" " << attr.
type << std::endl;
1099 ss_vertex <<
"#define "
1122 ss_vertex << msl_iface.msl_patch_default_get() << std::endl << std::endl;
1138 ss_vertex <<
"struct " << iface->
name <<
" {" << std::endl;
1139 for (
const StageInterfaceInfo::InOut &inout : iface->
inouts) {
1143 ss_vertex <<
"};" << std::endl;
1151 ss_vertex <<
"public:" << std::endl;
1156 bool is_inside_struct =
false;
1162 is_inside_struct =
true;
1166 for (
const StageInterfaceInfo::InOut &inout : iface->
inouts) {
1169 if (!is_inside_struct) {
1173 const char *arraystart = strchr(inout.
name.
c_str(),
'[');
1174 bool is_array = (arraystart !=
nullptr);
1175 int array_len = (is_array) ? std::stoi(std::regex_replace(
1180 std::string out_name = inout.
name.
c_str();
1181 std::size_t
pos = out_name.find(
'[');
1182 if (is_array &&
pos != std::string::npos) {
1183 out_name.resize(
pos);
1187 msl_iface.vertex_output_varyings.append(
1196 msl_iface.fragment_input_varyings.append(
1208 if (!msl_iface.uses_ssbo_vertex_fetch_mode) {
1209 ss_vertex << msl_iface.generate_msl_vertex_in_struct();
1215 if (msl_iface.uses_gl_Position) {
1216 ss_vertex <<
"float4 gl_Position;" << std::endl;
1218 if (msl_iface.uses_gl_PointSize) {
1219 ss_vertex <<
"float gl_PointSize = 1.0;" << std::endl;
1221 if (msl_iface.uses_gl_VertexID) {
1222 ss_vertex <<
"int gl_VertexID;" << std::endl;
1224 if (msl_iface.uses_gl_InstanceID) {
1225 ss_vertex <<
"int gl_InstanceID;" << std::endl;
1227 if (msl_iface.uses_gl_BaseInstanceARB) {
1228 ss_vertex <<
"int gl_BaseInstanceARB;" << std::endl;
1230 for (
const int cd : IndexRange(msl_iface.clip_distances.size())) {
1231 ss_vertex <<
"float gl_ClipDistance_" << cd <<
";" << std::endl;
1235 if (msl_iface.uses_gpu_layer) {
1236 ss_vertex <<
"int gpu_Layer = 0;" << std::endl;
1238 if (msl_iface.uses_gpu_viewport_index) {
1239 ss_vertex <<
"int gpu_ViewportIndex = 0;" << std::endl;
1246 if (msl_iface.uses_ssbo_vertex_fetch_mode) {
1247 ss_vertex <<
"constant uchar** MTL_VERTEX_DATA;" << std::endl;
1248 ss_vertex <<
"constant ushort* MTL_INDEX_DATA_U16 = nullptr;" << std::endl;
1249 ss_vertex <<
"constant uint32_t* MTL_INDEX_DATA_U32 = nullptr;" << std::endl;
1257 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
1262 ss_vertex << std::endl;
1265 ss_vertex << shd_builder_->glsl_vertex_source_ << std::endl;
1269 if (msl_iface.uses_transform_feedback) {
1270 ss_vertex << msl_iface.generate_msl_vertex_transform_feedback_out_struct(
ShaderStage::VERTEX);
1274 ss_vertex <<
"};" << std::endl;
1277 ss_vertex << msl_iface.generate_msl_vertex_entry_stub();
1280 if (!msl_iface.uses_transform_feedback) {
1283 if (msl_iface.use_argument_buffer_for_samplers()) {
1284 ss_fragment <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
1285 ss_fragment <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
1290 ss_fragment << msl_iface.msl_patch_default_get() << std::endl << std::endl;
1306 ss_fragment <<
"struct " << iface->
name <<
" {" << std::endl;
1307 for (
const StageInterfaceInfo::InOut &inout : iface->
inouts) {
1311 ss_fragment <<
"};" << std::endl;
1318 ss_fragment <<
"public:" << std::endl;
1323 bool is_inside_struct =
false;
1327 is_inside_struct =
true;
1331 for (
const StageInterfaceInfo::InOut &inout : iface->
inouts) {
1334 if (!is_inside_struct) {
1342 if (msl_iface.fragment_tile_inputs.size() > 0) {
1343 ss_fragment << msl_iface.generate_msl_fragment_struct(
true);
1345 ss_fragment << msl_iface.generate_msl_fragment_struct(
false);
1350 ss_fragment <<
"float4 gl_FragCoord;" << std::endl;
1351 if (msl_iface.uses_gl_FragColor) {
1352 ss_fragment <<
"float4 gl_FragColor;" << std::endl;
1354 if (msl_iface.uses_gl_FragDepth) {
1355 ss_fragment <<
"float gl_FragDepth;" << std::endl;
1357 if (msl_iface.uses_gl_FragStencilRefARB) {
1358 ss_fragment <<
"int gl_FragStencilRefARB;" << std::endl;
1360 if (msl_iface.uses_gl_PointCoord) {
1361 ss_fragment <<
"float2 gl_PointCoord;" << std::endl;
1363 if (msl_iface.uses_gl_FrontFacing) {
1364 ss_fragment <<
"bool gl_FrontFacing;" << std::endl;
1366 if (msl_iface.uses_gl_PrimitiveID) {
1367 ss_fragment <<
"uint gl_PrimitiveID;" << std::endl;
1371 if (msl_iface.uses_barycentrics) {
1372 ss_fragment <<
"vec3 gpu_BaryCoord;\n";
1376 if (msl_iface.uses_gpu_layer) {
1377 ss_fragment <<
"int gpu_Layer = 0;" << std::endl;
1379 if (msl_iface.uses_gpu_viewport_index) {
1380 ss_fragment <<
"int gpu_ViewportIndex = 0;" << std::endl;
1384 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
1391 ss_fragment << shd_builder_->glsl_fragment_source_ << std::endl;
1394 ss_fragment <<
"};" << std::endl;
1397 ss_fragment << msl_iface.generate_msl_fragment_entry_stub();
1401#if MTL_SHADER_DEBUG_EXPORT_SOURCE
1402 NSFileManager *sharedFM = [NSFileManager defaultManager];
1403 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
1404 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
1405 URLByAppendingPathComponent:
@"Shaders/"
1407 [sharedFM createDirectoryAtURL:shader_dir
1408 withIntermediateDirectories:YES
1411 const char *path_cstr = [shader_dir fileSystemRepresentation];
1413 std::ofstream vertex_fs;
1415 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedVertexShader.msl")
1417 vertex_fs << ss_vertex.str();
1420 if (!msl_iface.uses_transform_feedback) {
1421 std::ofstream fragment_fs;
1423 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedFragmentShader.msl")
1425 fragment_fs << ss_fragment.str();
1426 fragment_fs.close();
1430 "Vertex Shader Saved to: %s\n",
1431 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedFragmentShader.msl").c_str());
1435 NSString *msl_final_vert = [NSString stringWithUTF8String:ss_vertex.str().c_str()];
1436 NSString *msl_final_frag = (msl_iface.uses_transform_feedback) ?
1438 ([NSString stringWithUTF8String:ss_fragment.str().c_str()]);
1446 [[NSString stringWithFormat:
@"vertex_function_entry_%s", this->
name] retain]);
1448 [[NSString stringWithFormat:
@"fragment_function_entry_%s", this->
name] retain]);
1455 this->
set_interface(msl_iface.bake_shader_interface(this->name, info));
1458 uses_gpu_layer = msl_iface.uses_gpu_layer;
1459 uses_gpu_viewport_index = msl_iface.uses_gpu_viewport_index;
1460 use_ssbo_vertex_fetch_mode_ = msl_iface.uses_ssbo_vertex_fetch_mode;
1461 if (msl_iface.uses_ssbo_vertex_fetch_mode) {
1462 ssbo_vertex_fetch_output_prim_type_ = vertex_fetch_ssbo_output_prim_type;
1463 ssbo_vertex_fetch_output_num_verts_ = vertex_fetch_ssbo_num_output_verts;
1476 MSLGeneratorInterface msl_iface(*
this);
1482 msl_iface.prepare_from_createinfo(info);
1485 BLI_assert(shd_builder_->glsl_compute_source_.size() > 0);
1499 msl_iface.uses_gl_GlobalInvocationID =
1500 bool(info->
builtins_ & BuiltinBits::GLOBAL_INVOCATION_ID) ||
1501 shd_builder_->glsl_compute_source_.find(
"gl_GlobalInvocationID") != std::string::npos;
1503 msl_iface.uses_gl_WorkGroupSize = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_SIZE) ||
1504 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupSize") !=
1507 msl_iface.uses_gl_WorkGroupID = bool(info->
builtins_ & BuiltinBits::WORK_GROUP_ID) ||
1508 shd_builder_->glsl_compute_source_.find(
"gl_WorkGroupID") !=
1511 msl_iface.uses_gl_NumWorkGroups = bool(info->
builtins_ & BuiltinBits::NUM_WORK_GROUP) ||
1512 shd_builder_->glsl_compute_source_.find(
"gl_NumWorkGroups") !=
1515 msl_iface.uses_gl_LocalInvocationIndex =
1516 bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_INDEX) ||
1517 shd_builder_->glsl_compute_source_.find(
"gl_LocalInvocationIndex") != std::string::npos;
1519 msl_iface.uses_gl_LocalInvocationID = bool(info->
builtins_ & BuiltinBits::LOCAL_INVOCATION_ID) ||
1520 shd_builder_->glsl_compute_source_.find(
1521 "gl_LocalInvocationID") != std::string::npos;
1543 std::stringstream ss_compute;
1544 ss_compute <<
"#line 1 \"msl_wrapper_code\"\n";
1546 ss_compute <<
"#define GPU_ARB_shader_draw_parameters 1\n";
1547 if (
bool(info->
builtins_ & BuiltinBits::TEXTURE_ATOMIC) &&
1560 if (msl_iface.use_argument_buffer_for_samplers()) {
1561 ss_compute <<
"#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl;
1562 ss_compute <<
"#define ARGUMENT_BUFFER_NUM_SAMPLERS "
1567 if (msl_iface.uses_gl_WorkGroupSize) {
1571 if (msl_iface.uses_gl_WorkGroupSize) {
1572 ss_compute <<
"#define MTL_USE_WORKGROUP_SIZE 1" << std::endl;
1575 ss_compute <<
"#define MTL_WORKGROUP_SIZE_Y "
1580 ss_compute <<
"#define MTL_WORKGROUP_SIZE_Z "
1588 ss_compute << msl_iface.msl_patch_default_get() << std::endl << std::endl;
1594 ss_compute <<
"public:" << std::endl;
1604 for (
const MSLTextureResource &tex : msl_iface.texture_samplers) {
1609 ss_compute << std::endl;
1612 if (msl_iface.uses_gl_GlobalInvocationID) {
1613 ss_compute <<
"uint3 gl_GlobalInvocationID;" << std::endl;
1615 if (msl_iface.uses_gl_WorkGroupID) {
1616 ss_compute <<
"uint3 gl_WorkGroupID;" << std::endl;
1618 if (msl_iface.uses_gl_NumWorkGroups) {
1619 ss_compute <<
"uint3 gl_NumWorkGroups;" << std::endl;
1621 if (msl_iface.uses_gl_LocalInvocationIndex) {
1622 ss_compute <<
"uint gl_LocalInvocationIndex;" << std::endl;
1624 if (msl_iface.uses_gl_LocalInvocationID) {
1625 ss_compute <<
"uint3 gl_LocalInvocationID;" << std::endl;
1629 ss_compute << shd_builder_->glsl_compute_source_ << std::endl;
1636 if (msl_iface.shared_memory_blocks.size() > 0) {
1637 for (
const MSLSharedMemoryBlock &block : msl_iface.shared_memory_blocks) {
1648 ss_compute << std::endl;
1651 ss_compute <<
") : ";
1653 for (
const MSLSharedMemoryBlock &block : msl_iface.shared_memory_blocks) {
1664 ss_compute <<
"{ }" << std::endl;
1667 ss_compute <<
"};" << std::endl;
1670 ss_compute << msl_iface.generate_msl_compute_entry_stub();
1676 [[NSString stringWithFormat:
@"compute_function_entry_%s", this->
name] retain]);
1682#if MTL_SHADER_DEBUG_EXPORT_SOURCE
1683 NSFileManager *sharedFM = [NSFileManager defaultManager];
1684 NSURL *app_bundle_url = [[NSBundle mainBundle] bundleURL];
1685 NSURL *shader_dir = [[app_bundle_url URLByDeletingLastPathComponent]
1686 URLByAppendingPathComponent:
@"Shaders/"
1688 [sharedFM createDirectoryAtURL:shader_dir
1689 withIntermediateDirectories:YES
1692 const char *path_cstr = [shader_dir fileSystemRepresentation];
1694 std::ofstream compute_fs;
1696 (std::string(path_cstr) +
"/" + std::string(this->
name) +
"_GeneratedComputeShader.msl")
1698 compute_fs << ss_compute.str();
1702 "Compute Shader Saved to: %s\n",
1703 (std::string(path_cstr) + std::string(this->
name) +
"_GeneratedComputeShader.msl").c_str());
1706 NSString *msl_final_compute = [NSString stringWithUTF8String:ss_compute.str().c_str()];
1710 this->
set_interface(msl_iface.bake_shader_interface(this->name, info));
1713 this->compute_pso_common_state_.set_compute_workgroup_size(
1746 inp_uses_indexed_rendering->
location :
1749 inp_uses_index_mode_u16->
location :
1753 "uni_ssbo_input_prim_type_loc uniform location invalid!");
1755 "uni_ssbo_input_vert_count_loc uniform location invalid!");
1757 "uni_ssbo_uses_indexed_rendering uniform location invalid!");
1759 "uni_ssbo_uses_index_mode_u16 uniform location invalid!");
1761 "uni_ssbo_index_base_loc uniform location invalid!");
1771 ShaderSSBOAttributeBinding &cached_ssbo_attr = cached_ssbo_attribute_bindings_[i];
1772 cached_ssbo_attr.attribute_index = i;
1814 cached_ssbo_attr.uniform_stride = (inp_unf_stride !=
nullptr) ? inp_unf_stride->
location : -1;
1815 cached_ssbo_attr.uniform_offset = (inp_unf_offset !=
nullptr) ? inp_unf_offset->
location : -1;
1816 cached_ssbo_attr.uniform_fetchmode = (inp_unf_fetchmode !=
nullptr) ?
1819 cached_ssbo_attr.uniform_vbo_id = (inp_unf_vbo_id !=
nullptr) ? inp_unf_vbo_id->
location : -1;
1820 cached_ssbo_attr.uniform_attr_type = (inp_unf_attr_type !=
nullptr) ?
1824 BLI_assert(cached_ssbo_attr.uniform_offset != -1);
1825 BLI_assert(cached_ssbo_attr.uniform_stride != -1);
1826 BLI_assert(cached_ssbo_attr.uniform_fetchmode != -1);
1827 BLI_assert(cached_ssbo_attr.uniform_vbo_id != -1);
1828 BLI_assert(cached_ssbo_attr.uniform_attr_type != -1);
1835 create_info_ = info;
1847 for (
const auto &constant : create_info_->specialization_constants_) {
1859 int texture_slot_id = 0;
1860 int ubo_buffer_slot_id_ = 0;
1861 int storage_buffer_slot_id_ = 0;
1863 uint max_storage_buffer_location = 0;
1869 int max_sampler_slot = 0;
1870 if (!create_info_->auto_resource_location_) {
1873 max_sampler_slot =
max_ii(res.slot, max_sampler_slot);
1881 switch (res.bind_type) {
1896 msl_tex.
type = res.sampler.type;
1897 msl_tex.
name = res.sampler.name;
1899 msl_tex.
slot = texture_slot_id++;
1900 msl_tex.
location = (create_info_->auto_resource_location_) ? msl_tex.
slot : res.slot;
1924 msl_image.
type = res.image.type;
1925 msl_image.
name = res.image.name;
1926 msl_image.
access = access;
1927 msl_image.
slot = texture_slot_id++;
1928 msl_image.
location = (create_info_->auto_resource_location_) ? msl_image.
slot : res.slot;
1938 BLI_assert(res.uniformbuf.type_name.size() > 0);
1940 int64_t array_offset = res.uniformbuf.name.find_first_of(
"[");
1947 ubo.
slot = 1 + (ubo_buffer_slot_id_++);
1948 ubo.
location = (create_info_->auto_resource_location_) ? ubo.
slot : res.slot;
1953 ubo.
type_name = res.uniformbuf.type_name;
1955 ubo.
is_array = (array_offset > -1);
1959 ubo.
name = name_no_array;
1962 ubo.
name = res.uniformbuf.name;
1970 BLI_assert(res.storagebuf.type_name.size() > 0);
1972 int64_t array_offset = res.storagebuf.name.find_first_of(
"[");
1977 ssbo.
slot = storage_buffer_slot_id_++;
1978 ssbo.
location = (create_info_->auto_resource_location_) ? ssbo.
slot : res.slot;
1980 max_storage_buffer_location =
max_uu(max_storage_buffer_location, ssbo.
location);
1985 ssbo.
type_name = res.storagebuf.type_name;
1987 ssbo.
is_array = (array_offset > -1);
1991 ssbo.
name = name_no_array;
1994 ssbo.
name = res.storagebuf.name;
2005 uint atomic_fallback_buffer_count = 0;
2023 ssbo.
slot = storage_buffer_slot_id_++;
2024 ssbo.
location = max_storage_buffer_location + 1 + atomic_fallback_buffer_count;
2037 ssbo.
name = tex.
name +
"_storagebuf";
2046 atomic_fallback_buffer_count++;
2055 bool all_attr_location_assigned =
true;
2064 bool attr_location_assigned = (attr.
index >= 0);
2065 all_attr_location_assigned = all_attr_location_assigned && attr_location_assigned;
2073 if (!all_attr_location_assigned) {
2099 if (is_tile_based_arch) {
2120 mtl_frag_in.
type = frag_tile_in.
type;
2121 mtl_frag_in.
name = frag_tile_in.
name;
2132 switch (frag_tile_in.
type) {
2150 msl_image.
type = image_type;
2151 msl_image.
name = frag_tile_in.
name +
"_subpass_img";
2153 msl_image.
slot = texture_slot_id++;
2175 (create_info_->tf_names_.size() > 0);
2192 "Compiled Shader '%s' is falling back to bindless via argument buffers due to having a "
2193 "texture sampler of Index: %u Which exceeds the limit of 15+1. However shader only uses "
2194 "%d textures. Consider optimising bind points with .auto_resource_location(true).",
2195 parent_shader_.name_get(),
2201 return use_argument_buffer;
2245 const std::string &uname = attr.name;
2258 std::stringstream out;
2259 out << std::endl <<
"/*** AUTO-GENERATED MSL VERETX SHADER STUB. ***/" << std::endl;
2262 out <<
"#undef texture" << std::endl;
2263 out <<
"#undef textureLod" << std::endl;
2266 out <<
"#undef bool" << std::endl;
2280 out <<
"vertex_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
2282 out <<
"vertex_function_entry(\n\t";
2286 out <<
") {" << std::endl << std::endl;
2293 out << shader_stage_inst_name <<
".gl_VertexID = gl_VertexID;" << std::endl;
2296 out << shader_stage_inst_name <<
".gl_InstanceID = gl_InstanceID-gl_BaseInstanceARB;"
2300 out << shader_stage_inst_name <<
".gl_BaseInstanceARB = gl_BaseInstanceARB;" << std::endl;
2312 out <<
"\t/* Execute Vertex main function */\t" << std::endl
2313 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
2323 out <<
"if(is_function_constant_defined(MTL_global_pointsize)){ output.pointsize = "
2324 "(MTL_global_pointsize > 0.0)?MTL_global_pointsize:output.pointsize; }"
2332 out <<
"\treturn output;" << std::endl;
2342 std::stringstream out;
2343 out << std::endl <<
"/*** AUTO-GENERATED MSL FRAGMENT SHADER STUB. ***/" << std::endl;
2346 out <<
"#undef texture" << std::endl;
2347 out <<
"#undef textureLod" << std::endl;
2350 out <<
"#undef bool" << std::endl;
2357 out <<
"[[early_fragment_tests]]" << std::endl;
2370 out <<
") {" << std::endl << std::endl;
2374 <<
";" << std::endl;
2378 out << shader_stage_inst_name <<
".gl_PointCoord = gl_PointCoord;" << std::endl;
2381 out << shader_stage_inst_name <<
".gl_FrontFacing = gl_FrontFacing;" << std::endl;
2384 out <<
"fragment_shader_instance.gl_PrimitiveID = gl_PrimitiveID;" << std::endl;
2392 out << shader_stage_inst_name <<
".gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl;
2406 out <<
"\t/* Execute Fragment main function */\t" << std::endl
2407 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
2412 out <<
" return output;" << std::endl <<
"}";
2420 std::stringstream out;
2421 out << std::endl <<
"/*** AUTO-GENERATED MSL COMPUTE SHADER STUB. ***/" << std::endl;
2424 out <<
"#undef texture" << std::endl;
2425 out <<
"#undef textureLod" << std::endl;
2428 out <<
"#undef bool" << std::endl;
2434 out <<
"kernel void ";
2436 out <<
"compute_function_entry_" << parent_shader_.name_get() <<
"(\n\t";
2438 out <<
"compute_function_entry(\n\t";
2442 out <<
") {" << std::endl << std::endl;
2445 std::string stage_instance_constructor =
"";
2448 stage_instance_constructor +=
"(";
2456 stage_instance_constructor += ((!first) ?
"," :
"") + block.
varname;
2461 stage_instance_constructor +=
")";
2464 << stage_instance_constructor <<
";" << std::endl;
2469 out << shader_stage_inst_name <<
".gl_GlobalInvocationID = gl_GlobalInvocationID;"
2473 out << shader_stage_inst_name <<
".gl_WorkGroupID = gl_WorkGroupID;" << std::endl;
2476 out << shader_stage_inst_name <<
".gl_NumWorkGroups = gl_NumWorkGroups;" << std::endl;
2479 out << shader_stage_inst_name <<
".gl_LocalInvocationIndex = gl_LocalInvocationIndex;"
2483 out << shader_stage_inst_name <<
".gl_LocalInvocationID = gl_LocalInvocationID;" << std::endl;
2492 out <<
"\t/* Execute Compute main function */\t" << std::endl
2493 <<
"\t" << shader_stage_inst_name <<
".main();" << std::endl
2504 if (is_first_parameter) {
2505 is_first_parameter =
false;
2513 bool &is_first_parameter)
2522 if (
bool(tex.
stage & stage)) {
2524 <<
" [[texture(" << tex.
slot <<
")]]";
2535 <<
"\n\tconstant SStruct& samplers [[buffer(MTL_uniform_buffer_base_index+"
2543 if (
bool(tex.
stage & stage)) {
2545 <<
"_sampler [[sampler(" << tex.
slot <<
")]]";
2550 if (this->texture_samplers.size() > 16) {
2552 "[Metal] Warning: Shader exceeds limit of %u samplers on current hardware\n",
2560 bool &is_first_parameter)
2563 if (
bool(ubo.stage & stage)) {
2573 out << ubo.type_name <<
"* " << ubo.name <<
"[[buffer(MTL_uniform_buffer_base_index+"
2574 << ubo.slot <<
")]]";
2580 if (
bool(ssbo.stage & stage)) {
2583 const char *memory_scope = ((writeable) ?
"device " :
"constant ");
2593 out << ssbo.type_name <<
"* " << ssbo.name <<
"[[buffer(MTL_storage_buffer_base_index+"
2594 << (ssbo.slot) <<
")]]";
2601 std::stringstream out;
2602 bool is_first_parameter =
true;
2607 out <<
parameter_delimiter(is_first_parameter) <<
"\tconstant uchar* MTL_VERTEX_DATA_" << i
2608 <<
" [[buffer(" << i <<
")]]\n";
2611 <<
"\tconstant ushort* MTL_INDEX_DATA[[buffer(MTL_SSBO_VERTEX_FETCH_IBO_INDEX)]]";
2617 is_first_parameter =
false;
2624 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
2625 is_first_parameter =
false;
2634 <<
"::VertexOut_TF* "
2635 "transform_feedback_results[[buffer(MTL_transform_feedback_buffer_index)]]";
2644 <<
"\n\tconst uint32_t gl_VertexID [[vertex_id]]";
2648 <<
"\n\tconst uint32_t gl_InstanceID [[instance_id]]";
2652 <<
"\n\tconst uint32_t gl_BaseInstanceARB [[base_instance]]";
2659 bool is_first_parameter =
true;
2660 std::stringstream out;
2662 <<
"::VertexOut v_in [[stage_in]]";
2667 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
2677 <<
"\n\tconst float2 gl_PointCoord [[point_coord]]";
2681 <<
"\n\tconst bool gl_FrontFacing [[front_facing]]";
2685 <<
"\n\tconst uint gl_PrimitiveID [[primitive_id]]";
2691 <<
"\n\tconst float3 mtl_barycentric_coord [[barycentric_coord]]";
2705 bool is_first_parameter =
true;
2706 std::stringstream out;
2710 <<
"::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]";
2721 <<
"\n\tconst uint3 gl_GlobalInvocationID [[thread_position_in_grid]]";
2725 <<
"\n\tconst uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]";
2729 <<
"\n\tconst uint3 gl_NumWorkGroups [[threadgroups_per_grid]]";
2733 <<
"\n\tconst uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]";
2737 <<
"\n\tconst uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]";
2751 std::stringstream out;
2754 out <<
"typedef struct {" << std::endl;
2757 if (uniform.is_array) {
2758 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
"[" << uniform.array_elems
2759 <<
"];" << std::endl;
2762 out <<
"\t" <<
to_string(uniform.type) <<
" " << uniform.name <<
";" << std::endl;
2765 out <<
"} PushConstantBlock;\n\n";
2768 out << std::endl <<
"const constant PushConstantBlock *global_uniforms;" << std::endl;
2773 for (
const MSLUniform &uniform : this->uniforms) {
2774 out <<
"#define " << uniform.name <<
" global_uniforms->" << uniform.name << std::endl;
2783 std::stringstream out;
2787 out <<
"#undef " << uniform.name << std::endl;
2791 out <<
"#undef " << ubo.name << std::endl;
2795 out <<
"#undef " << ssbo.name << std::endl;
2802 std::stringstream out;
2810 out <<
"typedef struct {" << std::endl;
2823 if (
is_matrix_type(in_attr.type) && !this->uses_ssbo_vertex_fetch_mode) {
2825 out <<
"\t" <<
get_matrix_subtype(in_attr.type) <<
" __internal_" << in_attr.name << elem
2826 <<
" [[attribute(" << (in_attr.layout_location + elem) <<
")]];" << std::endl;
2830 out <<
"\t" << in_attr.type <<
" " << in_attr.name <<
" [[attribute("
2831 << in_attr.layout_location <<
")]];" << std::endl;
2835 out <<
"} VertexIn;" << std::endl << std::endl;
2843 std::stringstream out;
2846 out <<
"typedef struct {" << std::endl;
2852 bool first_attr_is_position =
false;
2858 out <<
"\tfloat4 _default_position_ [[position]]";
2859 out <<
" [[invariant]]";
2860 out <<
";" << std::endl;
2870 out <<
" [[invariant]]";
2871 out <<
";" << std::endl;
2872 first_attr_is_position =
true;
2877 bool skip_first_index = first_attr_is_position;
2881 if (skip_first_index) {
2882 skip_first_index =
false;
2886 if (v_out.is_array) {
2893 for (
int i = 0; i < v_out.array_elems; i++) {
2894 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name << i
2895 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2901 BLI_assert(v_out.get_mtl_interpolation_qualifier() ==
" [[flat]]" &&
2902 "Matrix varying types must have [[flat]] interpolation");
2905 out <<
"\t" << subtype << v_out.instance_name <<
" __matrix_" << v_out.name << elem
2906 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2910 out <<
"\t" << v_out.type <<
" " << v_out.instance_name <<
"_" << v_out.name
2911 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
2923 out <<
"\tfloat pointsize [[point_size]];" << std::endl;
2930 out <<
"\tfloat pointsize [[point_size, function_constant(MTL_global_pointsize)]];"
2937 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl;
2940 out <<
"\tfloat clipdistance [[clip_distance, "
2941 "function_constant(MTL_clip_distances_enabled)]] ["
2945 out <<
"\tfloat clipdistance [[clip_distance, "
2946 "function_constant(MTL_clip_distances_enabled)]];"
2949 out <<
"#endif" << std::endl;
2954 out <<
"\tuint gpu_Layer [[render_target_array_index]];" << std::endl;
2959 out <<
"\tuint gpu_ViewportIndex [[viewport_array_index]];" << std::endl;
2962 out <<
"} VertexOut;" << std::endl << std::endl;
2972 std::stringstream out;
2975 out <<
"typedef struct {" << std::endl;
2980 bool first_attr_is_position =
false;
2983 if (parent_shader_.has_transform_feedback_varying(
"gl_Position")) {
2984 out <<
"\tfloat4 pos [[position]];" << std::endl;
2986 .name =
"gl_Position",
2987 .interpolation_qualifier =
"",
2997 first_attr_is_position =
true;
3002 bool skip_first_index = first_attr_is_position;
3006 if (skip_first_index) {
3007 skip_first_index =
false;
3011 if (!parent_shader_.has_transform_feedback_varying(v_out.name)) {
3016 if (v_out.is_array) {
3018 for (
int i = 0; i < v_out.array_elems; i++) {
3019 out <<
"\t" << v_out.type <<
" " << v_out.name << i
3020 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
3026 BLI_assert(v_out.get_mtl_interpolation_qualifier() ==
" [[flat]]" &&
3027 "Matrix varying types must have [[flat]] interpolation");
3030 out <<
"\t" << subtype <<
" __matrix_" << v_out.name << elem
3031 << v_out.get_mtl_interpolation_qualifier() <<
";" << std::endl;
3035 out <<
"\t" << v_out.type <<
" " << v_out.name << v_out.get_mtl_interpolation_qualifier()
3036 <<
";" << std::endl;
3041 out <<
"} VertexOut_TF;" << std::endl << std::endl;
3048 std::stringstream out;
3053 out <<
"typedef struct {" << std::endl;
3054 for (
int f_output = 0; f_output < fragment_interface_src.size(); f_output++) {
3055 out <<
"\t" <<
to_string(fragment_interface_src[f_output].type) <<
" "
3056 << fragment_interface_src[f_output].name <<
" [[color("
3057 << fragment_interface_src[f_output].layout_location <<
")";
3058 if (fragment_interface_src[f_output].layout_index >= 0) {
3059 out <<
", index(" << fragment_interface_src[f_output].layout_index <<
")";
3061 if (fragment_interface_src[f_output].raster_order_group >= 0) {
3062 out <<
", raster_order_group(" << fragment_interface_src[f_output].raster_order_group <<
")";
3065 <<
";" << std::endl;
3073 out <<
"\tfloat fragdepth [[depth(" << out_depth_argument <<
")]];" << std::endl;
3077 out <<
"\tuint fragstencil [[stencil]];" << std::endl;
3095 std::stringstream out;
3098 out <<
"\t/* Copy Uniform block member reference */" << std::endl;
3100 <<
"global_uniforms = uniforms;" << std::endl;
3107 std::stringstream out;
3113 << tile_input.name <<
" = "
3114 <<
"fragment_tile_in." << tile_input.name <<
";" << std::endl;
3120 char swizzle[] =
"xyzw";
3124 std::string texel_co = (is_layered_fb) ?
3125 "ivec3(ivec2(v_in._default_position_.xy), int(v_in.gpu_Layer))" :
3126 "ivec2(v_in._default_position_.xy)";
3129 << tile_input.name <<
" = texelFetch("
3131 <<
"_subpass_img, " << texel_co <<
", 0)." << swizzle <<
";\n";
3140 std::stringstream out;
3141 out <<
"\t/* Copy UBO block references into local class variables */" << std::endl;
3145 if (
bool(ubo.stage & stage)) {
3152 if (!ubo.is_array) {
3155 out <<
" = " << ubo.name <<
";" << std::endl;
3160 out <<
"\t/* Copy SSBO block references into local class variables */" << std::endl;
3164 if (
bool(ssbo.stage & stage) && !ssbo.is_texture_buffer) {
3171 if (!ssbo.is_array) {
3174 out <<
" = " << ssbo.name <<
";" << std::endl;
3190 std::stringstream out;
3191 out <<
"const constant uchar* GLOBAL_MTL_VERTEX_DATA[MTL_SSBO_VERTEX_FETCH_MAX_VBOS] = {"
3195 out <<
"\t\tMTL_VERTEX_DATA_" << i << delimiter << std::endl;
3197 out <<
"};" << std::endl;
3198 out <<
"\t" << shader_stage_inst_name <<
".MTL_VERTEX_DATA = GLOBAL_MTL_VERTEX_DATA;"
3200 out <<
"\t" << shader_stage_inst_name <<
".MTL_INDEX_DATA_U16 = MTL_INDEX_DATA;" << std::endl;
3201 out <<
"\t" << shader_stage_inst_name
3202 <<
".MTL_INDEX_DATA_U32 = reinterpret_cast<constant "
3203 "uint32_t*>(MTL_INDEX_DATA);"
3209 std::stringstream out;
3210 out <<
"\t/* Copy Vertex Stage-in attributes into local variables */" << std::endl;
3247 bool do_attribute_conversion_on_read =
false;
3251 if (do_attribute_conversion_on_read) {
3253 out <<
"\t" << attribute_conversion_func_name <<
"(MTL_AttributeConvert"
3259 out <<
"\t" << shader_stage_inst_name <<
"."
3273 std::stringstream out;
3274 out <<
"\t/* Copy Vertex Outputs into output struct */" << std::endl;
3278 out <<
"\toutput._default_position_ = " << shader_stage_inst_name <<
".gl_Position;"
3283 out <<
"\toutput._default_position_.y = -output._default_position_.y;" << std::endl;
3284 out <<
"\toutput._default_position_.z = "
3285 "(output._default_position_.z+output._default_position_.w)/2.0;"
3291 out <<
"\toutput.pointsize = " << shader_stage_inst_name <<
".gl_PointSize;" << std::endl;
3296 out <<
"\toutput.gpu_Layer = " << shader_stage_inst_name <<
".gpu_Layer;" << std::endl;
3301 out <<
"\toutput.gpu_ViewportIndex = " << shader_stage_inst_name <<
".gpu_ViewportIndex;"
3309 out <<
"#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl
3310 <<
"if(MTL_clip_distances_enabled) {" << std::endl;
3314 out <<
"\toutput.clipdistance[" << cd
3315 <<
"] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd <<
"))?"
3316 << shader_stage_inst_name <<
".gl_ClipDistance_" << cd <<
":1.0;" << std::endl;
3320 out <<
"\toutput.clipdistance = " << shader_stage_inst_name <<
".gl_ClipDistance_0;"
3323 out <<
"}" << std::endl <<
"#endif" << std::endl;
3328 if (v_out.is_array) {
3330 for (
int i = 0; i < v_out.array_elems; i++) {
3331 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name << i <<
" = "
3332 << shader_stage_inst_name <<
".";
3334 if (v_out.instance_name !=
"") {
3335 out << v_out.instance_name <<
".";
3338 out << v_out.name <<
"[" << i <<
"]"
3339 <<
";" << std::endl;
3346 out <<
"\toutput." << v_out.instance_name <<
"__matrix_" << v_out.name << elem <<
" = "
3347 << shader_stage_inst_name <<
".";
3349 if (v_out.instance_name !=
"") {
3350 out << v_out.instance_name <<
".";
3353 out << v_out.name <<
"[" << elem <<
"];" << std::endl;
3361 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = to_vec4("
3362 << shader_stage_inst_name <<
"." << v_out.name <<
");" << std::endl;
3365 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
".y = -output."
3366 << v_out.name <<
".y;" << std::endl;
3371 out <<
"\toutput." << v_out.instance_name <<
"_" << v_out.name <<
" = "
3372 << shader_stage_inst_name <<
".";
3374 if (v_out.instance_name !=
"") {
3375 out << v_out.instance_name <<
".";
3378 out << v_out.name <<
";" << std::endl;
3392 std::stringstream out;
3393 out <<
"\t/* Copy Vertex TF Outputs into transform feedback buffer */" << std::endl;
3399 out <<
"transform_feedback_results[gl_VertexID]."
3413 std::stringstream out;
3414 out <<
"\t/* Copy Fragment input into local variables. */" << std::endl;
3418 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in._default_position_;"
3423 out <<
"\t" << shader_stage_inst_name <<
".gl_FragCoord = v_in."
3431 out <<
"\t" << shader_stage_inst_name <<
".gl_FragDepth = " << shader_stage_inst_name
3432 <<
".gl_FragCoord.z;" << std::endl;
3437 out <<
"\t" << shader_stage_inst_name <<
".gpu_Layer = v_in.gpu_Layer;" << std::endl;
3442 out <<
"\t" << shader_stage_inst_name <<
".gpu_ViewportIndex = v_in.gpu_ViewportIndex;"
3458 bool exists_in_vertex_output =
false;
3462 exists_in_vertex_output =
true;
3465 if (!exists_in_vertex_output) {
3467 "[Warning] Fragment shader expects varying input '%s', but this is not passed from "
3475 out <<
"\t" << shader_stage_inst_name <<
".";
3489 out <<
"\t" << shader_stage_inst_name <<
".";
3498 for (
int elem = 0; elem <
count; elem++) {
3499 out << ((elem == 0) ?
"(" :
"") <<
"v_in."
3502 << ((elem <
count - 1) ?
",\n" :
"");
3504 out <<
");" << std::endl;
3507 out <<
"\t" << shader_stage_inst_name <<
".";
3529 std::stringstream out;
3530 out <<
"\t/* Copy Fragment Outputs into output struct. */" << std::endl;
3534 out <<
"\toutput.fragdepth = " << shader_stage_inst_name <<
".gl_FragDepth;" << std::endl;
3539 out <<
"\toutput.fragstencil = uint(" << shader_stage_inst_name <<
".gl_FragStencilRefARB);"
3544 for (
int f_output = 0; f_output < this->
fragment_outputs.size(); f_output++) {
3546 out <<
"\toutput." << this->
fragment_outputs[f_output].name <<
" = " << shader_stage_inst_name
3560 std::stringstream out;
3561 out <<
"\t/* Populate local texture and sampler members */" << std::endl;
3568 <<
";" << std::endl;
3579 <<
"_sampler;" << std::endl;
3584 if (tex_buf_id != -1) {
3616 if (attr.layout_location >= 0) {
3619 for (
uint32_t i = 1; i <= location_element_count; i++) {
3621 uint32_t location_mask = (i << attr.layout_location);
3622 BLI_assert((used_locations & location_mask) == 0);
3623 used_locations = used_locations | location_mask;
3630 if (attr.layout_location == -1) {
3640 uint32_t location_mask = (1 << loc);
3646 uint32_t location_slot_mask = (1 << required_attr_slot_count) - 1;
3647 uint32_t sliding_location_slot_mask = location_slot_mask << location_mask;
3648 if ((used_locations & sliding_location_slot_mask) == 0) {
3650 attr.layout_location = loc;
3651 used_locations = used_locations | location_slot_mask;
3657 MTL_LOG_ERROR(
"Could not assign attribute location to attribute %s for shader %s",
3659 this->parent_shader_.name_get());
3666 int running_location_ind = 0;
3672 ((running_location_ind > 0) ? (this->
fragment_outputs[i].layout_location == -1) :
true),
3673 "Error: Mismatched input attributes, some with location specified, some without");
3676 running_location_ind++;
3686 const char *str_to_copy,
3694 uint32_t ret_len = strlen(str_to_copy);
3698 if (name_buffer_offset + ret_len + 1 > name_buffer_size) {
3699 name_buffer_size = name_buffer_offset +
max_ii(128, ret_len + 1);
3700 *name_buffer_ptr = (
char *)
MEM_reallocN(*name_buffer_ptr, name_buffer_size);
3704 uint32_t insert_offset = name_buffer_offset;
3705 char *current_offset = (*name_buffer_ptr) + insert_offset;
3706 memcpy(current_offset, str_to_copy, (ret_len + 1) *
sizeof(
char));
3709 name_buffer_offset += ret_len + 1;
3712 return insert_offset;
3744 std::string _internal_name = (elem == 0) ?
3748 std::to_string(elem);
3756 _internal_name.c_str(),
3758 name_buffer_offset),
3759 this->vertex_input_attributes[
attribute].layout_location + elem,
3771 "[Note] Matrix Type '%s' added to shader interface as vertex attribute. (Elem Count: "
3783 this->vertex_input_attributes[
attribute].name.c_str(),
3785 name_buffer_offset),
3786 this->vertex_input_attributes[
attribute].layout_location,
3801 &
interface->name_buffer_,
"PushConstantBlock", name_buffer_size, name_buffer_offset));
3803 for (
int uniform = 0; uniform < this->
uniforms.size(); uniform++) {
3806 this->uniforms[uniform].name.c_str(),
3808 name_buffer_offset),
3810 (this->
uniforms[uniform].is_array) ? this->
uniforms[uniform].array_elems : 1);
3814 for (
int uniform_block = 0; uniform_block < this->
uniform_blocks.size(); uniform_block++) {
3817 this->uniform_blocks[uniform_block].name.c_str(),
3819 name_buffer_offset),
3820 this->uniform_blocks[uniform_block].slot,
3821 this->uniform_blocks[uniform_block].location,
3823 this->uniform_blocks[uniform_block].stage);
3827 for (
int storage_block = 0; storage_block < this->
storage_blocks.size(); storage_block++) {
3830 this->storage_blocks[storage_block].name.c_str(),
3832 name_buffer_offset),
3833 this->storage_blocks[storage_block].slot,
3834 this->storage_blocks[storage_block].location,
3836 this->storage_blocks[storage_block].stage);
3842 uint tex_buf_ssbo_location = -1;
3843 uint tex_buf_ssbo_id = input_texture.atomic_fallback_buffer_ssbo_id;
3844 if (tex_buf_ssbo_id != -1) {
3845 tex_buf_ssbo_location = this->
storage_blocks[tex_buf_ssbo_id].location;
3849 input_texture.name.c_str(),
3851 name_buffer_offset),
3853 input_texture.location,
3854 input_texture.get_texture_binding_type(),
3855 input_texture.get_sampler_format(),
3856 input_texture.is_texture_sampler,
3857 input_texture.stage,
3858 tex_buf_ssbo_location);
3864 &
interface->name_buffer_, constant.name.c_str(), name_buffer_size, name_buffer_offset));
3875 interface->prepare_common_shader_inputs(info);
3878 if (name_buffer_offset < name_buffer_size) {
3889 switch (this->
type) {
3900 return "texturecube";
3903 return "texture1d_array";
3906 return "texture2d_array";
3909 return "texturecube_array";
3912 return "texture_buffer";
3921 return "depth2d_array";
3924 return "depth2d_array";
3933 return "depthcube_array";
3936 return "depthcube_array";
3948 return "texturecube";
3951 return "texture1d_array";
3954 return "texture2d_array";
3957 return "texturecube_array";
3960 return "texture_buffer";
3972 return "texturecube";
3975 return "texture1d_array";
3978 return "texture2d_array";
3981 return "texturecube_array";
3984 return "texture_buffer";
3994 if (supports_native_atomics) {
3995 return "texture2d_array";
4003 if (supports_native_atomics) {
4023 switch (this->
type) {
4025 return "_mtl_combined_image_sampler_1d";
4028 return "_mtl_combined_image_sampler_2d";
4031 return "_mtl_combined_image_sampler_3d";
4034 return "_mtl_combined_image_sampler_cube";
4037 return "_mtl_combined_image_sampler_1d_array";
4040 return "_mtl_combined_image_sampler_2d_array";
4043 return "_mtl_combined_image_sampler_cube_array";
4046 return "_mtl_combined_image_sampler_buffer";
4049 return "_mtl_combined_image_sampler_depth_2d";
4052 return "_mtl_combined_image_sampler_depth_2d";
4055 return "_mtl_combined_image_sampler_depth_2d_array";
4058 return "_mtl_combined_image_sampler_depth_2d_array";
4061 return "_mtl_combined_image_sampler_depth_cube";
4064 return "_mtl_combined_image_sampler_depth_cube";
4067 return "_mtl_combined_image_sampler_depth_cube_array";
4070 return "_mtl_combined_image_sampler_depth_cube_array";
4073 return "_mtl_combined_image_sampler_1d";
4076 return "_mtl_combined_image_sampler_2d";
4079 return "_mtl_combined_image_sampler_3d";
4082 return "_mtl_combined_image_sampler_cube";
4085 return "_mtl_combined_image_sampler_1d_array";
4088 return "_mtl_combined_image_sampler_2d_array";
4091 return "_mtl_combined_image_sampler_cube_array";
4094 return "_mtl_combined_image_sampler_buffer";
4097 return "_mtl_combined_image_sampler_1d";
4100 return "_mtl_combined_image_sampler_2d";
4103 return "_mtl_combined_image_sampler_3d";
4106 return "_mtl_combined_image_sampler_cube";
4109 return "_mtl_combined_image_sampler_1d_array";
4112 return "_mtl_combined_image_sampler_2d_array";
4115 return "_mtl_combined_image_sampler_cube_array";
4118 return "_mtl_combined_image_sampler_buffer";
4124 if (supports_native_atomics) {
4125 return "_mtl_combined_image_sampler_2d";
4128 return "_mtl_combined_image_sampler_2d_atomic_fallback";
4133 if (supports_native_atomics) {
4134 return "_mtl_combined_image_sampler_3d";
4137 return "_mtl_combined_image_sampler_3d_atomic_fallback";
4142 if (supports_native_atomics) {
4143 return "_mtl_combined_image_sampler_2d_array";
4146 return "_mtl_combined_image_sampler_2d_array_atomic_fallback";
4160 switch (this->
type) {
4221 switch (this->
type) {
4333 switch (this->
type) {
#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)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define ARRAY_SET_ITEMS(...)
#define UNUSED_VARS_NDEBUG(...)
int GPU_max_textures_vert()
#define MEM_reallocN(vmemh, len)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
vertex_source("basic_depth_pointcloud_vert.glsl") .additional_info("draw_pointcloud")
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr bool is_empty() const
constexpr int64_t size() 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
void prepare_ssbo_vertex_fetch_uniforms()
bool uses_gpu_viewport_index
blender::Vector< MSLBufferBlock > storage_blocks
std::string generate_msl_vertex_output_population()
shader::DepthWrite depth_write
bool uses_transform_feedback
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
std::string generate_msl_vertex_transform_feedback_out_struct(ShaderStage shader_stage)
blender::Vector< MSLVertexOutputAttribute > fragment_input_varyings
bool uses_ssbo_vertex_fetch_mode
std::string generate_msl_fragment_input_population()
blender::Vector< MSLVertexOutputAttribute > vertex_output_varyings
uint32_t get_sampler_argument_buffer_bind_index(ShaderStage stage)
std::string generate_msl_vertex_output_tf_population()
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
blender::Vector< MSLVertexOutputAttribute > vertex_output_varyings_tf
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()
blender::Vector< MSLSharedMemoryBlock > shared_memory_blocks
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()
bool supports_native_tile_inputs
static MTLCapabilities & get_capabilities()
uint32_t get_total_attributes() const
const char * get_name_at_offset(uint32_t offset) const
const MTLShaderInputAttribute & get_attribute(uint index) const
void set_fragment_function_name(NSString *fragment_function_name)
int uni_ssbo_input_prim_type_loc
std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override
void shader_compute_source_from_msl(NSString *input_compute_source)
int uni_ssbo_index_base_loc
int uni_ssbo_uses_index_mode_u16
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override
int uni_ssbo_input_vert_count_loc
int uni_ssbo_uses_indexed_rendering
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)
MTLShaderInterface * get_interface()
void prepare_ssbo_vertex_fetch_metadata()
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)
const ShaderInput * uniform_get(const char *name) const
ShaderInterface * interface
const char *const name_get() const
output_img push_constant(Type::FLOAT, "subtrahend") .define("TYPE"
void *(* MEM_mallocN)(size_t len, const char *str)
static void error(const char *str)
static void clear(Message &msg)
#define MTL_MAX_BUFFER_BINDINGS
#define MTL_MAX_TEXTURE_SLOTS
#define MTL_MAX_DEFAULT_SAMPLERS
#define MTL_LOG_INFO(info,...)
#define MTL_LOG_WARNING(info,...)
#define MTL_LOG_ERROR(info,...)
#define shader_debug_printf(...)
#define MTL_SHADER_SPECIALIZATION_CONSTANT_BASE_ID
#define UNIFORM_SSBO_VBO_ID_STR
#define UNIFORM_SSBO_OFFSET_STR
#define UNIFORM_SSBO_INPUT_VERT_COUNT_STR
#define UNIFORM_SSBO_INPUT_PRIM_TYPE_STR
#define UNIFORM_SSBO_STRIDE_STR
#define UNIFORM_SSBO_USES_INDEXED_RENDERING_STR
#define UNIFORM_SSBO_INDEX_MODE_U16_STR
#define UNIFORM_SSBO_FETCHMODE_STR
#define UNIFORM_SSBO_TYPE_STR
#define UNIFORM_SSBO_INDEX_BASE_STR
#define FRAGMENT_TILE_IN_STRUCT_NAME
char datatoc_mtl_shader_defines_msl[]
#define ATOMIC_DEFINE_STR
#define FRAGMENT_OUT_STRUCT_NAME
char datatoc_mtl_shader_shared_h[]
@ MTL_DATATYPE_INT1010102_NORM
uint mtl_get_data_type_size(eMTLDataType type)
#define MTL_SSBO_VERTEX_FETCH_MAX_VBOS
BLI_INLINE int to_component_count(const Type &type)
@ TEXTURE_ACCESS_READWRITE
static void replace_array_initializers_func(std::string &str)
uint get_shader_stage_index(ShaderStage stage)
char * next_word_in_range(char *begin, char *end)
const char * to_string(ShaderStage stage)
bool is_matrix_type(const std::string &type)
static void replace_matrix_constructors(std::string &str)
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 bool is_program_word(const char *chr, int *len)
static void extract_and_replace_clipping_distances(std::string &vertex_source, MSLGeneratorInterface &msl_iface)
static void remove_multiline_comments_func(std::string &str)
static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res)
const char * get_shader_stage_instance_name(ShaderStage stage)
static bool extract_ssbo_pragma_info(const MTLShader *shader, const MSLGeneratorInterface &, const std::string &in_vertex_src, MTLPrimitiveType &out_prim_tye, uint32_t &out_num_output_verts)
static void replace_outvars(std::string &str)
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)
static void extract_global_scope_constants(std::string &str, std::stringstream &)
std::string get_matrix_subtype(const std::string &type)
static int backwards_program_word_scan(const char *array_loc, const char *min)
static void remove_singleline_comments_func(std::string &str)
std::string get_attribute_conversion_function(bool *uses_conversion, const shader::Type &type)
bool is_builtin_type(std::string type)
char * next_symbol_in_range(char *begin, char *end, char symbol)
static bool balanced_braces(char *current_str_begin, char *current_str_end)
static void generate_specialization_constant_declarations(const shader::ShaderCreateInfo *info, std::stringstream &ss)
void extract_shared_memory_blocks(MSLGeneratorInterface &msl_iface, std::string &glsl_compute_source)
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_
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< 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