mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 11:20:20 +01:00
spirv: Implement OpArrayLength for OpenGL
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 <apinheiro@igalia.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8136>
This commit is contained in:
parent
e9ab35ad4f
commit
f65750d221
3 changed files with 43 additions and 21 deletions
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 *array_length =
|
||||
nir_build_deref_buffer_array_length(&b->nb, 32,
|
||||
vtn_pointer_to_ssa(b, array));
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue