Skip to content

Commit

Permalink
HLSL: Implement SM 6.8 BaseVertex/BaseInstance.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Jul 15, 2024
1 parent d17a2d6 commit 1de3f8c
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version 450
#extension GL_ARB_shader_draw_parameters : require

void main()
{
gl_Position = vec4(gl_BaseInstanceARB);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version 450
#extension GL_ARB_shader_draw_parameters : require

void main()
{
gl_Position = vec4(gl_BaseVertexARB);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#version 450

void main()
{
gl_Position = vec4(gl_InstanceIndex);
}
6 changes: 6 additions & 0 deletions shaders-hlsl-no-opt/vert/vertex-index.sm68.nofxc.fxconly.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#version 450

void main()
{
gl_Position = vec4(gl_VertexIndex);
}
57 changes: 48 additions & 9 deletions spirv_hlsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,9 +849,23 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
case BuiltInSubgroupLeMask:
case BuiltInSubgroupGtMask:
case BuiltInSubgroupGeMask:
// Handled specially.
break;

case BuiltInBaseVertex:
if (hlsl_options.shader_model >= 68)
{
type = "uint";
semantic = "SV_StartVertexLocation";
}
break;

case BuiltInBaseInstance:
// Handled specially.
if (hlsl_options.shader_model >= 68)
{
type = "uint";
semantic = "SV_StartInstanceLocation";
}
break;

case BuiltInHelperInvocation:
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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<BuiltIn>(i) == BuiltInInstanceIndex)
statement(builtin, " = int(stage_input.", builtin, ") + SPIRV_Cross_BaseInstance;");
if (hlsl_options.shader_model >= 68)
{
if (static_cast<BuiltIn>(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<BuiltIn>(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:
Expand Down Expand Up @@ -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
{
Expand Down
2 changes: 2 additions & 0 deletions test_shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 1de3f8c

Please sign in to comment.