mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-22 09:50:28 +01:00
spirv: Add more restrictions around Blocks
And take advantage of the new restriction to skip the ptr_as_array case for Blocks. Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36049>
This commit is contained in:
parent
ee555e9f75
commit
ea9deafff4
2 changed files with 39 additions and 8 deletions
|
|
@ -1454,7 +1454,12 @@ array_stride_decoration_cb(struct vtn_builder *b,
|
|||
struct vtn_type *type = val->type;
|
||||
|
||||
if (dec->decoration == SpvDecorationArrayStride) {
|
||||
if (vtn_type_contains_block(b, type)) {
|
||||
if (type->base_type == vtn_base_type_pointer &&
|
||||
(type->pointed->block || type->pointed->buffer_block)) {
|
||||
vtn_warn("A pointer to a structure decorated with *Block* or "
|
||||
"*BufferBlock* must not have an *ArrayStride* decoration");
|
||||
/* Ignore the decoration */
|
||||
} else if (vtn_type_contains_block(b, type)) {
|
||||
vtn_warn("The ArrayStride decoration cannot be applied to an array "
|
||||
"type which contains a structure type decorated Block "
|
||||
"or BufferBlock");
|
||||
|
|
|
|||
|
|
@ -2718,12 +2718,42 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
case SpvOpPtrAccessChain:
|
||||
case SpvOpInBoundsAccessChain:
|
||||
case SpvOpInBoundsPtrAccessChain: {
|
||||
struct vtn_access_chain *chain = vtn_access_chain_create(b, count - 4);
|
||||
bool ptr_as_array = opcode == SpvOpPtrAccessChain ||
|
||||
opcode == SpvOpInBoundsPtrAccessChain;
|
||||
|
||||
struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
|
||||
struct vtn_pointer *base = vtn_pointer(b, w[3]);
|
||||
|
||||
unsigned first_idx = 4;
|
||||
|
||||
/* The SPIR-V spec says
|
||||
*
|
||||
* "OpPtrAccessChain: If _Base_ points to a structure decorated with
|
||||
* *Block* or *BufferBlock* and the value of 'Element' is not zero
|
||||
* then the behavior is undefined."
|
||||
*/
|
||||
if (ptr_as_array &&
|
||||
(base->type->pointed->block || base->type->pointed->buffer_block)) {
|
||||
|
||||
struct vtn_value *val = vtn_untyped_value(b, w[first_idx]);
|
||||
if (val->value_type == vtn_value_type_constant &&
|
||||
vtn_constant_int(b, w[first_idx]) != 0) {
|
||||
vtn_warn("OpPtrAccessChain on a block with non-zero Element.");
|
||||
}
|
||||
|
||||
/* Any value other than zero for Element results in undefined
|
||||
* behavior so we can just ignore the ptr_as_array part.
|
||||
*/
|
||||
first_idx++;
|
||||
ptr_as_array = false;
|
||||
}
|
||||
|
||||
enum gl_access_qualifier access = 0;
|
||||
chain->ptr_as_array = (opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
|
||||
struct vtn_access_chain *chain = vtn_access_chain_create(b, count - first_idx);
|
||||
chain->ptr_as_array = ptr_as_array;
|
||||
|
||||
unsigned idx = 0;
|
||||
for (int i = 4; i < count; i++) {
|
||||
for (int i = first_idx; i < count; i++) {
|
||||
struct vtn_value *link_val = vtn_untyped_value(b, w[i]);
|
||||
if (link_val->value_type == vtn_value_type_constant) {
|
||||
chain->link[idx].mode = vtn_access_mode_literal;
|
||||
|
|
@ -2739,10 +2769,6 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
idx++;
|
||||
}
|
||||
|
||||
struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
|
||||
|
||||
struct vtn_pointer *base = vtn_pointer(b, w[3]);
|
||||
|
||||
chain->in_bounds = (opcode == SpvOpInBoundsAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
|
||||
|
||||
/* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue