Skip to content

Commit

Permalink
Fix asserting from uvec2 buffer reference bitcast
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed Apr 7, 2024
1 parent e4b225a commit 7cb5c71
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 7 deletions.
20 changes: 13 additions & 7 deletions spirv_reflect.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,17 +529,19 @@ 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];
}
}
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
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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 =
Expand Down
16 changes: 16 additions & 0 deletions tests/glsl/buffer_handle_uvec2_pc.glsl
Original file line number Diff line number Diff line change
@@ -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;
}
Binary file added tests/glsl/buffer_handle_uvec2_pc.spv
Binary file not shown.
94 changes: 94 additions & 0 deletions tests/glsl/buffer_handle_uvec2_pc.spv.yaml
Original file line number Diff line number Diff line change
@@ -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:
...
16 changes: 16 additions & 0 deletions tests/glsl/buffer_handle_uvec2_ssbo.glsl
Original file line number Diff line number Diff line change
@@ -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;
}
Binary file added tests/glsl/buffer_handle_uvec2_ssbo.spv
Binary file not shown.
115 changes: 115 additions & 0 deletions tests/glsl/buffer_handle_uvec2_ssbo.spv.yaml
Original file line number Diff line number Diff line change
@@ -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:
...

0 comments on commit 7cb5c71

Please sign in to comment.