Do not emit storage qualifiers for local variables.
Metal backend uses local variables to implement global variables. Do not emit storage qualifiers for any variable which is declared inside a function.
This commit is contained in:
Родитель
036b9b73f5
Коммит
bcf2303ba0
|
@ -3466,12 +3466,7 @@ void CompilerGLSL::store_flattened_struct(SPIRVariable &var, uint32_t value)
|
|||
// Since we're declaring a variable potentially multiple times here,
|
||||
// store the variable in an isolated scope.
|
||||
begin_scope();
|
||||
|
||||
// Emit variable without storage qualifiers because it's a local variable here.
|
||||
auto old_storage = var.storage;
|
||||
var.storage = StorageClassFunction;
|
||||
statement(variable_decl(var), " = ", rhs, ";");
|
||||
var.storage = old_storage;
|
||||
statement(variable_decl_function_local(var), " = ", rhs, ";");
|
||||
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||
|
@ -3828,12 +3823,25 @@ void CompilerGLSL::register_call_out_argument(uint32_t id)
|
|||
flush_variable_declaration(var->self);
|
||||
}
|
||||
|
||||
string CompilerGLSL::variable_decl_function_local(SPIRVariable &var)
|
||||
{
|
||||
// These variables are always function local,
|
||||
// so make sure we emit the variable without storage qualifiers.
|
||||
// Some backends will inject custom variables locally in a function
|
||||
// with a storage qualifier which is not function-local.
|
||||
auto old_storage = var.storage;
|
||||
var.storage = StorageClassFunction;
|
||||
auto expr = variable_decl(var);
|
||||
var.storage = old_storage;
|
||||
return expr;
|
||||
}
|
||||
|
||||
void CompilerGLSL::flush_variable_declaration(uint32_t id)
|
||||
{
|
||||
auto *var = maybe_get<SPIRVariable>(id);
|
||||
if (var && var->deferred_declaration)
|
||||
{
|
||||
statement(variable_decl(*var), ";");
|
||||
statement(variable_decl_function_local(*var), ";");
|
||||
var->deferred_declaration = false;
|
||||
}
|
||||
}
|
||||
|
@ -6099,7 +6107,7 @@ void CompilerGLSL::emit_function(SPIRFunction &func, uint64_t return_flags)
|
|||
add_local_variable_name(var.self);
|
||||
|
||||
if (var.initializer)
|
||||
statement(variable_decl(var), ";");
|
||||
statement(variable_decl_function_local(var), ";");
|
||||
else
|
||||
{
|
||||
// Don't declare variable until first use to declutter the GLSL output quite a lot.
|
||||
|
|
|
@ -239,6 +239,7 @@ protected:
|
|||
std::string to_array_size(const SPIRType &type, uint32_t index);
|
||||
uint32_t to_array_size_literal(const SPIRType &type, uint32_t index) const;
|
||||
std::string variable_decl(const SPIRVariable &variable);
|
||||
std::string variable_decl_function_local(SPIRVariable &variable);
|
||||
|
||||
void add_local_variable_name(uint32_t id);
|
||||
void add_resource_name(uint32_t id);
|
||||
|
@ -349,7 +350,7 @@ protected:
|
|||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
std::string to_qualifiers_glsl(uint32_t id);
|
||||
const char *to_precision_qualifiers_glsl(uint32_t id);
|
||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
|
||||
virtual const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
|
||||
const char *flags_to_precision_qualifiers_glsl(const SPIRType &type, uint64_t flags);
|
||||
const char *format_to_glsl(spv::ImageFormat format);
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index);
|
||||
|
|
|
@ -165,6 +165,19 @@ void CompilerHLSL::emit_interface_block_globally(const SPIRVariable &var)
|
|||
}
|
||||
}
|
||||
|
||||
const char *CompilerHLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
|
||||
{
|
||||
// Input and output variables are handled specially in HLSL backend.
|
||||
// The variables are declared as global, private variables, and do not need any qualifiers.
|
||||
if (var.storage == StorageClassUniformConstant || var.storage == StorageClassUniform ||
|
||||
var.storage == StorageClassPushConstant)
|
||||
{
|
||||
return "uniform ";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, uint32_t &binding_number, bool builtins)
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
@ -897,7 +910,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
|
|||
void CompilerHLSL::emit_uniform(const SPIRVariable &var)
|
||||
{
|
||||
add_resource_name(var.self);
|
||||
statement("uniform ", variable_decl(var), ";");
|
||||
statement(variable_decl(var), ";");
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t count)
|
||||
|
|
|
@ -66,6 +66,8 @@ private:
|
|||
void emit_push_constant_block(const SPIRVariable &var) override;
|
||||
void emit_uniform(const SPIRVariable &var) override;
|
||||
|
||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
||||
|
||||
Options options;
|
||||
bool requires_op_fmod = false;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче