KhronosGroup / SPIRV-Reflect

SPIRV-Reflect is a lightweight library that provides a C/C++ reflection API for SPIR-V shader bytecode in Vulkan applications.
Apache License 2.0
672 stars 147 forks source link

buffer_reference through push constant causing Assert/crash in spirv-reflect #231

Closed danginsburg closed 8 months ago

danginsburg commented 10 months ago

I am trying to use spirv-reflect to find out which members are statically referenced in a push_constant containing multiple buffer_references. This code is generated from slang, but I've stripped it down to create a minimal repro:

#version 450
#extension GL_EXT_buffer_reference : require
#extension GL_ARB_enhanced_layouts : require
#extension GL_EXT_nonuniform_qualifier : require
#extension GL_KHR_shader_subgroup_arithmetic : require
layout(row_major) uniform;
layout(row_major) buffer;

struct BDAGlobals_t_0
{
    vec4 g_vTest;
    vec4 g_vTest2;
};

layout(buffer_reference, std430, buffer_reference_align = 16) readonly buffer BufferPointer_BDAGlobals_t_0_1
{
    BDAGlobals_t_0 _data;
};

struct GlobalsBDAPushConstant_t_0
{
    BufferPointer_BDAGlobals_t_0_1  g_GlobalsBDAPerStage_0[6];
};

layout(push_constant)
layout(std140) uniform _S2
{
    BufferPointer_BDAGlobals_t_0_1  g_GlobalsBDAPerStage_0[6];
} g_GlobalsBDAPushConstant_0;

struct PS_OUTPUT_0
{
    vec4 vColor_1;
};

layout(location = 0) out vec4 _S149;

void main()
{

    _S149 = g_GlobalsBDAPushConstant_0.g_GlobalsBDAPerStage_0[0]._data.g_vTest;

    return;
}

If you compile this with glslangValidator as follows (or using the attached test.psv):

> glslangValidator -V spirv_reflect_bda.glsl -S frag -o test.spv

Then try to run it through spirv-reflect in a debug build (I'm on main to 3f468129720eded0cef4077302e491036d099856):

> spirv-reflect.exe test.spv
Assertion failed: base_var != 0, file C:\Users\dang\src\SPIRV-Reflect\spirv_reflect.c, line 631

@greg-lunarg had made patches to support reflecting statically referenced members in a buffer_reference, but it appears to be breaking down on this use case.

test.zip

spencer-lunarg commented 10 months ago

this seems related to https://github.com/KhronosGroup/SPIRV-Reflect/issues/230

I added logic to prevent infinite looping, but seems that causes things to crash once someone tries to use a valid array like g_GlobalsBDAPerStage_0[6];... already started looking into a fix so can add this to it to make sure it works