Work-around HLSL using zero-based InstanceID and VertexID variables, but SPIRV, like Metal, includes BaseInstance & BaseVertex. Until this can be fixed in DXC, which is really the proper place to solve this, we can decrement InstanceID & VertexID when the source is HLSL. Made in two parts. 1. Handle HLSL-style 0-based vertex/instance index. 2. We zero-base the InstanceID & VertexID variables for HLSL emulation elsewhere, so don't do it twice.
This commit is contained in:
parent
97a66ff906
commit
de6441af88
128
spirv_msl.cpp
128
spirv_msl.cpp
@ -2315,11 +2315,23 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
|
||||
{
|
||||
// The first member of the indirect buffer is always the number of vertices
|
||||
// to draw.
|
||||
statement("device ", to_name(ir.default_entry_point), "_", ib_var_ref, "& ", ib_var_ref, " = ",
|
||||
output_buffer_var_name, "[(", to_expression(builtin_instance_idx_id), " - ",
|
||||
to_expression(builtin_base_instance_id), ") * spvIndirectParams[0] + ",
|
||||
to_expression(builtin_vertex_idx_id), " - ", to_expression(builtin_base_vertex_id),
|
||||
"];");
|
||||
/* UE Change Begin: We zero-base the InstanceID & VertexID variables for HLSL emulation elsewhere, so don't do it twice */
|
||||
if (ir.source.hlsl == true)
|
||||
{
|
||||
statement("device ", to_name(ir.default_entry_point), "_", ib_var_ref, "& ", ib_var_ref, " = ",
|
||||
output_buffer_var_name, "[", to_expression(builtin_instance_idx_id), " * spvIndirectParams[0] + ",
|
||||
to_expression(builtin_vertex_idx_id),
|
||||
"];");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement("device ", to_name(ir.default_entry_point), "_", ib_var_ref, "& ", ib_var_ref, " = ",
|
||||
output_buffer_var_name, "[(", to_expression(builtin_instance_idx_id), " - ",
|
||||
to_expression(builtin_base_instance_id), ") * spvIndirectParams[0] + ",
|
||||
to_expression(builtin_vertex_idx_id), " - ", to_expression(builtin_base_vertex_id),
|
||||
"];");
|
||||
}
|
||||
/* UE Change End: We zero-base the InstanceID & VertexID variables for HLSL emulation elsewhere, so don't do it twice */
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -8024,7 +8036,11 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
|
||||
statement("char _m", index, "_pad", "[", pad_len, "];");
|
||||
}
|
||||
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
builtin_declaration = true;
|
||||
statement(to_struct_member(type, member_type_id, index, qualifier));
|
||||
builtin_declaration = false;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
}
|
||||
|
||||
void CompilerMSL::emit_struct_padding_target(const SPIRType &type)
|
||||
@ -8572,6 +8588,8 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
builtin_declaration = true;
|
||||
ep_args += builtin_type_decl(bi_type, var_id) + " " + to_expression(var_id);
|
||||
ep_args += " [[" + builtin_qualifier(bi_type);
|
||||
if (bi_type == BuiltInSampleMask && get_entry_point().flags.get(ExecutionModePostDepthCoverage))
|
||||
@ -8583,6 +8601,8 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
ep_args += ", post_depth_coverage";
|
||||
}
|
||||
ep_args += "]]";
|
||||
builtin_declaration = false;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
}
|
||||
}
|
||||
|
||||
@ -8613,6 +8633,14 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
if (needs_instance_idx_arg)
|
||||
ep_args += built_in_func_arg(BuiltInInstanceIndex, !ep_args.empty());
|
||||
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
if (needs_base_vertex_arg > 0)
|
||||
ep_args += built_in_func_arg(BuiltInBaseVertex, !ep_args.empty());
|
||||
|
||||
if (needs_base_instance_arg > 0)
|
||||
ep_args += built_in_func_arg(BuiltInBaseInstance, !ep_args.empty());
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
|
||||
if (capture_output_to_buffer)
|
||||
{
|
||||
// Add parameters to hold the indirect draw parameters and the shader output. This has to be handled
|
||||
@ -10580,19 +10608,97 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
|
||||
switch (builtin)
|
||||
{
|
||||
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
// Override GLSL compiler strictness
|
||||
case BuiltInVertexId:
|
||||
return "gl_VertexID";
|
||||
if ((ir.source.hlsl == true) && msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
if (builtin_declaration)
|
||||
{
|
||||
needs_base_vertex_arg++;
|
||||
return "gl_VertexID";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "(gl_VertexID - gl_BaseVertex)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "gl_VertexID";
|
||||
}
|
||||
case BuiltInInstanceId:
|
||||
return "gl_InstanceID";
|
||||
if ((ir.source.hlsl == true) && msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
if (builtin_declaration)
|
||||
{
|
||||
needs_base_instance_arg++;
|
||||
return "gl_InstanceID";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "(gl_InstanceID - gl_BaseInstance)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "gl_InstanceID";
|
||||
}
|
||||
case BuiltInVertexIndex:
|
||||
return "gl_VertexIndex";
|
||||
if ((ir.source.hlsl == true) && msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
if (builtin_declaration)
|
||||
{
|
||||
needs_base_vertex_arg++;
|
||||
return "gl_VertexIndex";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "(gl_VertexIndex - gl_BaseVertex)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "gl_VertexIndex";
|
||||
}
|
||||
case BuiltInInstanceIndex:
|
||||
return "gl_InstanceIndex";
|
||||
if ((ir.source.hlsl == true) && msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
if (builtin_declaration)
|
||||
{
|
||||
needs_base_instance_arg++;
|
||||
return "gl_InstanceIndex";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "(gl_InstanceIndex - gl_BaseInstance)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "gl_InstanceIndex";
|
||||
}
|
||||
case BuiltInBaseVertex:
|
||||
if (msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
needs_base_vertex_arg--;
|
||||
return "gl_BaseVertex";
|
||||
}
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("BaseVertex requires Metal 1.1 and Mac or Apple A9+ hardware.");
|
||||
}
|
||||
case BuiltInBaseInstance:
|
||||
if (msl_options.supports_msl_version(1, 1) && (msl_options.ios_support_base_vertex_instance || msl_options.is_macos()))
|
||||
{
|
||||
needs_base_instance_arg--;
|
||||
return "gl_BaseInstance";
|
||||
}
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("BaseInstance requires Metal 1.1 and Mac or Apple A9+ hardware.");
|
||||
}
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
case BuiltInDrawIndex:
|
||||
SPIRV_CROSS_THROW("DrawIndex is not supported in MSL.");
|
||||
|
||||
@ -10975,9 +11081,13 @@ string CompilerMSL::built_in_func_arg(BuiltIn builtin, bool prefix_comma)
|
||||
if (prefix_comma)
|
||||
bi_arg += ", ";
|
||||
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
builtin_declaration = true;
|
||||
bi_arg += builtin_type_decl(builtin);
|
||||
bi_arg += " " + builtin_to_glsl(builtin, StorageClassInput);
|
||||
bi_arg += " [[" + builtin_qualifier(builtin) + "]]";
|
||||
builtin_declaration = false;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
|
||||
return bi_arg;
|
||||
}
|
||||
|
@ -281,6 +281,9 @@ public:
|
||||
// Fragment output in MSL must have at least as many components as the render pass.
|
||||
// Add support to explicit pad out components.
|
||||
bool pad_fragment_output_components = false;
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
bool ios_support_base_vertex_instance = false;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
/* UE Change Begin: Use Metal's native frame-buffer fetch API for subpass inputs. */
|
||||
bool ios_use_framebuffer_fetch_subpasses = true;
|
||||
/* UE Change End: Use Metal's native frame-buffer fetch API for subpass inputs. */
|
||||
@ -773,9 +776,16 @@ protected:
|
||||
uint32_t patch_stage_out_var_id = 0;
|
||||
uint32_t stage_in_ptr_var_id = 0;
|
||||
uint32_t stage_out_ptr_var_id = 0;
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
int32_t needs_base_vertex_arg = 0;
|
||||
int32_t needs_base_instance_arg = 0;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
bool has_sampled_images = false;
|
||||
bool needs_vertex_idx_arg = false;
|
||||
bool needs_instance_idx_arg = false;
|
||||
/* UE Change Begin: Handle HLSL-style 0-based vertex/instance index. */
|
||||
bool builtin_declaration = false;
|
||||
/* UE Change End: Handle HLSL-style 0-based vertex/instance index. */
|
||||
/* UE Change Begin: Force the use of C style array declaration. */
|
||||
bool use_builtin_array = false;
|
||||
/* UE Change End: Force the use of C style array declaration. */
|
||||
|
Loading…
Reference in New Issue
Block a user