mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-24 03:00:30 +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;
|
struct vtn_type *type = val->type;
|
||||||
|
|
||||||
if (dec->decoration == SpvDecorationArrayStride) {
|
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 "
|
vtn_warn("The ArrayStride decoration cannot be applied to an array "
|
||||||
"type which contains a structure type decorated Block "
|
"type which contains a structure type decorated Block "
|
||||||
"or BufferBlock");
|
"or BufferBlock");
|
||||||
|
|
|
||||||
|
|
@ -2718,12 +2718,42 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
||||||
case SpvOpPtrAccessChain:
|
case SpvOpPtrAccessChain:
|
||||||
case SpvOpInBoundsAccessChain:
|
case SpvOpInBoundsAccessChain:
|
||||||
case SpvOpInBoundsPtrAccessChain: {
|
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;
|
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;
|
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]);
|
struct vtn_value *link_val = vtn_untyped_value(b, w[i]);
|
||||||
if (link_val->value_type == vtn_value_type_constant) {
|
if (link_val->value_type == vtn_value_type_constant) {
|
||||||
chain->link[idx].mode = vtn_access_mode_literal;
|
chain->link[idx].mode = vtn_access_mode_literal;
|
||||||
|
|
@ -2739,10 +2769,6 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
||||||
idx++;
|
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);
|
chain->in_bounds = (opcode == SpvOpInBoundsAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
|
||||||
|
|
||||||
/* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
|
/* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue