MSL: Need to emit two layers of address space.

When passing down arrays of buffer pointers, the array itself needs an
address space.
This commit is contained in:
Hans-Kristian Arntzen 2019-03-15 11:29:17 +01:00
parent e47a77d596
commit af8a9ccdcb
5 changed files with 44 additions and 14 deletions

View File

@ -8,6 +8,11 @@ struct SSBO
float4 ssbo;
};
struct SSBOs
{
float4 ssbo;
};
struct Push
{
float4 push;
@ -27,7 +32,7 @@ struct spvDescriptorSetBuffer0
{
texture2d<float> uTexture [[id(2)]];
sampler uTextureSmplr [[id(3)]];
constant UBO* m_82 [[id(5)]];
constant UBO* m_90 [[id(5)]];
array<texture2d<float>, 2> uTextures [[id(6)]];
array<sampler, 2> uTexturesSmplr [[id(8)]];
};
@ -36,7 +41,8 @@ struct spvDescriptorSetBuffer1
{
array<texture2d<float>, 4> uTexture2 [[id(3)]];
device SSBO* m_60 [[id(7)]];
array<sampler, 2> uSampler [[id(8)]];
device SSBOs* ssbos [[id(8)]][2];
array<sampler, 2> uSampler [[id(10)]];
};
struct spvDescriptorSetBuffer2
@ -57,8 +63,8 @@ struct main0_in
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], constant spvDescriptorSetBuffer1& spvDescriptorSet1 [[buffer(1)]], constant spvDescriptorSetBuffer2& spvDescriptorSet2 [[buffer(2)]], constant Push& registers [[buffer(3)]])
{
main0_out out = {};
out.FragColor = (((((spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, in.vUV) + spvDescriptorSet1.uTexture2[2].sample(spvDescriptorSet1.uSampler[1], in.vUV)) + spvDescriptorSet0.uTextures[1].sample(spvDescriptorSet0.uTexturesSmplr[1], in.vUV)) + (*spvDescriptorSet1.m_60).ssbo) + registers.push) + (*spvDescriptorSet0.m_82).ubo) + spvDescriptorSet2.ubos[0]->ubo;
out.FragColor += (*spvDescriptorSet0.m_82).ubo;
out.FragColor = ((((((spvDescriptorSet0.uTexture.sample(spvDescriptorSet0.uTextureSmplr, in.vUV) + spvDescriptorSet1.uTexture2[2].sample(spvDescriptorSet1.uSampler[1], in.vUV)) + spvDescriptorSet0.uTextures[1].sample(spvDescriptorSet0.uTexturesSmplr[1], in.vUV)) + (*spvDescriptorSet1.m_60).ssbo) + spvDescriptorSet1.ssbos[0]->ssbo) + registers.push) + (*spvDescriptorSet0.m_90).ubo) + spvDescriptorSet2.ubos[0]->ubo;
out.FragColor += (*spvDescriptorSet0.m_90).ubo;
out.FragColor += (*spvDescriptorSet1.m_60).ssbo;
out.FragColor += spvDescriptorSet2.ubos[1]->ubo;
out.FragColor += registers.push;

View File

@ -10,6 +10,11 @@ struct SSBO
float4 ssbo;
};
struct SSBOs
{
float4 ssbo;
};
struct Push
{
float4 push;
@ -29,7 +34,7 @@ struct spvDescriptorSetBuffer0
{
texture2d<float> uTexture [[id(2)]];
sampler uTextureSmplr [[id(3)]];
constant UBO* v_82 [[id(5)]];
constant UBO* v_90 [[id(5)]];
array<texture2d<float>, 2> uTextures [[id(6)]];
array<sampler, 2> uTexturesSmplr [[id(8)]];
};
@ -38,7 +43,8 @@ struct spvDescriptorSetBuffer1
{
array<texture2d<float>, 4> uTexture2 [[id(3)]];
device SSBO* v_60 [[id(7)]];
array<sampler, 2> uSampler [[id(8)]];
device SSBOs* ssbos [[id(8)]][2];
array<sampler, 2> uSampler [[id(10)]];
};
struct spvDescriptorSetBuffer2
@ -56,20 +62,21 @@ struct main0_in
float2 vUV [[user(locn0)]];
};
float4 sample_in_function2(thread texture2d<float> uTexture, thread const sampler uTextureSmplr, thread float2& vUV, thread const array<texture2d<float>, 4> uTexture2, thread const array<sampler, 2> uSampler, thread const array<texture2d<float>, 2> uTextures, thread const array<sampler, 2> uTexturesSmplr, device SSBO& v_60, constant Push& registers)
float4 sample_in_function2(thread texture2d<float> uTexture, thread const sampler uTextureSmplr, thread float2& vUV, thread const array<texture2d<float>, 4> uTexture2, thread const array<sampler, 2> uSampler, thread const array<texture2d<float>, 2> uTextures, thread const array<sampler, 2> uTexturesSmplr, device SSBO& v_60, const device SSBOs* constant (&ssbos)[2], constant Push& registers)
{
float4 ret = uTexture.sample(uTextureSmplr, vUV);
ret += uTexture2[2].sample(uSampler[1], vUV);
ret += uTextures[1].sample(uTexturesSmplr[1], vUV);
ret += v_60.ssbo;
ret += ssbos[0]->ssbo;
ret += registers.push;
return ret;
}
float4 sample_in_function(thread texture2d<float> uTexture, thread const sampler uTextureSmplr, thread float2& vUV, thread const array<texture2d<float>, 4> uTexture2, thread const array<sampler, 2> uSampler, thread const array<texture2d<float>, 2> uTextures, thread const array<sampler, 2> uTexturesSmplr, device SSBO& v_60, constant Push& registers, constant UBO& v_82, constant UBOs* (&ubos)[4])
float4 sample_in_function(thread texture2d<float> uTexture, thread const sampler uTextureSmplr, thread float2& vUV, thread const array<texture2d<float>, 4> uTexture2, thread const array<sampler, 2> uSampler, thread const array<texture2d<float>, 2> uTextures, thread const array<sampler, 2> uTexturesSmplr, device SSBO& v_60, const device SSBOs* constant (&ssbos)[2], constant Push& registers, constant UBO& v_90, constant UBOs* constant (&ubos)[4])
{
float4 ret = sample_in_function2(uTexture, uTextureSmplr, vUV, uTexture2, uSampler, uTextures, uTexturesSmplr, v_60, registers);
ret += v_82.ubo;
float4 ret = sample_in_function2(uTexture, uTextureSmplr, vUV, uTexture2, uSampler, uTextures, uTexturesSmplr, v_60, ssbos, registers);
ret += v_90.ubo;
ret += ubos[0]->ubo;
return ret;
}
@ -77,8 +84,8 @@ float4 sample_in_function(thread texture2d<float> uTexture, thread const sampler
fragment main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]], constant spvDescriptorSetBuffer1& spvDescriptorSet1 [[buffer(1)]], constant spvDescriptorSetBuffer2& spvDescriptorSet2 [[buffer(2)]], constant Push& registers [[buffer(3)]])
{
main0_out out = {};
out.FragColor = sample_in_function(spvDescriptorSet0.uTexture, spvDescriptorSet0.uTextureSmplr, in.vUV, spvDescriptorSet1.uTexture2, spvDescriptorSet1.uSampler, spvDescriptorSet0.uTextures, spvDescriptorSet0.uTexturesSmplr, (*spvDescriptorSet1.v_60), registers, (*spvDescriptorSet0.v_82), spvDescriptorSet2.ubos);
out.FragColor += (*spvDescriptorSet0.v_82).ubo;
out.FragColor = sample_in_function(spvDescriptorSet0.uTexture, spvDescriptorSet0.uTextureSmplr, in.vUV, spvDescriptorSet1.uTexture2, spvDescriptorSet1.uSampler, spvDescriptorSet0.uTextures, spvDescriptorSet0.uTexturesSmplr, (*spvDescriptorSet1.v_60), spvDescriptorSet1.ssbos, registers, (*spvDescriptorSet0.v_90), spvDescriptorSet2.ubos);
out.FragColor += (*spvDescriptorSet0.v_90).ubo;
out.FragColor += (*spvDescriptorSet1.v_60).ssbo;
out.FragColor += spvDescriptorSet2.ubos[1]->ubo;
out.FragColor += registers.push;

View File

@ -22,7 +22,7 @@ struct constant_block
#endif
constant int arraySize = SPIRV_CROSS_CONSTANT_ID_0;
void doWork(device storage_block* (&storage)[2], constant constant_block* (&constants)[4], thread const array<texture2d<int>, 3> images)
void doWork(device storage_block* constant (&storage)[2], constant constant_block* constant (&constants)[4], thread const array<texture2d<int>, 3> images)
{
storage[0]->baz = uint4(constants[3]->foo);
storage[1]->quux = images[2].read(uint2(int2(constants[1]->bar))).xy;

View File

@ -15,6 +15,11 @@ layout(std430, set = 1, binding = 7) buffer SSBO
vec4 ssbo;
};
layout(std430, set = 1, binding = 8) readonly buffer SSBOs
{
vec4 ssbo;
} ssbos[2];
layout(std140, set = 2, binding = 4) uniform UBOs
{
vec4 ubo;
@ -23,7 +28,7 @@ layout(std140, set = 2, binding = 4) uniform UBOs
layout(set = 0, binding = 2) uniform sampler2D uTexture;
layout(set = 0, binding = 6) uniform sampler2D uTextures[2];
layout(set = 1, binding = 3) uniform texture2D uTexture2[4];
layout(set = 1, binding = 8) uniform sampler uSampler[2];
layout(set = 1, binding = 10) uniform sampler uSampler[2];
layout(location = 0) in vec2 vUV;
layout(location = 0) out vec4 FragColor;
@ -33,6 +38,7 @@ vec4 sample_in_function2()
ret += texture(sampler2D(uTexture2[2], uSampler[1]), vUV);
ret += texture(uTextures[1], vUV);
ret += ssbo;
ret += ssbos[0].ssbo;
ret += registers.push;
return ret;
}

View File

@ -5967,6 +5967,17 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
// Arrays of images and samplers are special cased.
if (!address_space.empty())
decl = join(address_space, " ", decl);
// An awkward case where we need to emit *more* address space declarations (yay!).
// An example is where we pass down an array of buffer pointers to leaf functions.
// It's a constant array containing pointers to constants.
// The pointer array is always constant however. E.g.
// device SSBO * constant (&array)[N].
// const device SSBO * constant (&array)[N].
// constant SSBO * constant (&array)[N].
if (storage == StorageClassUniform || storage == StorageClassStorageBuffer)
decl += " constant";
decl += " (&";
decl += to_expression(name_id);
decl += ")";