MSL: Move inline uniform blocks to the end of the argument buffer.
Limit inline blocks to one per descriptor set. This should avoid the need for complicated code to calculate the argument buffer ID stride of an inline uniform block. If there's demand for more inline blocks, we can revisit this.
This commit is contained in:
parent
fedbc35315
commit
ae6c05f6f4
@ -36,8 +36,8 @@ constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(3u, 3u, 2u);
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
Foo m_32 [[id(0)]];
|
||||
constant Bar* m_38 [[id(12)]];
|
||||
constant Bar* m_38 [[id(0)]];
|
||||
Foo m_32 [[id(1)]];
|
||||
};
|
||||
|
||||
struct spvDescriptorSetBuffer1
|
||||
|
@ -36,8 +36,8 @@ constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(3u, 3u, 2u);
|
||||
|
||||
struct spvDescriptorSetBuffer0
|
||||
{
|
||||
Foo m_32 [[id(0)]];
|
||||
constant Bar* m_38 [[id(12)]];
|
||||
constant Bar* m_38 [[id(0)]];
|
||||
Foo m_32 [[id(1)]];
|
||||
};
|
||||
|
||||
struct spvDescriptorSetBuffer1
|
||||
|
@ -9856,31 +9856,6 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
|
||||
});
|
||||
}
|
||||
|
||||
// Returns the number of IDs that Metal would assign to an inline uniform block in an argument buffer.
|
||||
uint32_t CompilerMSL::get_inline_uniform_block_binding_stride(SPIRType &type)
|
||||
{
|
||||
// We need this information now.
|
||||
mark_scalar_layout_structs(type);
|
||||
unordered_set<uint32_t> aligned_structs;
|
||||
align_struct(type, aligned_structs);
|
||||
uint32_t binding_stride = 0;
|
||||
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||
{
|
||||
uint32_t member_type_id = type.member_types[i];
|
||||
uint32_t member_binding_stride = 1;
|
||||
auto &member_type = get<SPIRType>(member_type_id);
|
||||
if (member_type.basetype == SPIRType::Struct)
|
||||
member_binding_stride = get_inline_uniform_block_binding_stride(member_type);
|
||||
else if (member_is_packed_physical_type(type, i) && is_matrix(member_type))
|
||||
// Packed matrices are represented as arrays, so they get multiple IDs.
|
||||
member_binding_stride = member_type.columns;
|
||||
for (uint32_t j = 0; j < uint32_t(member_type.array.size()); j++)
|
||||
member_binding_stride *= to_array_size_literal(member_type, j);
|
||||
binding_stride += member_binding_stride;
|
||||
}
|
||||
return binding_stride;
|
||||
}
|
||||
|
||||
// Returns the Metal index of the resource of the specified type as used by the specified variable.
|
||||
uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane)
|
||||
{
|
||||
@ -9949,8 +9924,6 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base
|
||||
allocate_argument_buffer_ids = descriptor_set_is_argument_buffer(var_desc_set);
|
||||
|
||||
uint32_t binding_stride = 1;
|
||||
if (inline_uniform_blocks.count(SetBindingPair{ var_desc_set, var_binding }))
|
||||
binding_stride = get_inline_uniform_block_binding_stride(get_variable_data_type(var));
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
for (uint32_t i = 0; i < uint32_t(type.array.size()); i++)
|
||||
binding_stride *= to_array_size_literal(type, i);
|
||||
@ -12477,6 +12450,7 @@ void CompilerMSL::analyze_argument_buffers()
|
||||
uint32_t plane;
|
||||
};
|
||||
SmallVector<Resource> resources_in_set[kMaxArgumentBuffers];
|
||||
SmallVector<uint32_t> inline_block_vars;
|
||||
|
||||
bool set_needs_swizzle_buffer[kMaxArgumentBuffers] = {};
|
||||
bool set_needs_buffer_sizes[kMaxArgumentBuffers] = {};
|
||||
@ -12509,6 +12483,7 @@ void CompilerMSL::analyze_argument_buffers()
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t binding = get_decoration(var_id, DecorationBinding);
|
||||
if (type.basetype == SPIRType::SampledImage)
|
||||
{
|
||||
add_resource_name(var_id);
|
||||
@ -12531,9 +12506,14 @@ void CompilerMSL::analyze_argument_buffers()
|
||||
{ &var, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index, 0 });
|
||||
}
|
||||
}
|
||||
else if (inline_uniform_blocks.count(SetBindingPair{ desc_set, binding }))
|
||||
{
|
||||
inline_block_vars.push_back(var_id);
|
||||
}
|
||||
else if (!constexpr_sampler)
|
||||
{
|
||||
// constexpr samplers are not declared as resources.
|
||||
// Inline uniform blocks are always emitted at the end.
|
||||
if (!msl_options.is_ios() || type.basetype != SPIRType::Image || type.image.sampled != 2)
|
||||
{
|
||||
add_resource_name(var_id);
|
||||
@ -12608,6 +12588,16 @@ void CompilerMSL::analyze_argument_buffers()
|
||||
}
|
||||
}
|
||||
|
||||
// Now add inline uniform blocks.
|
||||
for (uint32_t var_id : inline_block_vars)
|
||||
{
|
||||
auto &var = get<SPIRVariable>(var_id);
|
||||
uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet);
|
||||
add_resource_name(var_id);
|
||||
resources_in_set[desc_set].push_back(
|
||||
{ &var, to_name(var_id), SPIRType::Struct, get_metal_resource_index(var, SPIRType::Struct), 0 });
|
||||
}
|
||||
|
||||
for (uint32_t desc_set = 0; desc_set < kMaxArgumentBuffers; desc_set++)
|
||||
{
|
||||
auto &resources = resources_in_set[desc_set];
|
||||
|
@ -862,7 +862,6 @@ protected:
|
||||
std::map<SetBindingPair, std::pair<uint32_t, uint32_t>> buffers_requiring_dynamic_offset;
|
||||
|
||||
std::unordered_set<SetBindingPair, InternalHasher> inline_uniform_blocks;
|
||||
uint32_t get_inline_uniform_block_binding_stride(SPIRType &type);
|
||||
|
||||
uint32_t argument_buffer_ids[kMaxArgumentBuffers];
|
||||
uint32_t argument_buffer_discrete_mask = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user