mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-19 04:08:25 +02:00
nir/lower_ssbo: add option to insert bounds checks
This is mostly useful in combination with `min_ssbo_size` when the native SSBO access instructions do the bounds check in HW so we don't want to add bounds checks for all SSBO accesses. Signed-off-by: Job Noorman <jnoorman@igalia.com> Reviewed-by: Emma Anholt <emma@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41477>
This commit is contained in:
parent
7b2dfdf15d
commit
2fee7ac87f
2 changed files with 33 additions and 0 deletions
|
|
@ -6720,6 +6720,13 @@ typedef struct nir_lower_ssbo_options {
|
|||
* larger buffers.
|
||||
*/
|
||||
uint32_t min_ssbo_size;
|
||||
|
||||
/* Add manual bounds checks for the generated global memory accesses. This
|
||||
* is mostly useful in combination with `min_ssbo_size` when the native
|
||||
* SSBO access instructions do the bounds check in HW so we don't want to
|
||||
* add bounds checks for all SSBO accesses.
|
||||
*/
|
||||
bool bounds_check;
|
||||
} nir_lower_ssbo_options;
|
||||
|
||||
bool nir_lower_ssbo(nir_shader *shader, const nir_lower_ssbo_options *opts);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ pass(nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
|||
|
||||
const nir_lower_ssbo_options *opts = data;
|
||||
uint32_t min_ssbo_size = opts ? opts->min_ssbo_size : 0;
|
||||
bool bounds_check = opts && opts->bounds_check;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
|
|
@ -63,6 +64,18 @@ pass(nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
|||
nir_push_if(b, nir_uge_imm(b, ssbo_size, min_ssbo_size));
|
||||
}
|
||||
|
||||
if (bounds_check) {
|
||||
nir_def *ssbo_size =
|
||||
nir_get_ssbo_size(b, 32, nir_get_io_index_src(intr)->ssa);
|
||||
nir_def *offset = get_offset(b, intr);
|
||||
nir_def *val = intr->intrinsic == nir_intrinsic_store_ssbo
|
||||
? nir_get_io_data_src(intr)->ssa
|
||||
: &intr->def;
|
||||
nir_def *max_offset =
|
||||
nir_iadd_imm(b, offset, val->bit_size * val->num_components / 8 - 1);
|
||||
nir_push_if(b, nir_ult(b, max_offset, ssbo_size));
|
||||
}
|
||||
|
||||
nir_def *def = NULL;
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_ssbo:
|
||||
|
|
@ -102,6 +115,19 @@ pass(nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (bounds_check) {
|
||||
nir_push_else(b, NULL);
|
||||
nir_def *zero;
|
||||
|
||||
if (def)
|
||||
zero = nir_imm_zero(b, def->num_components, def->bit_size);
|
||||
|
||||
nir_pop_if(b, NULL);
|
||||
|
||||
if (def)
|
||||
def = nir_if_phi(b, def, zero);
|
||||
}
|
||||
|
||||
if (min_ssbo_size) {
|
||||
nir_push_else(b, NULL);
|
||||
nir_instr *ssbo_clone = nir_instr_clone(b->shader, &intr->instr);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue