Closed sora-jp closed 3 years ago
This is because Vulkan and Direct3D have different binding models. Unfortunately, unlike for Metal, there doesn't seem to be an option to make SPIRV-Cross use SPIR-V binding numbers in HLSL. The best you can do is use CompilerHLSL::set_resource_binding_flags()
(spvc_compiler_hlsl_set_resource_binding_flags()
from C API) to turn off register
emission entirely. Perhaps we should add such an option.
Is there a way to find out the mapping from GLSL binding to HLSL register via the reflection api? Currently, the workaround I use is to compile the GLSL to SPIR-V with debug information enabled. This seems to force SPIRV-Cross to emit all buffers, even if they are unused.
Is there a way to find out the mapping from GLSL binding to HLSL register via the reflection api?
No. But, and I should've mentioned this earlier, you can control the register-binding mapping by using CompilerHLSL::add_hlsl_resource_binding()
(spvc_compiler_hlsl_add_resource_binding()
from C); then CompilerHLSL::is_hlsl_resource_binding_used()
(spvc_compiler_hlsl_is_resource_used()
from C) will tell you whether or not the shader actually uses the resource.
I'm not sure what you're doing, since I get the binding mapping. By default, HLSL output will follow SPIR-V decorations.
cbuffer _PERCAMERA : register(b1)
{
row_major float4x4 _19_MATRIX_VP : packoffset(c0);
float4 _19_CAMERA_POSITION : packoffset(c4);
};
cbuffer _PEROBJ : register(b2)
{
row_major float4x4 _25_MATRIX_M : packoffset(c0);
};
cbuffer _PERFRAME : register(b0)
{
float4 _37_Time : packoffset(c0);
};
static float4 gl_Position;
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
};
void vert_main()
{
gl_Position = mul(float4(0.0f, 0.0f, 0.0f, 1.0f), mul(_25_MATRIX_M, _19_MATRIX_VP));
}
SPIRV_Cross_Output main()
{
vert_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
return stage_output;
}
Closed as not a bug since I cannot reproduce.
When compiling Vulkan-style GLSL to SPIR-V, and then to HLSL, cbuffer indices get misaligned if a cbuffer gets optimized away in the GLSL -> SPIR-V stage.
Example GLSL (Vertex shader, fragment parts omitted for brevity):
Disassembled SPIR-V After compiling to SPIR-V, and then converting back to GLSL:
HLSL Output:
Notice how _23_25 is assigned to register b0, even though it is decorated with layout(binding = 1). I'm using Veldrid.SPIRV to interface with SPIRV-Cross from C#. They use a slightly outdated version, but I couldn't find any references to this happening anywhere, so I thought it would be best to create an issue. I can post the full code if needed, but I extracted the relevant bits only for now.