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
2k stars 555 forks source link

Dual-source blending not supported on hlsl #811

Closed zakorgy closed 5 years ago

zakorgy commented 5 years ago

I am working on a project which compiles glsl files to SPIRV binaries and later uses SPIRV-Cross to convert those to hlsl. My issue is similar to https://github.com/KhronosGroup/SPIRV-Cross/issues/516, but in this case with hlsl not with mtl. Also managed to reproduce it with one of the shaders from the repository(dual-source-blending.desktop.frag):

#version 450

layout(location = 0, index = 0) out vec4 FragColor0;
layout(location = 0, index = 1) out vec4 FragColor1;

void main()
{
        FragColor0 = vec4(1.0);
        FragColor1 = vec4(2.0);
}

After converting it with glslangValidator and SPIRV-Cross into a hlsl:

static float4 FragColor0;
static float4 FragColor1;

struct SPIRV_Cross_Output
{
    float4 FragColor0 : SV_Target0;
    float4 FragColor1 : SV_Target0;
};

void frag_main()
{
    FragColor0 = 1.0f.xxxx;
    FragColor1 = 2.0f.xxxx;
}

SPIRV_Cross_Output main()
{
    frag_main();
    SPIRV_Cross_Output stage_output;
    stage_output.FragColor0 = FragColor0;
    stage_output.FragColor1 = FragColor1;
    return stage_output;
}

I have used spirv-cross.exe --hlsl --shader-model 51 to generate the hlsl file. After loading this shader I have the following error message: error X4574: Duplicate system value semantic definition: output semantic \'SV_Target0\' and output semantic \'SV_Target0\'

This led me to that

struct SPIRV_Cross_Output
{
    float4 FragColor0 : SV_Target0;
    float4 FragColor1 : SV_Target1;
};

would be the correct output.

Also checked the SPIR-V binaries and the attributes look correct to me:

Decorate 9(FragColor0) Index 0
Decorate 9(FragColor0) Location 0
Decorate 12(FragColor1) Index 1
Decorate 12(FragColor1) Location 0
HansKristian-Work commented 5 years ago

https://docs.microsoft.com/en-us/windows/desktop/direct3d11/d3d10-graphics-programming-guide-output-merger-stage

D3D11 docs suggest that you do indeed use SV_Target0/Target1 to do dual-source blending.