KhronosGroup / glslang

Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.
Other
2.9k stars 815 forks source link

Using a buffer_reference buffer within a struct within a SSBO causes invalid const errors #3608

Open spnda opened 1 month ago

spnda commented 1 month ago

These are snippets from my local project where I experience this issue.

layout(buffer_reference, scalar) restrict readonly buffer UvBuffer {
    vec2 uvs[];
};

struct PrimitiveDraw {
    ...
    UvBuffer uvBuffers[maxUvSets]; // I use an array here, but it doesn't actually matter. Same behaviour with a single buffer.
};

layout(set = 1, binding = 4, scalar) restrict readonly buffer PrimitiveDrawBuffer {
    PrimitiveDraw primitives[];
};

void main() {
    const PrimitiveDraw draw = primitives[gl_DrawID]; // This is line 39 with the error
}

When I remove that array of buffer references the code compiles fine, but just adding that array (not using it) gives this:

ERROR: shaders/shadow_map.task.glsl:39: 'qualifier' : variables with reference type can't have qualifier 'const' 
ERROR: shaders/shadow_map.task.glsl:39: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated.

Removing the const qualifier does fix the error, but I don't think that is intended behaviour. How can a reference not be const, and why should using a buffer_reference have any effect on that? I'm using the glslangValidator as a compiler from the latest 1.3.283 SDK.

arcady-lunarg commented 1 month ago

Currently the buffer reference extension spec does not allow a const qualifier to be applied to a reference type, and my interpretation is that it prohibits your usage. Maybe @jeffbolznv can clarify.

jeffbolznv commented 1 month ago

I don't remember this, but found some history. This was added in https://github.com/KhronosGroup/GLSL/pull/54. There's an issue that says "The constant qualifier is disallowed because OpConstant doesn't support generating pointer constants (but note that reference types can participate in constant expressions)." So I guess this is working as intended?

spnda commented 1 month ago

I don't remember this, but found some history. This was added in KhronosGroup/GLSL#54. There's an issue that says "The constant qualifier is disallowed because OpConstant doesn't support generating pointer constants (but note that reference types can participate in constant expressions)." So I guess this is working as intended?

But isn't OpConstant used for declaring variables with an immediate value? Meaning something like OpConstant %6 1, or OpConstant %13 5? As far as I know, GLSL's const within functions is used only to indicate that a variable is immutable, which does not have anything to do with OpConstant and I don't think SPIR-V cares about mutability, either. So that seems like an invalid argument for this to me. However, I might be entirely mistaken, so please correct me if that's the case.

jeffbolznv commented 1 month ago

Like I said, I don't really remember the details. I think glslang tries to emit OpConstant for const variabes, which may be leftover from pre-4.20 when const was required to be initialized with a constant expression.