HLSL: Support BaseVertex/BaseInstance offsets.
Opt-in, since user need to know about a cbuffer. Conflicts a bit with the GLSL option for base instance, since that one is enabled by default, but the HLSL one isn't (because user needs to know about a magic cbuffer, whereas GLSL can only get default initialized uniform).
This commit is contained in:
Родитель
a57b93f6b7
Коммит
a2a44d944e
4
main.cpp
4
main.cpp
|
@ -516,6 +516,7 @@ struct CLIArguments
|
|||
bool msl = false;
|
||||
bool hlsl = false;
|
||||
bool hlsl_compat = false;
|
||||
bool hlsl_support_nonzero_base = false;
|
||||
bool vulkan_semantics = false;
|
||||
bool flatten_multidimensional_arrays = false;
|
||||
bool use_420pack_extension = true;
|
||||
|
@ -549,6 +550,7 @@ static void print_help()
|
|||
"\t[--reflect]\n"
|
||||
"\t[--shader-model]\n"
|
||||
"\t[--hlsl-enable-compat]\n"
|
||||
"\t[--hlsl-support-nonzero-basevertex-baseinstance]\n"
|
||||
"\t[--separate-shader-objects]\n"
|
||||
"\t[--pls-in format input-name]\n"
|
||||
"\t[--pls-out format output-name]\n"
|
||||
|
@ -705,6 +707,7 @@ static int main_inner(int argc, char *argv[])
|
|||
cbs.add("--msl", [&args](CLIParser &) { args.msl = true; });
|
||||
cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; });
|
||||
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("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
|
||||
cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
|
||||
cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });
|
||||
|
@ -991,6 +994,7 @@ static int main_inner(int argc, char *argv[])
|
|||
build_dummy_sampler = true;
|
||||
}
|
||||
|
||||
hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
|
||||
hlsl->set_hlsl_options(hlsl_opts);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
// Inverts gl_Position.y or equivalent.
|
||||
bool flip_vert_y = false;
|
||||
|
||||
// GLSL only, for HLSL version of this option, see CompilerHLSL.
|
||||
// If true, the backend will assume that InstanceIndex will need to apply
|
||||
// a base instance offset. Set to false if you know you will never use base instance
|
||||
// functionality as it might remove some internal uniforms.
|
||||
|
|
|
@ -902,6 +902,8 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
Bitset builtins = active_input_builtins;
|
||||
builtins.merge_or(active_output_builtins);
|
||||
|
||||
bool need_base_vertex_info = false;
|
||||
|
||||
// Emit global variables for the interface variables which are statically used by the shader.
|
||||
builtins.for_each_bit([&](uint32_t i) {
|
||||
const char *type = nullptr;
|
||||
|
@ -921,8 +923,13 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
|
||||
case BuiltInVertexId:
|
||||
case BuiltInVertexIndex:
|
||||
case BuiltInInstanceId:
|
||||
case BuiltInInstanceIndex:
|
||||
type = "int";
|
||||
if (hlsl_options.support_nonzero_base_vertex_base_instance)
|
||||
need_base_vertex_info = true;
|
||||
break;
|
||||
|
||||
case BuiltInInstanceId:
|
||||
case BuiltInSampleId:
|
||||
type = "int";
|
||||
break;
|
||||
|
@ -998,6 +1005,16 @@ void CompilerHLSL::emit_builtin_variables()
|
|||
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
|
||||
}
|
||||
});
|
||||
|
||||
if (need_base_vertex_info)
|
||||
{
|
||||
statement("cbuffer SPIRV_Cross_VertexInfo");
|
||||
begin_scope();
|
||||
statement("int SPIRV_Cross_BaseVertex;");
|
||||
statement("int SPIRV_Cross_BaseInstance;");
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_composite_constants()
|
||||
|
@ -2243,8 +2260,20 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||
|
||||
case BuiltInVertexId:
|
||||
case BuiltInVertexIndex:
|
||||
case BuiltInInstanceId:
|
||||
case BuiltInInstanceIndex:
|
||||
// D3D semantics are uint, but shader wants int.
|
||||
if (hlsl_options.support_nonzero_base_vertex_base_instance)
|
||||
{
|
||||
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 BuiltInInstanceId:
|
||||
// D3D semantics are uint, but shader wants int.
|
||||
statement(builtin, " = int(stage_input.", builtin, ");");
|
||||
break;
|
||||
|
|
|
@ -54,6 +54,12 @@ public:
|
|||
|
||||
// Allows the PointCoord builtin, returns float2(0.5, 0.5), as PointCoord is not supported in HLSL.
|
||||
bool point_coord_compat = false;
|
||||
|
||||
// If true, the backend will assume that VertexIndex and InstanceIndex will need to apply
|
||||
// a base offset, and you will need to fill in a cbuffer with offsets.
|
||||
// Set to false if you know you will never use base instance or base vertex
|
||||
// functionality as it might remove an internal cbuffer.
|
||||
bool support_nonzero_base_vertex_base_instance = false;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
|
|
Загрузка…
Ссылка в новой задаче