From f65750d2215242b17309b5aa8845b717bb913e77 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 16 Dec 2020 20:51:30 -0800 Subject: spirv: Implement OpArrayLength for OpenGL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses same NIR intrinsic as glsl_to_nir. Make it an option so it is easy later to move Vulkan drivers incrementally to use it. Fixes piglit test spec/arb_gl_spirv/execution/ssbo/unsized-array-length. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3691 Fixes: 15e43907 ("iris: Enable ARB_gl_spirv and ARB_spirv_extensions") Reviewed-by: Alejandro PiƱeiro Reviewed-by: Jason Ekstrand Part-of: --- src/compiler/spirv/nir_spirv.h | 5 ++++ src/compiler/spirv/vtn_variables.c | 54 ++++++++++++++++++++++++-------------- src/mesa/main/glspirv.c | 1 + 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h index b7d2432df7c..9585dbbec9b 100644 --- a/src/compiler/spirv/nir_spirv.h +++ b/src/compiler/spirv/nir_spirv.h @@ -69,6 +69,11 @@ struct spirv_to_nir_options { /* Create a nir library. */ bool create_library; + /* Whether to use nir_intrinsic_deref_buffer_array_length intrinsic instead + * of nir_intrinsic_get_ssbo_size to lower OpArrayLength. + */ + bool use_deref_buffer_array_length; + /* Initial value for shader_info::float_controls_execution_mode, * indicates hardware requirements rather than shader author intent */ diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 4cb1832d404..6cccb540090 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -2449,30 +2449,46 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, "OpArrayLength must reference the last memeber of the " "structure and that must be an array"); - const uint32_t offset = ptr->type->offsets[field]; - const uint32_t stride = ptr->type->members[field]->stride; - - if (!ptr->block_index) { + if (b->options->use_deref_buffer_array_length) { struct vtn_access_chain chain = { - .length = 0, + .length = 1, + .link = { + { .mode = vtn_access_mode_literal, .id = field }, + } }; - ptr = vtn_pointer_dereference(b, ptr, &chain); - vtn_assert(ptr->block_index); - } + struct vtn_pointer *array = vtn_pointer_dereference(b, ptr, &chain); - nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index); + nir_ssa_def *array_length = + nir_build_deref_buffer_array_length(&b->nb, 32, + vtn_pointer_to_ssa(b, array)); - /* array_length = max(buffer_size - offset, 0) / stride */ - nir_ssa_def *array_length = - nir_idiv(&b->nb, - nir_imax(&b->nb, - nir_isub(&b->nb, - buf_size, - nir_imm_int(&b->nb, offset)), - nir_imm_int(&b->nb, 0u)), - nir_imm_int(&b->nb, stride)); + vtn_push_nir_ssa(b, w[2], array_length); + } else { + const uint32_t offset = ptr->type->offsets[field]; + const uint32_t stride = ptr->type->members[field]->stride; + + if (!ptr->block_index) { + struct vtn_access_chain chain = { + .length = 0, + }; + ptr = vtn_pointer_dereference(b, ptr, &chain); + vtn_assert(ptr->block_index); + } + + nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index); - vtn_push_nir_ssa(b, w[2], array_length); + /* array_length = max(buffer_size - offset, 0) / stride */ + nir_ssa_def *array_length = + nir_idiv(&b->nb, + nir_imax(&b->nb, + nir_isub(&b->nb, + buf_size, + nir_imm_int(&b->nb, offset)), + nir_imm_int(&b->nb, 0u)), + nir_imm_int(&b->nb, stride)); + + vtn_push_nir_ssa(b, w[2], array_length); + } break; } diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c index 92c521ba649..1668be08d95 100644 --- a/src/mesa/main/glspirv.c +++ b/src/mesa/main/glspirv.c @@ -244,6 +244,7 @@ _mesa_spirv_to_nir(struct gl_context *ctx, const struct spirv_to_nir_options spirv_options = { .environment = NIR_SPIRV_OPENGL, .frag_coord_is_sysval = ctx->Const.GLSLFragCoordIsSysVal, + .use_deref_buffer_array_length = true, .caps = ctx->Const.SpirVCapabilities, .ubo_addr_format = nir_address_format_32bit_index_offset, .ssbo_addr_format = nir_address_format_32bit_index_offset, -- cgit v1.2.3