mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-09 22:00:05 +00:00
HLSL: Improve support for VertexInfo aux struct.
Add concept of explicit bindings for aux structs and allows query if these aux structs are required.
This commit is contained in:
parent
c821207ae2
commit
b5386e3ea9
17
main.cpp
17
main.cpp
@ -709,7 +709,12 @@ struct CLIArguments
|
||||
bool msl = false;
|
||||
bool hlsl = false;
|
||||
bool hlsl_compat = false;
|
||||
|
||||
bool hlsl_support_nonzero_base = false;
|
||||
bool hlsl_base_vertex_index_explicit_binding = false;
|
||||
uint32_t hlsl_base_vertex_index_register_index = 0;
|
||||
uint32_t hlsl_base_vertex_index_register_space = 0;
|
||||
|
||||
bool hlsl_force_storage_buffer_as_uav = false;
|
||||
bool hlsl_nonwritable_uav_texture_as_srv = false;
|
||||
bool hlsl_enable_16bit_types = false;
|
||||
@ -806,6 +811,7 @@ static void print_help_hlsl()
|
||||
"\t\tPointSize is ignored, and PointCoord returns (0.5, 0.5).\n"
|
||||
"\t[--hlsl-support-nonzero-basevertex-baseinstance]:\n\t\tSupport base vertex and base instance by emitting a special cbuffer declared as:\n"
|
||||
"\t\tcbuffer SPIRV_Cross_VertexInfo { int SPIRV_Cross_BaseVertex; int SPIRV_Cross_BaseInstance; };\n"
|
||||
"\t[--hlsl-basevertex-baseinstance-binding <register index> <register space>]:\n\t\tAssign a fixed binding to SPIRV_Cross_VertexInfo.\n"
|
||||
"\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
|
||||
"\t\tDo not emit any : register(#) bindings for specific resource types, and rely on HLSL compiler to assign something.\n"
|
||||
"\t[--hlsl-force-storage-buffer-as-uav]:\n\t\tAlways emit SSBOs as UAVs, even when marked as read-only.\n"
|
||||
@ -1370,6 +1376,12 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
hlsl_opts.flatten_matrix_vertex_input_semantics = args.hlsl_flatten_matrix_vertex_input_semantics;
|
||||
hlsl->set_hlsl_options(hlsl_opts);
|
||||
hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
|
||||
if (args.hlsl_base_vertex_index_explicit_binding)
|
||||
{
|
||||
hlsl->set_hlsl_aux_buffer_binding(HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE,
|
||||
args.hlsl_base_vertex_index_register_index,
|
||||
args.hlsl_base_vertex_index_register_space);
|
||||
}
|
||||
}
|
||||
|
||||
if (build_dummy_sampler)
|
||||
@ -1532,6 +1544,11 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
|
||||
cbs.add("--hlsl-support-nonzero-basevertex-baseinstance",
|
||||
[&args](CLIParser &) { args.hlsl_support_nonzero_base = true; });
|
||||
cbs.add("--hlsl-basevertex-baseinstance-binding", [&args](CLIParser &parser) {
|
||||
args.hlsl_base_vertex_index_explicit_binding = true;
|
||||
args.hlsl_base_vertex_index_register_index = parser.next_uint();
|
||||
args.hlsl_base_vertex_index_register_space = parser.next_uint();
|
||||
});
|
||||
cbs.add("--hlsl-auto-binding", [&args](CLIParser &parser) {
|
||||
args.hlsl_binding_flags |= hlsl_resource_type_to_flag(parser.next_string());
|
||||
});
|
||||
|
30
reference/shaders-hlsl-no-opt/vert/base-instance.vert
Normal file
30
reference/shaders-hlsl-no-opt/vert/base-instance.vert
Normal file
@ -0,0 +1,30 @@
|
||||
static float4 gl_Position;
|
||||
static int gl_BaseInstanceARB;
|
||||
cbuffer SPIRV_Cross_VertexInfo
|
||||
{
|
||||
int SPIRV_Cross_BaseVertex;
|
||||
int SPIRV_Cross_BaseInstance;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
};
|
||||
|
||||
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 = SPIRV_Cross_BaseInstance;
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
30
reference/shaders-hlsl-no-opt/vert/base-vertex.vert
Normal file
30
reference/shaders-hlsl-no-opt/vert/base-vertex.vert
Normal file
@ -0,0 +1,30 @@
|
||||
static float4 gl_Position;
|
||||
static int gl_BaseVertexARB;
|
||||
cbuffer SPIRV_Cross_VertexInfo
|
||||
{
|
||||
int SPIRV_Cross_BaseVertex;
|
||||
int SPIRV_Cross_BaseInstance;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
};
|
||||
|
||||
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 = SPIRV_Cross_BaseVertex;
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
7
shaders-hlsl-no-opt/vert/base-instance.vert
Normal file
7
shaders-hlsl-no-opt/vert/base-instance.vert
Normal file
@ -0,0 +1,7 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_draw_parameters : require
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(gl_BaseInstanceARB);
|
||||
}
|
7
shaders-hlsl-no-opt/vert/base-vertex.vert
Normal file
7
shaders-hlsl-no-opt/vert/base-vertex.vert
Normal file
@ -0,0 +1,7 @@
|
||||
#version 450
|
||||
#extension GL_ARB_shader_draw_parameters : require
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(gl_BaseVertexARB);
|
||||
}
|
@ -748,6 +748,8 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
|
||||
case BuiltInSubgroupLeMask:
|
||||
case BuiltInSubgroupGtMask:
|
||||
case BuiltInSubgroupGeMask:
|
||||
case BuiltInBaseVertex:
|
||||
case BuiltInBaseInstance:
|
||||
// Handled specially.
|
||||
break;
|
||||
|
||||
@ -1032,8 +1034,6 @@ void CompilerHLSL::emit_builtin_variables()
|
||||
Bitset builtins = active_input_builtins;
|
||||
builtins.merge_or(active_output_builtins);
|
||||
|
||||
bool need_base_vertex_info = false;
|
||||
|
||||
std::unordered_map<uint32_t, ID> builtin_to_initializer;
|
||||
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
|
||||
if (!is_builtin_variable(var) || var.storage != StorageClassOutput || !var.initializer)
|
||||
@ -1087,7 +1087,13 @@ void CompilerHLSL::emit_builtin_variables()
|
||||
case BuiltInInstanceIndex:
|
||||
type = "int";
|
||||
if (hlsl_options.support_nonzero_base_vertex_base_instance)
|
||||
need_base_vertex_info = true;
|
||||
base_vertex_info.used = true;
|
||||
break;
|
||||
|
||||
case BuiltInBaseVertex:
|
||||
case BuiltInBaseInstance:
|
||||
type = "int";
|
||||
base_vertex_info.used = true;
|
||||
break;
|
||||
|
||||
case BuiltInInstanceId:
|
||||
@ -1187,9 +1193,17 @@ void CompilerHLSL::emit_builtin_variables()
|
||||
}
|
||||
});
|
||||
|
||||
if (need_base_vertex_info)
|
||||
if (base_vertex_info.used)
|
||||
{
|
||||
statement("cbuffer SPIRV_Cross_VertexInfo");
|
||||
string binding_info;
|
||||
if (base_vertex_info.explicit_binding)
|
||||
{
|
||||
binding_info = join(" : register(b", base_vertex_info.register_index);
|
||||
if (base_vertex_info.register_space)
|
||||
binding_info += join(", space", base_vertex_info.register_space);
|
||||
binding_info += ")";
|
||||
}
|
||||
statement("cbuffer SPIRV_Cross_VertexInfo", binding_info);
|
||||
begin_scope();
|
||||
statement("int SPIRV_Cross_BaseVertex;");
|
||||
statement("int SPIRV_Cross_BaseInstance;");
|
||||
@ -1198,6 +1212,30 @@ void CompilerHLSL::emit_builtin_variables()
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space)
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
{
|
||||
base_vertex_info.explicit_binding = true;
|
||||
base_vertex_info.register_space = register_space;
|
||||
base_vertex_info.register_index = register_index;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding)
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
base_vertex_info.explicit_binding = false;
|
||||
}
|
||||
|
||||
bool CompilerHLSL::is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const
|
||||
{
|
||||
if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE)
|
||||
return base_vertex_info.used;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_composite_constants()
|
||||
{
|
||||
// HLSL cannot declare structs or arrays inline, so we must move them out to
|
||||
@ -2612,6 +2650,14 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
||||
statement(builtin, " = int(stage_input.", builtin, ");");
|
||||
break;
|
||||
|
||||
case BuiltInBaseVertex:
|
||||
statement(builtin, " = SPIRV_Cross_BaseVertex;");
|
||||
break;
|
||||
|
||||
case BuiltInBaseInstance:
|
||||
statement(builtin, " = SPIRV_Cross_BaseInstance;");
|
||||
break;
|
||||
|
||||
case BuiltInInstanceId:
|
||||
// D3D semantics are uint, but shader wants int.
|
||||
statement(builtin, " = int(stage_input.", builtin, ");");
|
||||
|
@ -98,6 +98,11 @@ struct HLSLResourceBinding
|
||||
} cbv, uav, srv, sampler;
|
||||
};
|
||||
|
||||
enum HLSLAuxBinding
|
||||
{
|
||||
HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0
|
||||
};
|
||||
|
||||
class CompilerHLSL : public CompilerGLSL
|
||||
{
|
||||
public:
|
||||
@ -211,6 +216,11 @@ public:
|
||||
// Controls which storage buffer bindings will be forced to be declared as UAVs.
|
||||
void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding);
|
||||
|
||||
// By default, these magic buffers are not assigned a specific binding.
|
||||
void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space);
|
||||
void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding);
|
||||
bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const;
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
|
||||
@ -373,6 +383,14 @@ private:
|
||||
|
||||
std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t register_index = 0;
|
||||
uint32_t register_space = 0;
|
||||
bool explicit_binding = false;
|
||||
bool used = false;
|
||||
} base_vertex_info;
|
||||
|
||||
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL.
|
||||
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user