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.03k stars 559 forks source link

GLSL: Incorrect code generated for certain types of BDA usage #2260

Closed doitsujin closed 8 months ago

doitsujin commented 8 months ago

Hello,

when using buffer reference types that contain structs, while also using the same structs directly, spirv-cross seems to get confused and emits multiple conflicting type declarations. As a result, glslang fails to compile the returned code with error messages like:

ERROR: a.mesh:295: '' :  syntax error, unexpected LEFT_BRACE, expecting COMMA or SEMICOLON
ERROR: 1 compilation errors.  No code generated.

As an example, one of my GLSL shaders contains the following declaration:

struct InstanceNode {
  uint32_t        nodeIndex;
  uint32_t        flags;
  uint32_t        dirtyFrameId;
  uint32_t        updateFrameId;
  uint64_t        geometryBuffer;
  uint64_t        animationBuffer;
  uint64_t        propertyBuffer;
  uint64_t        assetListBuffer;
};

layout(buffer_reference, buffer_reference_align = 16, scalar)
readonly buffer InstanceNodeBufferIn {
  InstanceNode    nodes[];
};

From the compiled SPIR-V binary (attached below), spirv-cross turns that into this:

struct _921
{
    uint nodeIndex;
    uint flags;
    uint dirtyFrameId;
    uint updateFrameId;
    uint64_t geometryBuffer;
    uint64_t animationBuffer;
    uint64_t propertyBuffer;
    uint64_t assetListBuffer;
};

layout(buffer_reference) buffer _921;

layout(buffer_reference, buffer_reference_align = 16, std430) readonly buffer InstanceNodeBufferIn
{
    _921 nodes[];
};

layout(buffer_reference, std430) buffer _921
{
    uint nodeIndex;
    uint flags;
    uint dirtyFrameId;
    uint updateFrameId;
    uint64_t geometryBuffer;
    uint64_t animationBuffer;
    uint64_t propertyBuffer;
    uint64_t assetListBuffer;
};

Note that InstanceNodeBufferIn is supposed to contain an array of plain structs, rather than an array of buffer references.

Here's a mesh shader that reproduces the issue (zipped, because github restricts file extensions): ms_material.zip

HansKristian-Work commented 8 months ago

Fixed on main.