From 7cb5c714ecdfaf07b67517aea79cc821accb0fd8 Mon Sep 17 00:00:00 2001 From: spencer-lunarg Date: Sun, 7 Apr 2024 13:54:45 +0900 Subject: [PATCH] Fix asserting from uvec2 buffer reference bitcast --- spirv_reflect.c | 20 ++-- tests/glsl/buffer_handle_uvec2_pc.glsl | 16 +++ tests/glsl/buffer_handle_uvec2_pc.spv | Bin 0 -> 768 bytes tests/glsl/buffer_handle_uvec2_pc.spv.yaml | 94 +++++++++++++++ tests/glsl/buffer_handle_uvec2_ssbo.glsl | 16 +++ tests/glsl/buffer_handle_uvec2_ssbo.spv | Bin 0 -> 836 bytes tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml | 115 +++++++++++++++++++ 7 files changed, 254 insertions(+), 7 deletions(-) create mode 100644 tests/glsl/buffer_handle_uvec2_pc.glsl create mode 100644 tests/glsl/buffer_handle_uvec2_pc.spv create mode 100644 tests/glsl/buffer_handle_uvec2_pc.spv.yaml create mode 100644 tests/glsl/buffer_handle_uvec2_ssbo.glsl create mode 100644 tests/glsl/buffer_handle_uvec2_ssbo.spv create mode 100644 tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml diff --git a/spirv_reflect.c b/spirv_reflect.c index 92f8b33..45b5fce 100644 --- a/spirv_reflect.c +++ b/spirv_reflect.c @@ -529,8 +529,8 @@ static SpvReflectTypeDescription* FindType(SpvReflectShaderModule* p_module, uin } static SpvReflectPrvAccessChain* FindAccessChain(SpvReflectPrvParser* p_parser, uint32_t id) { - uint32_t ac_cnt = p_parser->access_chain_count; - for (uint32_t i = 0; i < ac_cnt; i++) { + const uint32_t ac_count = p_parser->access_chain_count; + for (uint32_t i = 0; i < ac_count; i++) { if (p_parser->access_chains[i].result_id == id) { return &p_parser->access_chains[i]; } @@ -538,8 +538,10 @@ static SpvReflectPrvAccessChain* FindAccessChain(SpvReflectPrvParser* p_parser, return 0; } -static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* ac) { - uint32_t base_id = ac->base_id; +// Access Chains mostly have their Base ID pointed directly to a OpVariable, but sometimes +// it will be through a load and this funciton handles the edge cases how to find that +static uint32_t FindAccessChainBaseVariable(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) { + uint32_t base_id = p_access_chain->base_id; SpvReflectPrvNode* base_node = FindNode(p_parser, base_id); // TODO - This is just a band-aid to fix crashes. // Need to understand why here and hopefully remove @@ -555,6 +557,10 @@ static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessCha case SpvOpFunctionParameter: { UNCHECKED_READU32(p_parser, base_node->word_offset + 2, base_id); } break; + case SpvOpBitcast: + // This can be caused by something like GL_EXT_buffer_reference_uvec2 trying to load a pointer. + // We currently call from a push constant, so no way to have a reference loop back into the PC block + return 0; default: { assert(false); } break; @@ -573,8 +579,8 @@ static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessCha return base_id; } -static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* ac) { - uint32_t base_id = ac->base_id; +static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) { + uint32_t base_id = p_access_chain->base_id; SpvReflectPrvNode* base_node = FindNode(p_parser, base_id); assert(base_node->op == SpvOpLoad); UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id); @@ -3888,7 +3894,7 @@ static SpvReflectResult ParsePushConstantBlocks(SpvReflectPrvParser* p_parser, S for (uint32_t access_chain_index = 0; access_chain_index < p_parser->access_chain_count; ++access_chain_index) { SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]); // Skip any access chains that aren't touching this push constant block - if (p_push_constant->spirv_id != FindBaseId(p_parser, p_access_chain)) { + if (p_push_constant->spirv_id != FindAccessChainBaseVariable(p_parser, p_access_chain)) { continue; } SpvReflectBlockVariable* p_var = diff --git a/tests/glsl/buffer_handle_uvec2_pc.glsl b/tests/glsl/buffer_handle_uvec2_pc.glsl new file mode 100644 index 0000000..2e589eb --- /dev/null +++ b/tests/glsl/buffer_handle_uvec2_pc.glsl @@ -0,0 +1,16 @@ +#version 460 +#extension GL_EXT_buffer_reference2 : require +#extension GL_EXT_buffer_reference_uvec2 : require + +layout(buffer_reference) buffer VertexBuffer; +layout(buffer_reference, buffer_reference_align = 16, std430) buffer VertexBuffer { + int x; +}; + +layout(push_constant, std430) uniform PerFrameData { + uvec2 bufferId; +} pc; + +void main() { + VertexBuffer(pc.bufferId).x = 0; +} \ No newline at end of file diff --git a/tests/glsl/buffer_handle_uvec2_pc.spv b/tests/glsl/buffer_handle_uvec2_pc.spv new file mode 100644 index 0000000000000000000000000000000000000000..4fd10f8f876536f6f6986aedffeb1fc52a82684e GIT binary patch literal 768 zcmZ`%OG^S_6ur(kTT4 z&|@#x@U-KzuY0r|?3#rh`?THYmaYy$Jv)zI4r08LH&SLm6PcVrsl`ef=tGWoGd|B> zjFV%$j3@OLYHY(*FvEpi1t=Tv@o^)Lxtpdxxhi5AXo543jn6yCu~!bd3M7CX1|opYYC>Yt6|Vj>|a#>p_ia@ zcCU*)cx86(oS8FcW?ds*Pm9FFl#Em)JSB+(5uyLw6v;_e+IL<1ws~*AJiYlt*BROV zbmBRW%I?hu1LdK{jB5U;qDpt<_&ya(Nd^6_R=d^kr~Ss!@jmgq81e-@Y8NDlpGX4s z>j3hwL`zLuLl@8sm*eZMye<5aLiS9w!4zY1R<65Niv@yuaOFxi`@ z9y+nK9{06$-<>EI>eO^h{-WP9pBVXNJn3ubX=tp1o+;d`FrF>M_&@@TwcA>sSQWV} z{2GjNp6Qso5@RnDz6y)M_H@h~5BclxjM;A&y^HYQ_y(xMIYWLT!ikYr)^*IEU{B7* z|AmLU`~czibBQN4^038R=cuG!LF4a;sk@;ua@ZeZ1Q_SL0LGYiYO($oTb;uG00+lf A