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:
Chip Davis 2019-02-06 15:17:14 -06:00
parent f55253dc1b
commit 056c0e207d
14 changed files with 29 additions and 59 deletions

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -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;
}

View File

@ -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;
}

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -7,7 +7,6 @@ using namespace metal;
struct spvAux
{
uint vertexCount;
uint swizzleConst[1];
};

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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, ")]]");
}
}

View File

@ -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;