MSL improvements:

- pack/unpack nested constant buffer structs
- support for write-only textures (only global ones for now)
- better rt index support for msl generator
This commit is contained in:
Vadim Shcherbakov 2017-12-06 09:51:23 -08:00 committed by Arseny Kapoulkine
parent ed461b44d9
commit 6c41f9e9da
3 changed files with 29 additions and 6 deletions

View File

@ -657,10 +657,11 @@ struct SPIRVariable : IVariant
};
SPIRVariable() = default;
SPIRVariable(uint32_t basetype_, spv::StorageClass storage_, uint32_t initializer_ = 0)
SPIRVariable(uint32_t basetype_, spv::StorageClass storage_, uint32_t initializer_ = 0, uint32_t basevariable_ = 0)
: basetype(basetype_)
, storage(storage_)
, initializer(initializer_)
, basevariable(basevariable_)
{
}
@ -668,6 +669,7 @@ struct SPIRVariable : IVariant
spv::StorageClass storage = spv::StorageClassGeneric;
uint32_t decoration = 0;
uint32_t initializer = 0;
uint32_t basevariable = 0;
std::vector<uint32_t> dereference_chain;
bool compat_builtin = false;

View File

@ -1706,6 +1706,13 @@ void Compiler::parse(const Instruction &instruction)
auto &var = set<SPIRVariable>(id, type, storage, initializer);
auto &ttype = get<SPIRType>(type);
if (ttype.basetype == SPIRType::BaseType::Image)
{
set_decoration(id, DecorationNonWritable);
set_decoration(id, DecorationNonReadable);
}
if (variable_storage_is_aliased(var))
aliased_variables.push_back(var.self);

View File

@ -301,9 +301,10 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
uint32_t next_id = increase_bound_by(uint32_t(added_arg_ids.size()));
for (uint32_t arg_id : added_arg_ids)
{
uint32_t type_id = get<SPIRVariable>(arg_id).basetype;
auto var = get<SPIRVariable>(arg_id);
uint32_t type_id = var.basetype;
func.add_parameter(type_id, next_id, true);
set<SPIRVariable>(next_id, type_id, StorageClassFunction);
set<SPIRVariable>(next_id, type_id, StorageClassFunction, 0, arg_id);
// Ensure both the existing and new variables have the same name, and the name is valid
string vld_name = ensure_valid_name(to_name(arg_id), "v");
@ -360,6 +361,11 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
uint32_t mbr_type_id = type.member_types[mbr_idx];
auto &mbr_type = get<SPIRType>(mbr_type_id);
mark_as_packable(mbr_type);
if (mbr_type.type_alias)
{
auto &mbr_type_alias = get<SPIRType>(mbr_type.type_alias);
mark_as_packable(mbr_type_alias);
}
}
}
}
@ -1351,8 +1357,11 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
// Mark that this shader reads from this image
uint32_t img_id = ops[2];
auto *p_var = maybe_get_backing_variable(img_id);
if (p_var)
if (p_var && has_decoration(p_var->self, DecorationNonReadable))
{
unset_decoration(p_var->self, DecorationNonReadable);
force_recompile = true;
}
emit_texture_op(instruction);
break;
@ -2673,7 +2682,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
if (constref)
decl += "const ";
decl += type_to_glsl(type);
decl += type_to_glsl(type, arg.id);
if (is_array(type))
decl += "*";
@ -2940,6 +2949,8 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
default:
{
auto *p_var = maybe_get_backing_variable(id);
if (p_var && p_var->basevariable)
p_var = maybe_get<SPIRVariable>(p_var->basevariable);
if (p_var && !has_decoration(p_var->self, DecorationNonWritable))
{
img_type_name += ", access::";
@ -2996,12 +3007,13 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
return "gl_VertexIndex";
case BuiltInInstanceIndex:
return "gl_InstanceIndex";
case BuiltInLayer:
return current_function && (current_function->self == entry_point) ? stage_out_var_name + ".gl_Layer": "gl_Layer";
// When used in the entry function, output builtins are qualified with output struct name.
case BuiltInPosition:
case BuiltInPointSize:
case BuiltInClipDistance:
case BuiltInLayer:
case BuiltInFragDepth:
if (current_function && (current_function->self == entry_point))
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
@ -3096,6 +3108,8 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin)
return "uint";
case BuiltInInstanceIndex:
return "uint";
case BuiltInLayer:
return "uint";
// Vertex function out
case BuiltInClipDistance: