Be more precise in usage of pointer/array mixing.
This commit is contained in:
Родитель
cfd1618e31
Коммит
71fe651e43
|
@ -5445,23 +5445,55 @@ void Compiler::analyze_interlocked_resource_usage()
|
|||
}
|
||||
|
||||
bool Compiler::type_is_array_of_pointers(const SPIRType &type) const
|
||||
{
|
||||
if (!type_is_top_level_array(type))
|
||||
return false;
|
||||
|
||||
// BDA types must have parent type hierarchy.
|
||||
if (!type.parent_type)
|
||||
return false;
|
||||
|
||||
// Punch through all array layers.
|
||||
auto *parent = &get<SPIRType>(type.parent_type);
|
||||
while (type_is_top_level_array(*parent))
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
return type_is_top_level_pointer(*parent);
|
||||
}
|
||||
|
||||
bool Compiler::type_is_top_level_pointer(const SPIRType &type) const
|
||||
{
|
||||
if (!type.pointer)
|
||||
return false;
|
||||
|
||||
// If parent type has same pointer depth, we must have an array of pointers.
|
||||
return type.pointer_depth == get<SPIRType>(type.parent_type).pointer_depth;
|
||||
// Function pointers, should not be hit by valid SPIR-V.
|
||||
// Parent type will be SPIRFunction instead.
|
||||
if (type.basetype == SPIRType::Unknown)
|
||||
return false;
|
||||
|
||||
// Some types are synthesized in-place without complete type hierarchy and might not have parent types,
|
||||
// but these types are never array-of-pointer or any complicated BDA type, infer reasonable defaults.
|
||||
if (type.parent_type)
|
||||
return type.pointer_depth > get<SPIRType>(type.parent_type).pointer_depth;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::type_is_top_level_physical_pointer(const SPIRType &type) const
|
||||
{
|
||||
return type.pointer && type.storage == StorageClassPhysicalStorageBuffer &&
|
||||
type.pointer_depth > get<SPIRType>(type.parent_type).pointer_depth;
|
||||
return type_is_top_level_pointer(type) && type.storage == StorageClassPhysicalStorageBuffer;
|
||||
}
|
||||
|
||||
bool Compiler::type_is_top_level_array(const SPIRType &type) const
|
||||
{
|
||||
return !type.array.empty() && type.array.size() > get<SPIRType>(type.parent_type).array.size();
|
||||
if (type.array.empty())
|
||||
return false;
|
||||
|
||||
// If we have pointer and array, we infer pointer-to-array as it's the only meaningful thing outside BDA.
|
||||
if (type.parent_type)
|
||||
return type.array.size() > get<SPIRType>(type.parent_type).array.size();
|
||||
else
|
||||
return !type.pointer;
|
||||
}
|
||||
|
||||
bool Compiler::flush_phi_required(BlockID from, BlockID to) const
|
||||
|
|
|
@ -1145,6 +1145,7 @@ protected:
|
|||
|
||||
bool type_is_array_of_pointers(const SPIRType &type) const;
|
||||
bool type_is_top_level_physical_pointer(const SPIRType &type) const;
|
||||
bool type_is_top_level_pointer(const SPIRType &type) const;
|
||||
bool type_is_top_level_array(const SPIRType &type) const;
|
||||
bool type_is_block_like(const SPIRType &type) const;
|
||||
bool type_is_opaque_value(const SPIRType &type) const;
|
||||
|
|
|
@ -14550,7 +14550,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member)
|
|||
string type_name;
|
||||
|
||||
// Pointer?
|
||||
if (type.pointer)
|
||||
if (type_is_top_level_pointer(type) || type_is_array_of_pointers(type))
|
||||
{
|
||||
assert(type.pointer_depth > 0);
|
||||
|
||||
|
@ -14578,7 +14578,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member)
|
|||
// the C-style nesting works right.
|
||||
// FIXME: This is somewhat of a hack.
|
||||
bool old_is_using_builtin_array = is_using_builtin_array;
|
||||
if (type.storage == StorageClassPhysicalStorageBuffer)
|
||||
if (type_is_top_level_physical_pointer(type))
|
||||
is_using_builtin_array = false;
|
||||
|
||||
type_name = join(type_address_space, " ", type_to_glsl(*p_parent_type, id));
|
||||
|
|
|
@ -292,7 +292,7 @@ bool CompilerReflection::type_is_reference(const SPIRType &type) const
|
|||
{
|
||||
// Physical pointers and arrays of physical pointers need to refer to the pointee's type.
|
||||
return type_is_top_level_physical_pointer(type) ||
|
||||
(!type.array.empty() && type_is_top_level_physical_pointer(get<SPIRType>(type.parent_type)));
|
||||
(type_is_array_of_pointers(type) && type.storage == StorageClassPhysicalStorageBuffer);
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_types()
|
||||
|
|
Загрузка…
Ссылка в новой задаче