MSL: Emit threadgroup storage class for masked control point outputs.

Shader can still rely on writes to threadgroup memory to be visible.
This commit is contained in:
Hans-Kristian Arntzen 2021-03-26 17:23:44 +01:00
parent ea91579a7f
commit f2b5fb3f45
4 changed files with 27 additions and 10 deletions

View File

@ -12644,6 +12644,11 @@ string CompilerGLSL::variable_decl(const SPIRType &type, const string &name, uin
return join(type_name, " ", name, type_to_array_glsl(type));
}
bool CompilerGLSL::variable_decl_is_threadgroup_like(const SPIRVariable &var) const
{
return var.storage == StorageClassWorkgroup;
}
// Emit a structure member. Subclasses may override to modify output,
// or to dynamically add a padding member if needed.
void CompilerGLSL::emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
@ -13559,7 +13564,7 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags)
auto &var = get<SPIRVariable>(v);
var.deferred_declaration = false;
if (var.storage == StorageClassWorkgroup)
if (variable_decl_is_threadgroup_like(var))
{
// Special variable type which cannot have initializer,
// need to be declared as standalone variables.

View File

@ -385,6 +385,7 @@ protected:
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
virtual void emit_fixup();
virtual std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0);
virtual bool variable_decl_is_threadgroup_like(const SPIRVariable &var) const;
virtual std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id);
struct TextureFunctionBaseArguments

View File

@ -2927,7 +2927,8 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
// If we ignore an output, we must still emit it, since it might be used by app.
// Instead, just emit it as early declaration.
entry_func.add_local_variable(var.self);
vars_needing_early_declaration.push_back(var.self);
if (!variable_decl_is_threadgroup_like(var))
vars_needing_early_declaration.push_back(var.self);
return;
}
}
@ -12756,8 +12757,10 @@ string CompilerMSL::to_qualifiers_glsl(uint32_t id)
{
string quals;
auto *var = maybe_get<SPIRVariable>(id);
auto &type = expression_type(id);
if (type.storage == StorageClassWorkgroup)
if (type.storage == StorageClassWorkgroup || (var && variable_decl_is_threadgroup_like(*var)))
quals += "threadgroup ";
return quals;
@ -12938,18 +12941,24 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type)
}
}
bool CompilerMSL::variable_decl_is_threadgroup_like(const SPIRVariable &variable) const
{
bool is_patch = has_decoration(variable.self, DecorationPatch);
auto model = get_execution_model();
return variable.storage == StorageClassWorkgroup ||
(variable.storage == StorageClassOutput &&
model == ExecutionModelTessellationControl &&
!is_patch);
}
// Threadgroup arrays can't have a wrapper type
std::string CompilerMSL::variable_decl(const SPIRVariable &variable)
{
if (variable.storage == StorageClassWorkgroup)
{
bool old_is_using_builtin_array = is_using_builtin_array;
if (variable_decl_is_threadgroup_like(variable))
is_using_builtin_array = true;
}
std::string expr = CompilerGLSL::variable_decl(variable);
if (variable.storage == StorageClassWorkgroup)
{
is_using_builtin_array = false;
}
is_using_builtin_array = old_is_using_builtin_array;
return expr;
}

View File

@ -736,6 +736,8 @@ protected:
// Threadgroup arrays can't have a wrapper type
std::string variable_decl(const SPIRVariable &variable) override;
bool variable_decl_is_threadgroup_like(const SPIRVariable &variable) const override;
// GCC workaround of lambdas calling protected functions (for older GCC versions)
std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0) override;