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 0000000..4fd10f8 Binary files /dev/null and b/tests/glsl/buffer_handle_uvec2_pc.spv differ diff --git a/tests/glsl/buffer_handle_uvec2_pc.spv.yaml b/tests/glsl/buffer_handle_uvec2_pc.spv.yaml new file mode 100644 index 0000000..1d2cac3 --- /dev/null +++ b/tests/glsl/buffer_handle_uvec2_pc.spv.yaml @@ -0,0 +1,94 @@ +%YAML 1.0 +--- +all_type_descriptions: + - &td0 + id: 7 + op: 23 + type_name: + struct_member_name: "bufferId" + storage_class: 0 # UniformConstant + type_flags: 0x00000104 # VECTOR INT + decoration_flags: 0x00000000 # NONE + traits: + numeric: + scalar: { width: 32, signedness: 0 } + vector: { component_count: 2 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 0 + members: + - &td1 + id: 8 + op: 30 + type_name: "PerFrameData" + struct_member_name: + storage_class: -1 # NOT APPLICABLE + type_flags: 0x10080000 # STRUCT EXTERNAL_BLOCK + decoration_flags: 0x00000001 # BLOCK + traits: + numeric: + scalar: { width: 0, signedness: 0 } + vector: { component_count: 0 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 1 + members: + - *td0 +all_block_variables: + - &bv0 + name: "bufferId" + offset: 0 + absolute_offset: 0 + size: 8 + padded_size: 16 + decorations: 0x00000000 # NONE + numeric: + scalar: { width: 32, signedness: 0 } + vector: { component_count: 2 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 0 + members: + type_description: *td0 + - &bv1 + name: "pc" + offset: 0 + absolute_offset: 0 + size: 16 + padded_size: 16 + decorations: 0x00000000 # NONE + numeric: + scalar: { width: 0, signedness: 0 } + vector: { component_count: 0 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 1 + members: + - *bv0 + type_description: *td1 +all_descriptor_bindings: +all_interface_variables: +module: + generator: 8 # Khronos Glslang Reference Front End + entry_point_name: "main" + entry_point_id: 4 + source_language: 2 # GLSL + source_language_version: 460 + spirv_execution_model: 5 # GLCompute + shader_stage: 0x00000020 # CS + descriptor_binding_count: 0 + descriptor_bindings: + descriptor_set_count: 0 + descriptor_sets: + input_variable_count: 0, + input_variables: + output_variable_count: 0, + output_variables: + push_constant_count: 1, + push_constants: + - *bv1 # "pc" + specialization_constant_count: 0, + specialization_constants: +... diff --git a/tests/glsl/buffer_handle_uvec2_ssbo.glsl b/tests/glsl/buffer_handle_uvec2_ssbo.glsl new file mode 100644 index 0000000..a58dbc6 --- /dev/null +++ b/tests/glsl/buffer_handle_uvec2_ssbo.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(set = 0, binding = 0) buffer T1 { + uvec2 bufferId; +} ssbo; + +void main() { + VertexBuffer(ssbo.bufferId).x = 0; +} \ No newline at end of file diff --git a/tests/glsl/buffer_handle_uvec2_ssbo.spv b/tests/glsl/buffer_handle_uvec2_ssbo.spv new file mode 100644 index 0000000..2289761 Binary files /dev/null and b/tests/glsl/buffer_handle_uvec2_ssbo.spv differ diff --git a/tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml b/tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml new file mode 100644 index 0000000..66430f8 --- /dev/null +++ b/tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml @@ -0,0 +1,115 @@ +%YAML 1.0 +--- +all_type_descriptions: + - &td0 + id: 7 + op: 23 + type_name: + struct_member_name: "bufferId" + storage_class: 0 # UniformConstant + type_flags: 0x00000104 # VECTOR INT + decoration_flags: 0x00000000 # NONE + traits: + numeric: + scalar: { width: 32, signedness: 0 } + vector: { component_count: 2 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 0 + members: + - &td1 + id: 8 + op: 30 + type_name: "T1" + struct_member_name: + storage_class: -1 # NOT APPLICABLE + type_flags: 0x10080000 # STRUCT EXTERNAL_BLOCK + decoration_flags: 0x00000001 # BLOCK + traits: + numeric: + scalar: { width: 0, signedness: 0 } + vector: { component_count: 0 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 1 + members: + - *td0 +all_block_variables: + - &bv0 + name: "bufferId" + offset: 0 + absolute_offset: 0 + size: 8 + padded_size: 8 + decorations: 0x00000000 # NONE + numeric: + scalar: { width: 32, signedness: 0 } + vector: { component_count: 2 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 0 + members: + type_description: *td0 + - &bv1 + name: "ssbo" + offset: 0 + absolute_offset: 0 + size: 0 + padded_size: 0 + decorations: 0x00000000 # NONE + numeric: + scalar: { width: 0, signedness: 0 } + vector: { component_count: 0 } + matrix: { column_count: 0, row_count: 0, stride: 0 } + array: { dims_count: 0, dims: [], stride: 0 } + member_count: 1 + members: + - *bv0 + type_description: *td1 +all_descriptor_bindings: + - &db0 + spirv_id: 10 + name: "ssbo" + binding: 0 + input_attachment_index: 0 + set: 0 + decoration_flags: 0x00000000 # NONE + descriptor_type: 7 # VK_DESCRIPTOR_TYPE_STORAGE_BUFFER + resource_type: 8 # UAV + image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown + block: *bv1 # "ssbo" + array: { dims_count: 0, dims: [] } + accessed: 1 + uav_counter_id: 4294967295 + uav_counter_binding: + type_description: *td1 + word_offset: { binding: 118, set: 114 } +all_interface_variables: +module: + generator: 8 # Khronos Glslang Reference Front End + entry_point_name: "main" + entry_point_id: 4 + source_language: 2 # GLSL + source_language_version: 460 + spirv_execution_model: 5 # GLCompute + shader_stage: 0x00000020 # CS + descriptor_binding_count: 1 + descriptor_bindings: + - *db0 # "ssbo" + descriptor_set_count: 1 + descriptor_sets: + - set: 0 + binding_count: 1 + bindings: + - *db0 # "ssbo" + input_variable_count: 0, + input_variables: + output_variable_count: 0, + output_variables: + push_constant_count: 0, + push_constants: + specialization_constant_count: 0, + specialization_constants: +...