Skip to content

Commit 38681a3

Browse files
MSL: add gl_DrawID (DrawIndex) support for MacOS (#2634)
* MSL: add gl_DrawID (DrawIndex) support for MacOS * Updated tests to include gl_DrawID for MSL * Added recommended changes to include DrawID with tessellation. Removed msl version and device checks, since the feature is emulated. Updated corresponding tests. * MSL: Fixups for DrawID implementation from review. --------- Co-authored-by: Hans-Kristian Arntzen <post@arntzen-software.no>
1 parent 39e6a39 commit 38681a3

8 files changed

Lines changed: 48 additions & 17 deletions

File tree

reference/opt/shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.for-tess.vert

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ struct main0_out
88
float4 gl_Position;
99
};
1010

11-
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 spvStageInputSize [[grid_size]], uint3 spvDispatchBase [[grid_origin]], device main0_out* spvOut [[buffer(28)]])
11+
kernel void main0(constant uint* spvDrawIndex [[buffer(19)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 spvStageInputSize [[grid_size]], uint3 spvDispatchBase [[grid_origin]], device main0_out* spvOut [[buffer(28)]])
1212
{
1313
device main0_out& out = spvOut[gl_GlobalInvocationID.y * spvStageInputSize.x + gl_GlobalInvocationID.x];
1414
if (any(gl_GlobalInvocationID >= spvStageInputSize))
1515
return;
1616
uint gl_BaseVertex = spvDispatchBase.x;
1717
uint gl_BaseInstance = spvDispatchBase.y;
18-
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), 0.0, 1.0);
18+
uint gl_DrawID = *spvDrawIndex;
19+
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), float(int(gl_DrawID)), 1.0);
1920
}
2021

reference/opt/shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.vert

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ struct main0_out
88
float4 gl_Position [[position]];
99
};
1010

11-
vertex main0_out main0(uint gl_BaseVertex [[base_vertex]], uint gl_BaseInstance [[base_instance]])
11+
vertex main0_out main0(constant uint* spvDrawIndex [[buffer(19)]], uint gl_BaseVertex [[base_vertex]], uint gl_BaseInstance [[base_instance]])
1212
{
1313
main0_out out = {};
14-
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), 0.0, 1.0);
14+
uint gl_DrawID = *spvDrawIndex;
15+
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), float(int(gl_DrawID)), 1.0);
1516
return out;
1617
}
1718

reference/shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.for-tess.vert

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ struct main0_out
88
float4 gl_Position;
99
};
1010

11-
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 spvStageInputSize [[grid_size]], uint3 spvDispatchBase [[grid_origin]], device main0_out* spvOut [[buffer(28)]])
11+
kernel void main0(constant uint* spvDrawIndex [[buffer(19)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 spvStageInputSize [[grid_size]], uint3 spvDispatchBase [[grid_origin]], device main0_out* spvOut [[buffer(28)]])
1212
{
1313
device main0_out& out = spvOut[gl_GlobalInvocationID.y * spvStageInputSize.x + gl_GlobalInvocationID.x];
1414
if (any(gl_GlobalInvocationID >= spvStageInputSize))
1515
return;
1616
uint gl_BaseVertex = spvDispatchBase.x;
1717
uint gl_BaseInstance = spvDispatchBase.y;
18-
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), 0.0, 1.0);
18+
uint gl_DrawID = *spvDrawIndex;
19+
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), float(int(gl_DrawID)), 1.0);
1920
}
2021

reference/shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.vert

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ struct main0_out
88
float4 gl_Position [[position]];
99
};
1010

11-
vertex main0_out main0(uint gl_BaseVertex [[base_vertex]], uint gl_BaseInstance [[base_instance]])
11+
vertex main0_out main0(constant uint* spvDrawIndex [[buffer(19)]], uint gl_BaseVertex [[base_vertex]], uint gl_BaseInstance [[base_instance]])
1212
{
1313
main0_out out = {};
14-
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), 0.0, 1.0);
14+
uint gl_DrawID = *spvDrawIndex;
15+
out.gl_Position = float4(float(int(gl_BaseVertex)), float(int(gl_BaseInstance)), float(int(gl_DrawID)), 1.0);
1516
return out;
1617
}
1718

shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.for-tess.vert

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ out gl_PerVertex
77

88
void main()
99
{
10-
gl_Position = vec4(gl_BaseVertex, gl_BaseInstance, 0, 1);
10+
gl_Position = vec4(gl_BaseVertex, gl_BaseInstance, gl_DrawID, 1);
1111
}

shaders-msl/desktop-only/vert/shader-draw-parameters.desktop.vert

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ out gl_PerVertex
55
vec4 gl_Position;
66
};
77

8+
void in_func()
9+
{
10+
gl_Position.w = float(gl_DrawID);
11+
}
12+
813
void main()
914
{
10-
gl_Position = vec4(gl_BaseVertex, gl_BaseInstance, 0, 1);
15+
gl_Position = vec4(gl_BaseVertex, gl_BaseInstance, gl_DrawID, 1);
1116
}

spirv_msl.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,18 @@ void CompilerMSL::build_implicit_builtins()
10871087
dynamic_offsets_buffer_id = var_id;
10881088
}
10891089

1090+
if (active_input_builtins.get(BuiltInDrawIndex))
1091+
{
1092+
// This is always emulated.
1093+
uint32_t var_id = build_constant_uint_array_pointer();
1094+
set_name(var_id, "spvDrawIndex");
1095+
// This should never match anything.
1096+
set_decoration(var_id, DecorationDescriptorSet, ~(6u));
1097+
set_decoration(var_id, DecorationBinding, msl_options.draw_id_buffer_index);
1098+
set_extended_decoration(var_id, SPIRVCrossDecorationResourceIndexPrimary, msl_options.draw_id_buffer_index);
1099+
draw_index_buffer_id = var_id;
1100+
}
1101+
10901102
// If we're returning a struct from a vertex-like entry point, we must return a position attribute.
10911103
bool need_position = (get_execution_model() == ExecutionModelVertex || is_tese_shader()) &&
10921104
!capture_output_to_buffer && !get_is_rasterization_disabled() &&
@@ -1766,6 +1778,8 @@ string CompilerMSL::compile()
17661778
add_active_interface_variable(view_mask_buffer_id);
17671779
if (dynamic_offsets_buffer_id)
17681780
add_active_interface_variable(dynamic_offsets_buffer_id);
1781+
if (draw_index_buffer_id)
1782+
add_active_interface_variable(draw_index_buffer_id);
17691783
if (builtin_layer_id)
17701784
add_active_interface_variable(builtin_layer_id);
17711785
if (builtin_dispatch_base_id && !msl_options.supports_msl_version(1, 2))
@@ -13820,9 +13834,6 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
1382013834
return "";
1382113835
return string(" [[") + builtin_qualifier(builtin) + "]]";
1382213836

13823-
case BuiltInDrawIndex:
13824-
SPIRV_CROSS_THROW("DrawIndex is not supported in MSL.");
13825-
1382613837
default:
1382713838
return "";
1382813839
}
@@ -14671,6 +14682,9 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type)
1467114682
/* fallthrough */
1467214683
case BuiltInSubgroupLocalInvocationId:
1467314684
return !msl_options.emulate_subgroups;
14685+
case BuiltInDrawIndex:
14686+
// Emulated
14687+
return false;
1467414688
default:
1467514689
return true;
1467614690
}
@@ -15969,6 +15983,12 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
1596915983
to_expression(builtin_dispatch_base_id), ".y;");
1597015984
});
1597115985
break;
15986+
case BuiltInDrawIndex:
15987+
entry_func.fixup_hooks_in.push_back([=]() {
15988+
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = *",
15989+
to_expression(draw_index_buffer_id), ";");
15990+
});
15991+
break;
1597215992
default:
1597315993
break;
1597415994
}
@@ -18119,8 +18139,9 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
1811918139
{
1812018140
SPIRV_CROSS_THROW("BaseInstance requires Metal 1.1 and Mac or Apple A9+ hardware.");
1812118141
}
18142+
1812218143
case BuiltInDrawIndex:
18123-
SPIRV_CROSS_THROW("DrawIndex is not supported in MSL.");
18144+
return "gl_DrawID";
1812418145

1812518146
// When used in the entry function, output builtins are qualified with output struct name.
1812618147
// Test storage class as NOT Input, as output builtins might be part of generic type.
@@ -18231,8 +18252,6 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
1823118252
return "instance_id";
1823218253
case BuiltInBaseInstance:
1823318254
return "base_instance";
18234-
case BuiltInDrawIndex:
18235-
SPIRV_CROSS_THROW("DrawIndex is not supported in MSL.");
1823618255

1823718256
// Vertex function out
1823818257
case BuiltInClipDistance:
@@ -18456,7 +18475,7 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id)
1845618475
case BuiltInBaseInstance:
1845718476
return "uint";
1845818477
case BuiltInDrawIndex:
18459-
SPIRV_CROSS_THROW("DrawIndex is not supported in MSL.");
18478+
return "uint";
1846018479

1846118480
// Vertex function out
1846218481
case BuiltInClipDistance:
@@ -19670,6 +19689,7 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
1967019689
case BuiltInSubgroupSize:
1967119690
case BuiltInSubgroupLocalInvocationId:
1967219691
case BuiltInViewIndex:
19692+
case BuiltInDrawIndex:
1967319693
case BuiltInVertexIndex:
1967419694
case BuiltInInstanceIndex:
1967519695
case BuiltInBaseInstance:

spirv_msl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ class CompilerMSL : public CompilerGLSL
317317
uint32_t shader_input_buffer_index = 22;
318318
uint32_t shader_index_buffer_index = 21;
319319
uint32_t shader_patch_input_buffer_index = 20;
320+
uint32_t draw_id_buffer_index = 19;
320321
uint32_t shader_input_wg_index = 0;
321322
uint32_t device_index = 0;
322323
uint32_t enable_frag_output_mask = 0xffffffff;
@@ -1180,6 +1181,7 @@ class CompilerMSL : public CompilerGLSL
11801181
uint32_t swizzle_buffer_id = 0;
11811182
uint32_t buffer_size_buffer_id = 0;
11821183
uint32_t view_mask_buffer_id = 0;
1184+
uint32_t draw_index_buffer_id = 0;
11831185
uint32_t dynamic_offsets_buffer_id = 0;
11841186
uint32_t uint_type_id = 0;
11851187
uint32_t shared_uint_type_id = 0;

0 commit comments

Comments
 (0)