Skip to content

Commit b50ffbd

Browse files
Fix asserting from uvec2 buffer reference bitcast (#259)
1 parent 806c5d8 commit b50ffbd

7 files changed

+254
-7
lines changed

spirv_reflect.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,17 +529,19 @@ static SpvReflectTypeDescription* FindType(SpvReflectShaderModule* p_module, uin
529529
}
530530

531531
static SpvReflectPrvAccessChain* FindAccessChain(SpvReflectPrvParser* p_parser, uint32_t id) {
532-
uint32_t ac_cnt = p_parser->access_chain_count;
533-
for (uint32_t i = 0; i < ac_cnt; i++) {
532+
const uint32_t ac_count = p_parser->access_chain_count;
533+
for (uint32_t i = 0; i < ac_count; i++) {
534534
if (p_parser->access_chains[i].result_id == id) {
535535
return &p_parser->access_chains[i];
536536
}
537537
}
538538
return 0;
539539
}
540540

541-
static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* ac) {
542-
uint32_t base_id = ac->base_id;
541+
// Access Chains mostly have their Base ID pointed directly to a OpVariable, but sometimes
542+
// it will be through a load and this funciton handles the edge cases how to find that
543+
static uint32_t FindAccessChainBaseVariable(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) {
544+
uint32_t base_id = p_access_chain->base_id;
543545
SpvReflectPrvNode* base_node = FindNode(p_parser, base_id);
544546
// TODO - This is just a band-aid to fix crashes.
545547
// Need to understand why here and hopefully remove
@@ -555,6 +557,10 @@ static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessCha
555557
case SpvOpFunctionParameter: {
556558
UNCHECKED_READU32(p_parser, base_node->word_offset + 2, base_id);
557559
} break;
560+
case SpvOpBitcast:
561+
// This can be caused by something like GL_EXT_buffer_reference_uvec2 trying to load a pointer.
562+
// We currently call from a push constant, so no way to have a reference loop back into the PC block
563+
return 0;
558564
default: {
559565
assert(false);
560566
} break;
@@ -573,8 +579,8 @@ static uint32_t FindBaseId(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessCha
573579
return base_id;
574580
}
575581

576-
static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* ac) {
577-
uint32_t base_id = ac->base_id;
582+
static SpvReflectBlockVariable* GetRefBlkVar(SpvReflectPrvParser* p_parser, SpvReflectPrvAccessChain* p_access_chain) {
583+
uint32_t base_id = p_access_chain->base_id;
578584
SpvReflectPrvNode* base_node = FindNode(p_parser, base_id);
579585
assert(base_node->op == SpvOpLoad);
580586
UNCHECKED_READU32(p_parser, base_node->word_offset + 3, base_id);
@@ -3888,7 +3894,7 @@ static SpvReflectResult ParsePushConstantBlocks(SpvReflectPrvParser* p_parser, S
38883894
for (uint32_t access_chain_index = 0; access_chain_index < p_parser->access_chain_count; ++access_chain_index) {
38893895
SpvReflectPrvAccessChain* p_access_chain = &(p_parser->access_chains[access_chain_index]);
38903896
// Skip any access chains that aren't touching this push constant block
3891-
if (p_push_constant->spirv_id != FindBaseId(p_parser, p_access_chain)) {
3897+
if (p_push_constant->spirv_id != FindAccessChainBaseVariable(p_parser, p_access_chain)) {
38923898
continue;
38933899
}
38943900
SpvReflectBlockVariable* p_var =
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#version 460
2+
#extension GL_EXT_buffer_reference2 : require
3+
#extension GL_EXT_buffer_reference_uvec2 : require
4+
5+
layout(buffer_reference) buffer VertexBuffer;
6+
layout(buffer_reference, buffer_reference_align = 16, std430) buffer VertexBuffer {
7+
int x;
8+
};
9+
10+
layout(push_constant, std430) uniform PerFrameData {
11+
uvec2 bufferId;
12+
} pc;
13+
14+
void main() {
15+
VertexBuffer(pc.bufferId).x = 0;
16+
}
768 Bytes
Binary file not shown.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
%YAML 1.0
2+
---
3+
all_type_descriptions:
4+
- &td0
5+
id: 7
6+
op: 23
7+
type_name:
8+
struct_member_name: "bufferId"
9+
storage_class: 0 # UniformConstant
10+
type_flags: 0x00000104 # VECTOR INT
11+
decoration_flags: 0x00000000 # NONE
12+
traits:
13+
numeric:
14+
scalar: { width: 32, signedness: 0 }
15+
vector: { component_count: 2 }
16+
matrix: { column_count: 0, row_count: 0, stride: 0 }
17+
image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown
18+
array: { dims_count: 0, dims: [], stride: 0 }
19+
member_count: 0
20+
members:
21+
- &td1
22+
id: 8
23+
op: 30
24+
type_name: "PerFrameData"
25+
struct_member_name:
26+
storage_class: -1 # NOT APPLICABLE
27+
type_flags: 0x10080000 # STRUCT EXTERNAL_BLOCK
28+
decoration_flags: 0x00000001 # BLOCK
29+
traits:
30+
numeric:
31+
scalar: { width: 0, signedness: 0 }
32+
vector: { component_count: 0 }
33+
matrix: { column_count: 0, row_count: 0, stride: 0 }
34+
image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown
35+
array: { dims_count: 0, dims: [], stride: 0 }
36+
member_count: 1
37+
members:
38+
- *td0
39+
all_block_variables:
40+
- &bv0
41+
name: "bufferId"
42+
offset: 0
43+
absolute_offset: 0
44+
size: 8
45+
padded_size: 16
46+
decorations: 0x00000000 # NONE
47+
numeric:
48+
scalar: { width: 32, signedness: 0 }
49+
vector: { component_count: 2 }
50+
matrix: { column_count: 0, row_count: 0, stride: 0 }
51+
array: { dims_count: 0, dims: [], stride: 0 }
52+
member_count: 0
53+
members:
54+
type_description: *td0
55+
- &bv1
56+
name: "pc"
57+
offset: 0
58+
absolute_offset: 0
59+
size: 16
60+
padded_size: 16
61+
decorations: 0x00000000 # NONE
62+
numeric:
63+
scalar: { width: 0, signedness: 0 }
64+
vector: { component_count: 0 }
65+
matrix: { column_count: 0, row_count: 0, stride: 0 }
66+
array: { dims_count: 0, dims: [], stride: 0 }
67+
member_count: 1
68+
members:
69+
- *bv0
70+
type_description: *td1
71+
all_descriptor_bindings:
72+
all_interface_variables:
73+
module:
74+
generator: 8 # Khronos Glslang Reference Front End
75+
entry_point_name: "main"
76+
entry_point_id: 4
77+
source_language: 2 # GLSL
78+
source_language_version: 460
79+
spirv_execution_model: 5 # GLCompute
80+
shader_stage: 0x00000020 # CS
81+
descriptor_binding_count: 0
82+
descriptor_bindings:
83+
descriptor_set_count: 0
84+
descriptor_sets:
85+
input_variable_count: 0,
86+
input_variables:
87+
output_variable_count: 0,
88+
output_variables:
89+
push_constant_count: 1,
90+
push_constants:
91+
- *bv1 # "pc"
92+
specialization_constant_count: 0,
93+
specialization_constants:
94+
...
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#version 460
2+
#extension GL_EXT_buffer_reference2 : require
3+
#extension GL_EXT_buffer_reference_uvec2 : require
4+
5+
layout(buffer_reference) buffer VertexBuffer;
6+
layout(buffer_reference, buffer_reference_align = 16, std430) buffer VertexBuffer {
7+
int x;
8+
};
9+
10+
layout(set = 0, binding = 0) buffer T1 {
11+
uvec2 bufferId;
12+
} ssbo;
13+
14+
void main() {
15+
VertexBuffer(ssbo.bufferId).x = 0;
16+
}
836 Bytes
Binary file not shown.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
%YAML 1.0
2+
---
3+
all_type_descriptions:
4+
- &td0
5+
id: 7
6+
op: 23
7+
type_name:
8+
struct_member_name: "bufferId"
9+
storage_class: 0 # UniformConstant
10+
type_flags: 0x00000104 # VECTOR INT
11+
decoration_flags: 0x00000000 # NONE
12+
traits:
13+
numeric:
14+
scalar: { width: 32, signedness: 0 }
15+
vector: { component_count: 2 }
16+
matrix: { column_count: 0, row_count: 0, stride: 0 }
17+
image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown
18+
array: { dims_count: 0, dims: [], stride: 0 }
19+
member_count: 0
20+
members:
21+
- &td1
22+
id: 8
23+
op: 30
24+
type_name: "T1"
25+
struct_member_name:
26+
storage_class: -1 # NOT APPLICABLE
27+
type_flags: 0x10080000 # STRUCT EXTERNAL_BLOCK
28+
decoration_flags: 0x00000001 # BLOCK
29+
traits:
30+
numeric:
31+
scalar: { width: 0, signedness: 0 }
32+
vector: { component_count: 0 }
33+
matrix: { column_count: 0, row_count: 0, stride: 0 }
34+
image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown
35+
array: { dims_count: 0, dims: [], stride: 0 }
36+
member_count: 1
37+
members:
38+
- *td0
39+
all_block_variables:
40+
- &bv0
41+
name: "bufferId"
42+
offset: 0
43+
absolute_offset: 0
44+
size: 8
45+
padded_size: 8
46+
decorations: 0x00000000 # NONE
47+
numeric:
48+
scalar: { width: 32, signedness: 0 }
49+
vector: { component_count: 2 }
50+
matrix: { column_count: 0, row_count: 0, stride: 0 }
51+
array: { dims_count: 0, dims: [], stride: 0 }
52+
member_count: 0
53+
members:
54+
type_description: *td0
55+
- &bv1
56+
name: "ssbo"
57+
offset: 0
58+
absolute_offset: 0
59+
size: 0
60+
padded_size: 0
61+
decorations: 0x00000000 # NONE
62+
numeric:
63+
scalar: { width: 0, signedness: 0 }
64+
vector: { component_count: 0 }
65+
matrix: { column_count: 0, row_count: 0, stride: 0 }
66+
array: { dims_count: 0, dims: [], stride: 0 }
67+
member_count: 1
68+
members:
69+
- *bv0
70+
type_description: *td1
71+
all_descriptor_bindings:
72+
- &db0
73+
spirv_id: 10
74+
name: "ssbo"
75+
binding: 0
76+
input_attachment_index: 0
77+
set: 0
78+
decoration_flags: 0x00000000 # NONE
79+
descriptor_type: 7 # VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
80+
resource_type: 8 # UAV
81+
image: { dim: 0, depth: 0, arrayed: 0, ms: 0, sampled: 0, image_format: 0 } # dim=1D image_format=Unknown
82+
block: *bv1 # "ssbo"
83+
array: { dims_count: 0, dims: [] }
84+
accessed: 1
85+
uav_counter_id: 4294967295
86+
uav_counter_binding:
87+
type_description: *td1
88+
word_offset: { binding: 118, set: 114 }
89+
all_interface_variables:
90+
module:
91+
generator: 8 # Khronos Glslang Reference Front End
92+
entry_point_name: "main"
93+
entry_point_id: 4
94+
source_language: 2 # GLSL
95+
source_language_version: 460
96+
spirv_execution_model: 5 # GLCompute
97+
shader_stage: 0x00000020 # CS
98+
descriptor_binding_count: 1
99+
descriptor_bindings:
100+
- *db0 # "ssbo"
101+
descriptor_set_count: 1
102+
descriptor_sets:
103+
- set: 0
104+
binding_count: 1
105+
bindings:
106+
- *db0 # "ssbo"
107+
input_variable_count: 0,
108+
input_variables:
109+
output_variable_count: 0,
110+
output_variables:
111+
push_constant_count: 0,
112+
push_constants:
113+
specialization_constant_count: 0,
114+
specialization_constants:
115+
...

0 commit comments

Comments
 (0)