Be more precise in usage of pointer/array mixing.
This commit is contained in:
parent
cfd1618e31
commit
71fe651e43
@ -5445,23 +5445,55 @@ void Compiler::analyze_interlocked_resource_usage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Compiler::type_is_array_of_pointers(const SPIRType &type) const
|
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)
|
if (!type.pointer)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If parent type has same pointer depth, we must have an array of pointers.
|
// Function pointers, should not be hit by valid SPIR-V.
|
||||||
return type.pointer_depth == get<SPIRType>(type.parent_type).pointer_depth;
|
// 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
|
bool Compiler::type_is_top_level_physical_pointer(const SPIRType &type) const
|
||||||
{
|
{
|
||||||
return type.pointer && type.storage == StorageClassPhysicalStorageBuffer &&
|
return type_is_top_level_pointer(type) && type.storage == StorageClassPhysicalStorageBuffer;
|
||||||
type.pointer_depth > get<SPIRType>(type.parent_type).pointer_depth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compiler::type_is_top_level_array(const SPIRType &type) const
|
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
|
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_array_of_pointers(const SPIRType &type) const;
|
||||||
bool type_is_top_level_physical_pointer(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_top_level_array(const SPIRType &type) const;
|
||||||
bool type_is_block_like(const SPIRType &type) const;
|
bool type_is_block_like(const SPIRType &type) const;
|
||||||
bool type_is_opaque_value(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;
|
string type_name;
|
||||||
|
|
||||||
// Pointer?
|
// Pointer?
|
||||||
if (type.pointer)
|
if (type_is_top_level_pointer(type) || type_is_array_of_pointers(type))
|
||||||
{
|
{
|
||||||
assert(type.pointer_depth > 0);
|
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.
|
// the C-style nesting works right.
|
||||||
// FIXME: This is somewhat of a hack.
|
// FIXME: This is somewhat of a hack.
|
||||||
bool old_is_using_builtin_array = is_using_builtin_array;
|
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;
|
is_using_builtin_array = false;
|
||||||
|
|
||||||
type_name = join(type_address_space, " ", type_to_glsl(*p_parent_type, id));
|
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.
|
// Physical pointers and arrays of physical pointers need to refer to the pointee's type.
|
||||||
return type_is_top_level_physical_pointer(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()
|
void CompilerReflection::emit_types()
|
||||||
|
Loading…
Reference in New Issue
Block a user