Merge pull request #1303 from KhronosGroup/fix-1302
MSL: Fix access chain for deep struct hierarchy on array of buffers.
This commit is contained in:
commit
e58e8d5dbe
@ -0,0 +1,32 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
float4 v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UBO
|
||||||
|
{
|
||||||
|
Foo foo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spvDescriptorSetBuffer0
|
||||||
|
{
|
||||||
|
constant UBO* ubos [[id(0)]][2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 FragColor [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0(constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
out.FragColor = spvDescriptorSet0.ubos[1]->foo.v;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
float4 v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UBO
|
||||||
|
{
|
||||||
|
Foo foo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 FragColor [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0(constant UBO* ubos_0 [[buffer(0)]], constant UBO* ubos_1 [[buffer(1)]])
|
||||||
|
{
|
||||||
|
constant UBO* ubos[] =
|
||||||
|
{
|
||||||
|
ubos_0,
|
||||||
|
ubos_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
main0_out out = {};
|
||||||
|
out.FragColor = ubos[1]->foo.v;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
vec4 v;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
Foo foo;
|
||||||
|
} ubos[2];
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = ubos[1].foo.v;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
struct Foo
|
||||||
|
{
|
||||||
|
vec4 v;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) uniform UBO
|
||||||
|
{
|
||||||
|
Foo foo;
|
||||||
|
} ubos[2];
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = ubos[1].foo.v;
|
||||||
|
}
|
@ -10505,7 +10505,12 @@ string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uin
|
|||||||
|
|
||||||
if (var)
|
if (var)
|
||||||
{
|
{
|
||||||
bool is_buffer_variable = var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer;
|
// Only allow -> dereference for block types. This is so we get expressions like
|
||||||
|
// buffer[i]->first_member.second_member, rather than buffer[i]->first->second.
|
||||||
|
bool is_block = has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock);
|
||||||
|
|
||||||
|
bool is_buffer_variable =
|
||||||
|
is_block && (var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer);
|
||||||
declared_as_pointer = is_buffer_variable && is_array(get<SPIRType>(var->basetype));
|
declared_as_pointer = is_buffer_variable && is_array(get<SPIRType>(var->basetype));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user