Take the vertex count from any indirect parameters passed.
This is necessary to deal with indirect draws, where the draw parameters are given in a buffer instead of passed by the CPU. For normal draws, the draw parameters are set with Metal's `setVertexBytes:` method. This undoes the change to add the vertex count to the aux buffer, rendering that entire discussion largely moot. Oh well. It was a discussion that needed to happen anyway.
This commit is contained in:
parent
f55253dc1b
commit
056c0e207d
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -8,12 +8,6 @@ struct UBO
|
||||
float4x4 uMVP;
|
||||
};
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 vNormal [[user(locn0)]];
|
||||
@ -26,9 +20,9 @@ struct main0_in
|
||||
float3 aNormal [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], constant spvAux& spvAuxBuffer [[buffer(30)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(29)]])
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
|
||||
{
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvAuxBuffer.vertexCount + gl_VertexIndex - gl_BaseVertex];
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
|
||||
out.gl_Position = _16.uMVP * in.aVertex;
|
||||
out.vNormal = in.aNormal;
|
||||
}
|
||||
|
@ -8,12 +8,6 @@ struct UBO
|
||||
float4x4 uMVP;
|
||||
};
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 vNormal [[user(locn0)]];
|
||||
@ -26,9 +20,9 @@ struct main0_in
|
||||
float3 aNormal [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]], constant spvAux& spvAuxBuffer [[buffer(30)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(29)]])
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
|
||||
{
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvAuxBuffer.vertexCount + gl_VertexIndex - gl_BaseVertex];
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
|
||||
out.gl_Position = _18.uMVP * in.aVertex;
|
||||
out.vNormal = in.aNormal;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,6 @@ using namespace metal;
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
|
@ -8,12 +8,6 @@ struct UBO
|
||||
float4x4 uMVP;
|
||||
};
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 vNormal [[user(locn0)]];
|
||||
@ -26,9 +20,9 @@ struct main0_in
|
||||
float3 aNormal [[attribute(1)]];
|
||||
};
|
||||
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], constant spvAux& spvAuxBuffer [[buffer(30)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(29)]])
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
|
||||
{
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvAuxBuffer.vertexCount + gl_VertexIndex - gl_BaseVertex];
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
|
||||
out.gl_Position = _16.uMVP * in.aVertex;
|
||||
out.vNormal = in.aNormal;
|
||||
}
|
||||
|
@ -10,12 +10,6 @@ struct UBO
|
||||
float4x4 uMVP;
|
||||
};
|
||||
|
||||
struct spvAux
|
||||
{
|
||||
uint vertexCount;
|
||||
uint swizzleConst[1];
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 vNormal [[user(locn0)]];
|
||||
@ -34,9 +28,9 @@ void set_output(device float4& gl_Position, constant UBO& v_18, thread float4& a
|
||||
vNormal = aNormal;
|
||||
}
|
||||
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& v_18 [[buffer(0)]], constant spvAux& spvAuxBuffer [[buffer(30)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(29)]])
|
||||
vertex void main0(main0_in in [[stage_in]], constant UBO& v_18 [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_BaseVertex [[base_vertex]], uint gl_InstanceIndex [[instance_id]], uint gl_BaseInstance [[base_instance]], device main0_out* spvOut [[buffer(28)]], device uint* spvIndirectParams [[buffer(29)]])
|
||||
{
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvAuxBuffer.vertexCount + gl_VertexIndex - gl_BaseVertex];
|
||||
device main0_out& out = spvOut[(gl_InstanceIndex - gl_BaseInstance) * spvIndirectParams[0] + gl_VertexIndex - gl_BaseVertex];
|
||||
set_output(out.gl_Position, v_18, in.aVertex, out.vNormal, in.aNormal);
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,7 @@ using namespace std;
|
||||
static const uint32_t k_unknown_location = ~0u;
|
||||
static const uint32_t k_unknown_component = ~0u;
|
||||
|
||||
static const uint32_t k_aux_mbr_idx_vertex_count = 0u;
|
||||
static const uint32_t k_aux_mbr_idx_swizzle_const = 1u;
|
||||
static const uint32_t k_aux_mbr_idx_swizzle_const = 0u;
|
||||
|
||||
CompilerMSL::CompilerMSL(vector<uint32_t> spirv_, vector<MSLVertexAttr> *p_vtx_attrs,
|
||||
vector<MSLResourceBinding> *p_res_bindings)
|
||||
@ -254,7 +253,7 @@ void CompilerMSL::build_implicit_builtins()
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_aux_buffer_def || capture_output_to_buffer)
|
||||
if (needs_aux_buffer_def)
|
||||
{
|
||||
uint32_t offset = ir.increase_bound_by(5);
|
||||
uint32_t type_id = offset;
|
||||
@ -278,16 +277,13 @@ void CompilerMSL::build_implicit_builtins()
|
||||
|
||||
SPIRType struct_type;
|
||||
struct_type.basetype = SPIRType::Struct;
|
||||
struct_type.member_types.push_back(type_id); // Vertex count
|
||||
struct_type.member_types.push_back(type_arr_id); // Swizzle constants
|
||||
struct_type.member_types.push_back(type_arr_id);
|
||||
auto &type = set<SPIRType>(struct_id, struct_type);
|
||||
type.self = struct_id;
|
||||
set_decoration(struct_id, DecorationBlock);
|
||||
set_name(struct_id, "spvAux");
|
||||
set_member_name(struct_id, k_aux_mbr_idx_vertex_count, "vertexCount");
|
||||
set_member_decoration(struct_id, k_aux_mbr_idx_vertex_count, DecorationOffset, 0);
|
||||
set_member_name(struct_id, k_aux_mbr_idx_swizzle_const, "swizzleConst");
|
||||
set_member_decoration(struct_id, k_aux_mbr_idx_swizzle_const, DecorationOffset, 4);
|
||||
set_member_decoration(struct_id, k_aux_mbr_idx_swizzle_const, DecorationOffset, 0);
|
||||
|
||||
SPIRType struct_type_ptr = struct_type;
|
||||
struct_type_ptr.pointer = true;
|
||||
@ -1515,12 +1511,15 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
|
||||
// as a reference to the final output element in the buffer. Then we can
|
||||
// avoid the extra copy.
|
||||
entry_func.fixup_hooks_in.push_back([=]() {
|
||||
auto &aux_type = expression_type(aux_buffer_id);
|
||||
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), ") * ", to_expression(aux_buffer_id), ".",
|
||||
to_member_name(aux_type, k_aux_mbr_idx_vertex_count), " + ",
|
||||
to_expression(builtin_vertex_idx_id), " - ", to_expression(builtin_base_vertex_id), "];");
|
||||
if (stage_out_var_id)
|
||||
{
|
||||
// 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), "];");
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
@ -4761,14 +4760,16 @@ string CompilerMSL::entry_point_args(bool append_comma)
|
||||
|
||||
if (capture_output_to_buffer)
|
||||
{
|
||||
// Add a parameter to hold the shader output. This has to be handled
|
||||
// Add parameters to hold the indirect draw parameters and the shader output. This has to be handled
|
||||
// specially because it needs to be a pointer, not a reference.
|
||||
if (stage_out_var_id)
|
||||
{
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += "device " + type_to_glsl(get_stage_out_struct_type()) + "* " + output_buffer_var_name +
|
||||
" [[buffer(" + convert_to_string(msl_options.shader_output_buffer_index) + ")]]";
|
||||
ep_args += join("device ", type_to_glsl(get_stage_out_struct_type()), "* ", output_buffer_var_name,
|
||||
" [[buffer(", msl_options.shader_output_buffer_index, ")]], ");
|
||||
ep_args +=
|
||||
join("device uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ static const uint32_t kPushConstBinding = 0;
|
||||
|
||||
// The current version of the aux buffer structure. It must be incremented any time a
|
||||
// new field is added to the aux buffer.
|
||||
#define SPIRV_CROSS_MSL_AUX_BUFFER_STRUCT_VERSION 2
|
||||
#define SPIRV_CROSS_MSL_AUX_BUFFER_STRUCT_VERSION 1
|
||||
|
||||
// Decompiles SPIR-V to Metal Shading Language
|
||||
class CompilerMSL : public CompilerGLSL
|
||||
@ -168,7 +168,8 @@ public:
|
||||
uint32_t msl_version = make_msl_version(1, 2);
|
||||
uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
|
||||
uint32_t aux_buffer_index = 30;
|
||||
uint32_t shader_output_buffer_index = 29;
|
||||
uint32_t indirect_params_buffer_index = 29;
|
||||
uint32_t shader_output_buffer_index = 28;
|
||||
bool enable_point_size_builtin = true;
|
||||
bool disable_rasterization = false;
|
||||
bool capture_output_to_buffer = false;
|
||||
|
Loading…
Reference in New Issue
Block a user