MSL: Unify the get_*_address_space() methods.
These methods have largely the same logic, with minor differences. That I felt compelled to duplicate the logic into another method was one of the things that bothered me about the variable pointers change. This cleans that part of the code up; now we don't have two places to change.
This commit is contained in:
parent
301eab1b7a
commit
df18d98bea
@ -6576,80 +6576,15 @@ string CompilerMSL::func_type_decl(SPIRType &type)
|
|||||||
string CompilerMSL::get_argument_address_space(const SPIRVariable &argument)
|
string CompilerMSL::get_argument_address_space(const SPIRVariable &argument)
|
||||||
{
|
{
|
||||||
const auto &type = get<SPIRType>(argument.basetype);
|
const auto &type = get<SPIRType>(argument.basetype);
|
||||||
Bitset flags;
|
return get_type_address_space(type, argument.self, true);
|
||||||
if (type.basetype == SPIRType::Struct &&
|
|
||||||
(has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock)))
|
|
||||||
flags = ir.get_buffer_block_flags(argument);
|
|
||||||
else
|
|
||||||
flags = get_decoration_bitset(argument.self);
|
|
||||||
const char *addr_space = nullptr;
|
|
||||||
|
|
||||||
switch (type.storage)
|
|
||||||
{
|
|
||||||
case StorageClassWorkgroup:
|
|
||||||
addr_space = "threadgroup";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StorageClassStorageBuffer:
|
|
||||||
{
|
|
||||||
// For arguments from variable pointers, we use the write count deduction, so
|
|
||||||
// we should not assume any constness here. Only for global SSBOs.
|
|
||||||
bool readonly = false;
|
|
||||||
if (has_decoration(type.self, DecorationBlock))
|
|
||||||
readonly = flags.get(DecorationNonWritable);
|
|
||||||
|
|
||||||
addr_space = readonly ? "const device" : "device";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case StorageClassUniform:
|
|
||||||
case StorageClassUniformConstant:
|
|
||||||
case StorageClassPushConstant:
|
|
||||||
if (type.basetype == SPIRType::Struct)
|
|
||||||
{
|
|
||||||
bool ssbo = has_decoration(type.self, DecorationBufferBlock);
|
|
||||||
if (ssbo)
|
|
||||||
{
|
|
||||||
bool readonly = flags.get(DecorationNonWritable);
|
|
||||||
addr_space = readonly ? "const device" : "device";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
addr_space = "constant";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StorageClassFunction:
|
|
||||||
case StorageClassGeneric:
|
|
||||||
// No address space for plain values.
|
|
||||||
addr_space = type.pointer ? "thread" : "";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StorageClassInput:
|
|
||||||
if (get_execution_model() == ExecutionModelTessellationControl && argument.basevariable == stage_in_ptr_var_id)
|
|
||||||
addr_space = "threadgroup";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StorageClassOutput:
|
|
||||||
if (capture_output_to_buffer)
|
|
||||||
addr_space = "device";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addr_space)
|
|
||||||
addr_space = "thread";
|
|
||||||
|
|
||||||
return join(flags.get(DecorationVolatile) || flags.get(DecorationCoherent) ? "volatile " : "", addr_space);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id)
|
string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bool argument)
|
||||||
{
|
{
|
||||||
// This can be called for variable pointer contexts as well, so be very careful about which method we choose.
|
// This can be called for variable pointer contexts as well, so be very careful about which method we choose.
|
||||||
Bitset flags;
|
Bitset flags;
|
||||||
if (ir.ids[id].get_type() == TypeVariable && type.basetype == SPIRType::Struct &&
|
auto *var = maybe_get<SPIRVariable>(id);
|
||||||
|
if (var && type.basetype == SPIRType::Struct &&
|
||||||
(has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock)))
|
(has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock)))
|
||||||
flags = get_buffer_block_flags(id);
|
flags = get_buffer_block_flags(id);
|
||||||
else
|
else
|
||||||
@ -6663,8 +6598,16 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case StorageClassStorageBuffer:
|
case StorageClassStorageBuffer:
|
||||||
addr_space = flags.get(DecorationNonWritable) ? "const device" : "device";
|
{
|
||||||
|
// For arguments from variable pointers, we use the write count deduction, so
|
||||||
|
// we should not assume any constness here. Only for global SSBOs.
|
||||||
|
bool readonly = false;
|
||||||
|
if (!var || has_decoration(type.self, DecorationBlock))
|
||||||
|
readonly = flags.get(DecorationNonWritable);
|
||||||
|
|
||||||
|
addr_space = readonly ? "const device" : "device";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case StorageClassUniform:
|
case StorageClassUniform:
|
||||||
case StorageClassUniformConstant:
|
case StorageClassUniformConstant:
|
||||||
@ -6677,14 +6620,18 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id)
|
|||||||
else
|
else
|
||||||
addr_space = "constant";
|
addr_space = "constant";
|
||||||
}
|
}
|
||||||
else
|
else if (!argument)
|
||||||
addr_space = "constant";
|
addr_space = "constant";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StorageClassFunction:
|
case StorageClassFunction:
|
||||||
case StorageClassGeneric:
|
case StorageClassGeneric:
|
||||||
// No address space for plain values.
|
break;
|
||||||
addr_space = type.pointer ? "thread" : "";
|
|
||||||
|
case StorageClassInput:
|
||||||
|
if (get_execution_model() == ExecutionModelTessellationControl && var &&
|
||||||
|
var->basevariable == stage_in_ptr_var_id)
|
||||||
|
addr_space = "threadgroup";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StorageClassOutput:
|
case StorageClassOutput:
|
||||||
@ -6697,7 +6644,8 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!addr_space)
|
if (!addr_space)
|
||||||
addr_space = "thread";
|
// No address space for plain values.
|
||||||
|
addr_space = type.pointer || (argument && type.basetype == SPIRType::ControlPointArray) ? "thread" : "";
|
||||||
|
|
||||||
return join(flags.get(DecorationVolatile) || flags.get(DecorationCoherent) ? "volatile " : "", addr_space);
|
return join(flags.get(DecorationVolatile) || flags.get(DecorationCoherent) ? "volatile " : "", addr_space);
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ protected:
|
|||||||
void ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t index);
|
void ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t index);
|
||||||
bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const;
|
bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const;
|
||||||
std::string get_argument_address_space(const SPIRVariable &argument);
|
std::string get_argument_address_space(const SPIRVariable &argument);
|
||||||
std::string get_type_address_space(const SPIRType &type, uint32_t id);
|
std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false);
|
||||||
const char *to_restrict(uint32_t id, bool space = true);
|
const char *to_restrict(uint32_t id, bool space = true);
|
||||||
SPIRType &get_stage_in_struct_type();
|
SPIRType &get_stage_in_struct_type();
|
||||||
SPIRType &get_stage_out_struct_type();
|
SPIRType &get_stage_out_struct_type();
|
||||||
|
Loading…
Reference in New Issue
Block a user