KhronosGroup / SPIRV-Cross

SPIRV-Cross is a practical tool and library for performing reflection on SPIR-V and disassembling SPIR-V back to high level languages.
Apache License 2.0
2.02k stars 558 forks source link

Binding decoration question #1191

Closed QuantumDeveloper closed 4 years ago

QuantumDeveloper commented 4 years ago

Hi. I am playing now with your tool and I got a question regarding bindings decoration.

For example, I have something like that:

sampler sampleType : register(s0);
cbuffer Matrices : register(b0)
{
    matrix wvp;
    float4 fillColor;
};

In both cases I will receive 0 as Binding Decoration. So, could you please say does I understand it correctly that I could assign the same Binding ID to the different VkDescriptorSetLayoutBinding but mentioning descriptorType and it will work fine?

HansKristian-Work commented 4 years ago

The binding models of Vulkan and D3D (11 I assume) are quite different. Binding 0 (for a given descriptor set) can only hold one type of descriptor in Vulkan, whereas in GL and D3D11 the bindings are split based on resource type. Typically, you will have a remapping scheme in your HLSL-to-SPIR-V compiler which assigns bindings which can work on Vulkan. SPIRV-Cross will reflect whatever is in the shader module though.

QuantumDeveloper commented 4 years ago

Could you please say how to achieve this? Should I write some custom remapper or this functionality already exists?

HansKristian-Work commented 4 years ago

See glslang's --shift-*-binding functionality.

QuantumDeveloper commented 4 years ago

Do you mean this? If yes, then could you say how to deal with it in spirv_cross_c, because I am using C# bindings to C wrapper of Cross lib.

QuantumDeveloper commented 4 years ago

@HansKristian-Work does this actually possible to achieve with spirv-cross-c? Sorry for a lot of questions, but currently I dont understand how to deal with this issue.

Update I made preprocess output and even in that output I see same binding id for different targets, which is strange, because Vulkan is not supporting this

HansKristian-Work commented 4 years ago

Do you have a concrete repro case (source files, commands to glslang, SPIR-V, etc)? The only thing relevant for SPIRV-Cross here is going to be get_decoration(..., DecorationBinding).

QuantumDeveloper commented 4 years ago

Yeah, I have sample where I have register(s0) for sampler and register(t0) for texture and this will give me 0 binding id for both cases.

So, if its not related to spirv-cross, maybe I need to apply some compile options or something like that? On 1 Nov 2019, 16:08 +0200, Hans-Kristian Arntzen notifications@github.com, wrote:

Do you have a concrete repro case? The only thing relevant for SPIRV-Cross here is going to be get_decoration(..., DecorationBinding). — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

HansKristian-Work commented 4 years ago

Well, here's an example:

cbuffer Buf : register(b0)
{
    float4 v;
};

Texture2D Tex : register(t0);
SamplerState Samp : register(s0);

float4 main(float2 UV : TEXCOORD0) : SV_Target
{
    return v * Tex.Sample(Samp, UV);
}
glslangValidator -D -H -V -o /tmp/test.spv /tmp/test.frag -e main --shift-cbuffer-binding 8 --shift-texture-binding 16 --shift-sampler-binding 24

then you get in Vulkan GLSL:

#version 450

layout(set = 0, binding = 8, std140) uniform Buf
{
    vec4 v;
} _16;

layout(set = 0, binding = 16) uniform texture2D Tex;
layout(set = 0, binding = 24) uniform sampler Samp;

layout(location = 0) in vec2 UV;
layout(location = 0) out vec4 _entryPointOutput;

vec4 _main(vec2 UV_1)
{
    return _16.v * texture(sampler2D(Tex, Samp), UV_1);
}

void main()
{
    vec2 UV_1 = UV;
    vec2 param = UV_1;
    _entryPointOutput = _main(param);
}
QuantumDeveloper commented 4 years ago

@HansKristian-Work Yeah, I also found shifting functionality in ShaderC sources but one here confusing me: we manually shift bindings which could lead also to not correct results in case if we will have for ex., register(t0) and register(t8). So, we could here have an intersection of binding ids. This is especially actual for case of automatic processing when you dont know exactly what is inside each shader. Another option though is not to assign registers at all, then seems binding ids works correctly, but this looks like a limitation as for me. What do you think?

HansKristian-Work commented 4 years ago

You'll need to use strides large enough that there is no overlap, up to you how you ensure that. This really isn't a SPIRV-Cross issue though, this is a shader toolchain thing.

QuantumDeveloper commented 4 years ago

OK, thanks a lot for clarification and your answers