MSL: Ensure discrete runtime arrays of buffers have known length.
An entry-point array of buffers, that is not part of a Metal argument buffer, requires a known length, so it can be emitted as discrete buffers. For runtime arrays of resources, this can be retrieved from the resource binding information added via add_msl_resource_binding(). - Redefine get_resource_array_size() to consolidate array sizing using both var type, and runtime array sizing from resource bindings, if not found in type. - Use get_resource_array_size() to fix issue for runtime arrays of buffers. - Update runtime arrays of images and samplers to use get_resource_array_size(). - Add .DS_Store to .gitignore (unrelated).
This commit is contained in:
parent
f349c91274
commit
d47183c0db
3
.gitignore
vendored
3
.gitignore
vendored
@ -21,5 +21,8 @@
|
|||||||
.vs/
|
.vs/
|
||||||
*.vcxproj.user
|
*.vcxproj.user
|
||||||
|
|
||||||
|
# Mac OS X Finder
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
!CMakeLists.txt
|
!CMakeLists.txt
|
||||||
!LICENSES/*.txt
|
!LICENSES/*.txt
|
||||||
|
@ -191,13 +191,19 @@ bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t de
|
|||||||
|
|
||||||
bool CompilerMSL::is_var_runtime_size_array(const SPIRVariable &var) const
|
bool CompilerMSL::is_var_runtime_size_array(const SPIRVariable &var) const
|
||||||
{
|
{
|
||||||
return is_runtime_size_array(get_variable_data_type(var)) && get_resource_array_size(var.self) == 0;
|
auto& type = get_variable_data_type(var);
|
||||||
|
return is_runtime_size_array(type) && get_resource_array_size(type, var.self) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the size of the array of resources used by the variable with the specified id.
|
// Returns the size of the array of resources used by the variable with the specified type and id.
|
||||||
// The returned value is retrieved from the resource binding added using add_msl_resource_binding().
|
// The size is first retrieved from the type, but in the case of runtime array sizing,
|
||||||
uint32_t CompilerMSL::get_resource_array_size(uint32_t id) const
|
// the size is retrieved from the resource binding added using add_msl_resource_binding().
|
||||||
|
uint32_t CompilerMSL::get_resource_array_size(const SPIRType &type, uint32_t id) const
|
||||||
{
|
{
|
||||||
|
uint32_t array_size = to_array_size_literal(type);
|
||||||
|
if (array_size)
|
||||||
|
return array_size;
|
||||||
|
|
||||||
StageSetBinding tuple = { get_entry_point().model, get_decoration(id, DecorationDescriptorSet),
|
StageSetBinding tuple = { get_entry_point().model, get_decoration(id, DecorationDescriptorSet),
|
||||||
get_decoration(id, DecorationBinding) };
|
get_decoration(id, DecorationBinding) };
|
||||||
auto itr = resource_bindings.find(tuple);
|
auto itr = resource_bindings.find(tuple);
|
||||||
@ -1399,7 +1405,8 @@ void CompilerMSL::emit_entry_point_declarations()
|
|||||||
statement(get_argument_address_space(var), " ", type_to_glsl(buffer_type), "* ",
|
statement(get_argument_address_space(var), " ", type_to_glsl(buffer_type), "* ",
|
||||||
to_restrict(var.self, true), name, "[] =");
|
to_restrict(var.self, true), name, "[] =");
|
||||||
begin_scope();
|
begin_scope();
|
||||||
for (uint32_t i = 0; i < to_array_size_literal(type); ++i)
|
uint32_t array_size = get_resource_array_size(type, var.self);
|
||||||
|
for (uint32_t i = 0; i < array_size; ++i)
|
||||||
statement(name, "_", i, ",");
|
statement(name, "_", i, ",");
|
||||||
end_scope_decl();
|
end_scope_decl();
|
||||||
statement_no_indent("");
|
statement_no_indent("");
|
||||||
@ -13410,11 +13417,6 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
|
|||||||
if (type.array.size() > 1)
|
if (type.array.size() > 1)
|
||||||
SPIRV_CROSS_THROW("Arrays of arrays of buffers are not supported.");
|
SPIRV_CROSS_THROW("Arrays of arrays of buffers are not supported.");
|
||||||
|
|
||||||
// Metal doesn't directly support this, so we must expand the
|
|
||||||
// array. We'll declare a local array to hold these elements
|
|
||||||
// later.
|
|
||||||
uint32_t array_size = to_array_size_literal(type);
|
|
||||||
|
|
||||||
is_using_builtin_array = true;
|
is_using_builtin_array = true;
|
||||||
if (is_var_runtime_size_array(var))
|
if (is_var_runtime_size_array(var))
|
||||||
{
|
{
|
||||||
@ -13442,6 +13444,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
uint32_t array_size = get_resource_array_size(type, var_id);
|
||||||
for (uint32_t i = 0; i < array_size; ++i)
|
for (uint32_t i = 0; i < array_size; ++i)
|
||||||
{
|
{
|
||||||
if (!ep_args.empty())
|
if (!ep_args.empty())
|
||||||
@ -15342,10 +15345,7 @@ std::string CompilerMSL::sampler_type(const SPIRType &type, uint32_t id)
|
|||||||
|
|
||||||
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||||
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
||||||
uint32_t array_size = to_array_size_literal(type);
|
uint32_t array_size = get_resource_array_size(type, id);
|
||||||
if (array_size == 0)
|
|
||||||
array_size = get_resource_array_size(id);
|
|
||||||
|
|
||||||
if (array_size == 0)
|
if (array_size == 0)
|
||||||
{
|
{
|
||||||
add_spv_func_and_recompile(SPVFuncImplVariableDescriptor);
|
add_spv_func_and_recompile(SPVFuncImplVariableDescriptor);
|
||||||
@ -15395,10 +15395,7 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
|||||||
|
|
||||||
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||||
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
||||||
uint32_t array_size = to_array_size_literal(type);
|
uint32_t array_size = get_resource_array_size(type, id);
|
||||||
if (array_size == 0)
|
|
||||||
array_size = get_resource_array_size(id);
|
|
||||||
|
|
||||||
if (array_size == 0)
|
if (array_size == 0)
|
||||||
{
|
{
|
||||||
add_spv_func_and_recompile(SPVFuncImplVariableDescriptor);
|
add_spv_func_and_recompile(SPVFuncImplVariableDescriptor);
|
||||||
|
@ -977,7 +977,7 @@ protected:
|
|||||||
void emit_interface_block(uint32_t ib_var_id);
|
void emit_interface_block(uint32_t ib_var_id);
|
||||||
bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs);
|
bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs);
|
||||||
bool is_var_runtime_size_array(const SPIRVariable &var) const;
|
bool is_var_runtime_size_array(const SPIRVariable &var) const;
|
||||||
uint32_t get_resource_array_size(uint32_t id) const;
|
uint32_t get_resource_array_size(const SPIRType &type, uint32_t id) const;
|
||||||
|
|
||||||
void fix_up_shader_inputs_outputs();
|
void fix_up_shader_inputs_outputs();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user