diff --git a/reference/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert b/reference/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..d8804504 --- /dev/null +++ b/reference/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,25 @@ +static float4 gl_Position; +static int gl_BaseInstanceARB; +struct SPIRV_Cross_Input +{ + uint gl_BaseInstanceARB : SV_StartInstanceLocation; +}; + +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = float(gl_BaseInstanceARB).xxxx; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + gl_BaseInstanceARB = stage_input.gl_BaseInstanceARB; + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/reference/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert b/reference/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..a75b8e8e --- /dev/null +++ b/reference/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,25 @@ +static float4 gl_Position; +static int gl_BaseVertexARB; +struct SPIRV_Cross_Input +{ + uint gl_BaseVertexARB : SV_StartVertexLocation; +}; + +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = float(gl_BaseVertexARB).xxxx; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + gl_BaseVertexARB = stage_input.gl_BaseVertexARB; + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/reference/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert b/reference/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..dd575033 --- /dev/null +++ b/reference/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,28 @@ +static float4 gl_Position; +static int gl_InstanceIndex; +static int gl_BaseInstanceARB; +struct SPIRV_Cross_Input +{ + uint gl_InstanceIndex : SV_InstanceID; + uint gl_BaseInstanceARB : SV_StartInstanceLocation; +}; + +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = float(gl_InstanceIndex).xxxx; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + gl_InstanceIndex = int(stage_input.gl_InstanceIndex + stage_input.gl_BaseInstanceARB); + gl_BaseInstanceARB = stage_input.gl_BaseInstanceARB; + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/reference/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert b/reference/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..c0ace4d8 --- /dev/null +++ b/reference/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,28 @@ +static float4 gl_Position; +static int gl_VertexIndex; +static int gl_BaseVertexARB; +struct SPIRV_Cross_Input +{ + uint gl_VertexIndex : SV_VertexID; + uint gl_BaseVertexARB : SV_StartVertexLocation; +}; + +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = float(gl_VertexIndex).xxxx; +} + +SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) +{ + gl_VertexIndex = int(stage_input.gl_VertexIndex + stage_input.gl_BaseVertexARB); + gl_BaseVertexARB = stage_input.gl_BaseVertexARB; + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert b/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..20b686cf --- /dev/null +++ b/shaders-hlsl-no-opt/vert/base-instance-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,7 @@ +#version 450 +#extension GL_ARB_shader_draw_parameters : require + +void main() +{ + gl_Position = vec4(gl_BaseInstanceARB); +} diff --git a/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert b/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..ef486c85 --- /dev/null +++ b/shaders-hlsl-no-opt/vert/base-vertex-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,7 @@ +#version 450 +#extension GL_ARB_shader_draw_parameters : require + +void main() +{ + gl_Position = vec4(gl_BaseVertexARB); +} diff --git a/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert b/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..64568137 --- /dev/null +++ b/shaders-hlsl-no-opt/vert/instance-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,6 @@ +#version 450 + +void main() +{ + gl_Position = vec4(gl_InstanceIndex); +} diff --git a/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert b/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert new file mode 100644 index 00000000..8cd94ddf --- /dev/null +++ b/shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert @@ -0,0 +1,6 @@ +#version 450 + +void main() +{ + gl_Position = vec4(gl_VertexIndex); +} diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index ac1d262a..46fc1768 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -849,11 +849,25 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() case BuiltInSubgroupLeMask: case BuiltInSubgroupGtMask: case BuiltInSubgroupGeMask: - case BuiltInBaseVertex: - case BuiltInBaseInstance: // Handled specially. break; + case BuiltInBaseVertex: + if (hlsl_options.shader_model >= 68) + { + type = "uint"; + semantic = "SV_StartVertexLocation"; + } + break; + + case BuiltInBaseInstance: + if (hlsl_options.shader_model >= 68) + { + type = "uint"; + semantic = "SV_StartInstanceLocation"; + } + break; + case BuiltInHelperInvocation: if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment) SPIRV_CROSS_THROW("Helper Invocation input is only supported in PS 5.0 or higher."); @@ -1231,7 +1245,7 @@ void CompilerHLSL::emit_builtin_variables() case BuiltInVertexIndex: case BuiltInInstanceIndex: type = "int"; - if (hlsl_options.support_nonzero_base_vertex_base_instance) + if (hlsl_options.support_nonzero_base_vertex_base_instance || hlsl_options.shader_model >= 68) base_vertex_info.used = true; break; @@ -1353,7 +1367,7 @@ void CompilerHLSL::emit_builtin_variables() } }); - if (base_vertex_info.used) + if (base_vertex_info.used && hlsl_options.shader_model < 68) { string binding_info; if (base_vertex_info.explicit_binding) @@ -3136,23 +3150,39 @@ void CompilerHLSL::emit_hlsl_entry_point() case BuiltInVertexIndex: case BuiltInInstanceIndex: // D3D semantics are uint, but shader wants int. - if (hlsl_options.support_nonzero_base_vertex_base_instance) + if (hlsl_options.support_nonzero_base_vertex_base_instance || hlsl_options.shader_model >= 68) { - if (static_cast(i) == BuiltInInstanceIndex) - statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseInstance;"); + if (hlsl_options.shader_model >= 68) + { + if (static_cast(i) == BuiltInInstanceIndex) + statement(builtin, " = int(stage_input.", builtin, " + stage_input.gl_BaseInstanceARB);"); + else + statement(builtin, " = int(stage_input.", builtin, " + stage_input.gl_BaseVertexARB);"); + } else - statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseVertex;"); + { + if (static_cast(i) == BuiltInInstanceIndex) + statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseInstance;"); + else + statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseVertex;"); + } } else statement(builtin, " = int(stage_input.", builtin, ");"); break; case BuiltInBaseVertex: - statement(builtin, " = SPIRV_Cross_BaseVertex;"); + if (hlsl_options.shader_model >= 68) + statement(builtin, " = stage_input.gl_BaseVertexARB;"); + else + statement(builtin, " = SPIRV_Cross_BaseVertex;"); break; case BuiltInBaseInstance: - statement(builtin, " = SPIRV_Cross_BaseInstance;"); + if (hlsl_options.shader_model >= 68) + statement(builtin, " = stage_input.gl_BaseInstanceARB;"); + else + statement(builtin, " = SPIRV_Cross_BaseInstance;"); break; case BuiltInInstanceId: @@ -6714,6 +6744,15 @@ string CompilerHLSL::compile() if (need_subpass_input) active_input_builtins.set(BuiltInFragCoord); + // Need to offset by BaseVertex/BaseInstance in SM 6.8+. + if (hlsl_options.shader_model >= 68) + { + if (active_input_builtins.get(BuiltInVertexIndex)) + active_input_builtins.set(BuiltInBaseVertex); + if (active_input_builtins.get(BuiltInInstanceIndex)) + active_input_builtins.set(BuiltInBaseInstance); + } + uint32_t pass_count = 0; do { diff --git a/test_shaders.py b/test_shaders.py index 481a2d15..58c9d7d9 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -494,6 +494,8 @@ def shader_to_sm(shader): return '62' elif '.sm60.' in shader: return '60' + elif '.sm68.' in shader: + return '68' elif '.sm51.' in shader: return '51' elif '.sm30.' in shader: