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:
Hans-Kristian Arntzen 2017-02-24 11:15:34 +01:00
Родитель 036b9b73f5
Коммит bcf2303ba0
4 изменённых файлов: 34 добавлений и 10 удалений

Просмотреть файл

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