protonscr

test_shader_io_mismatch seems to use xfb incorrectly

vkd3dopen
HansKristian-Work/vkd3d-proton#1938 · opened 2024-03-12 by hakzsam · updated 2024-03-12 · 3 comments · github
Hhakzsam 2024-03-12 github
d3d12: ======== test_shader_io_mismatch begin ========
d3d12: ../src/compiler/nir/nir_gather_xfb_info.c:104: add_var_xfb_outputs: Assertion `xfb->buffer_to_stream[buffer] == var->data.stream' failed.
Aborted (core dumped)
#version 450
layout(triangles) in;
layout(max_vertices = 3, points) out;

layout(xfb_buffer = 0, xfb_stride = 64, stream = 1) out gl_PerVertex
{
    layout(xfb_offset = 0) vec4 gl_Position;
};

invariant gl_Position;

layout(location = 1) in vec3 ARG[3];
layout(location = 2) in vec2 ARG_1[3];
layout(location = 3) in uvec4 ARG_2[3];
layout(location = 1, xfb_buffer = 0, xfb_stride = 64, xfb_offset = 16) out vec3 ARG_3;
layout(location = 2, xfb_buffer = 0, xfb_stride = 64, xfb_offset = 28) flat out uvec4 ARG_2_1;
layout(location = 4, xfb_buffer = 1, xfb_stride = 64, xfb_offset = 0, stream = 1) out vec2 ARG_1_1;

void main()
{
    uint _44;
    _44 = 0u;
    for (;;)
    {
        gl_Position.x = gl_in[_44].gl_Position.x;
        gl_Position.y = gl_in[_44].gl_Position.y;
        gl_Position.z = gl_in[_44].gl_Position.z;
        gl_Position.w = gl_in[_44].gl_Position.w;
        ARG_3.x = ARG[_44].x;
        ARG_3.y = ARG[_44].y;
        ARG_3.z = ARG[_44].z;
        ARG_2_1.x = ARG_2[_44].x;
        ARG_2_1.y = ARG_2[_44].y;
        ARG_2_1.z = ARG_2[_44].z;
        ARG_2_1.w = ARG_2[_44].w;
        EmitStreamVertex(int(0u));
        uint _45 = _44 + 1u;
        if (_45 == 3u)
        {
            break;
        }
        else
        {
            _44 = _45;
        }
    }
    gl_Position.x = gl_in[0u].gl_Position.x;
    gl_Position.y = gl_in[0u].gl_Position.y;
    gl_Position.z = gl_in[0u].gl_Position.z;
    gl_Position.w = gl_in[0u].gl_Position.w;
    ARG_1_1.x = ARG_1[0u].x;
    ARG_1_1.y = ARG_1[0u].y;
    EmitStreamVertex(int(1u));
}

The Vulkan spec says:

"VUID-StandaloneSpirv-Stream-04694
If any variables or block members in the output interface of the entry point being compiled are decorated with Stream, then all variables belonging to the same XfbBuffer must specify the same Stream value"

I think it's a test bug.

Ddoitsujin maintainer 2024-03-12 github

The test should be correct, this looks more like an actual xfb bug since the test deliberately declares multiple variables in different streams as SV_Position and our shader compilers don't seem to handle that. This is perfectly legal in D3D12.

Hhakzsam 2024-03-12 github

But it doesn't seem legal in VK.

Ddoitsujin maintainer 2024-03-12 github

Again, the problem is that we have multiple SV_Position variables that our compilers map to a single one. The correct fix here is to only map the one for the rasterized stream to gl_Position and keep the other ones separate, same for all other potential system values.

Nothing extracted yet.