SPIRV-Cross/reference/shaders-msl/frag/argument-buffers.msl2.argument.frag
Hans-Kristian Arntzen 5b952d2cbf MSL: Rethink how opaque descriptors are passed to leaf functions.
We were passing arrays by value which the compiler fails to optimize,
causing abyssal performance. To fix this, we need to consider that
descriptors can be in constant or const device address spaces.

Also, lone descriptors are passed by value, so we explicitly remove address
space qualifiers.

One failure case is when shader passes a texture/sampler array as an
argument. It's all UniformConstant in SPIR-V, but in MSL it might be
thread, const device or constant, so that won't work ...
Global variable use works fine though, and that should cover 99.9999999%
of use cases.
2022-01-18 14:40:52 +01:00

97 lines
3.1 KiB
GLSL

#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct SSBO
{
float4 ssbo;
};
struct SSBOs
{
float4 ssbo;
};
struct Push
{
float4 push;
};
struct UBO
{
float4 ubo;
};
struct UBOs
{
float4 ubo;
};
struct spvDescriptorSetBuffer0
{
texture2d<float> uTexture [[id(0)]];
sampler uTextureSmplr [[id(1)]];
array<texture2d<float>, 2> uTextures [[id(2)]];
array<sampler, 2> uTexturesSmplr [[id(4)]];
constant UBO* v_90 [[id(6)]];
};
struct spvDescriptorSetBuffer1
{
array<texture2d<float>, 4> uTexture2 [[id(0)]];
array<sampler, 2> uSampler [[id(4)]];
device SSBO* v_60 [[id(6)]];
const device SSBOs* ssbos [[id(7)]][2];
};
struct spvDescriptorSetBuffer2
{
constant UBOs* ubos [[id(0)]][4];
};
struct main0_out
{
float4 FragColor [[color(0)]];
};
struct main0_in
{
float2 vUV [[user(locn0)]];
};
static inline __attribute__((always_inline))
float4 sample_in_function2(texture2d<float> uTexture, sampler uTextureSmplr, thread float2& vUV, constant array<texture2d<float>, 4>& uTexture2, constant array<sampler, 2>& uSampler, constant array<texture2d<float>, 2>& uTextures, constant 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;
}
static inline __attribute__((always_inline))
float4 sample_in_function(texture2d<float> uTexture, sampler uTextureSmplr, thread float2& vUV, constant array<texture2d<float>, 4>& uTexture2, constant array<sampler, 2>& uSampler, constant array<texture2d<float>, 2>& uTextures, constant 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, ssbos, registers);
ret += v_90.ubo;
ret += ubos[0]->ubo;
return ret;
}
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), 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;
return out;
}