nir/lower_io: Eliminate oob writes and return zero for oob reads
Out-of-bounds writes could be eliminated per spec: Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says: "In the subsections described above for array, vector, matrix and structure accesses, any out-of-bounds access produced undefined behavior.... Out-of-bounds writes may be discarded or overwrite other variables of the active program. Out-of-bounds reads return undefined values, which include values from other variables of the active program or zero." GL_KHR_robustness and GL_ARB_robustness encourage us to return zero for reads. Otherwise get_io_offset would return out-of-bound offset which may result in out-of-bound loading/storing of inputs/outputs, that could cause issues in drivers down the line. E.g. this fixes such dereference: int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]]; in brw_nir.c CC: <mesa-stable@lists.freedesktop.org> Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com> Reviewed-by: Eric Anholt <eric@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6428>
This commit is contained in:

committed by
Marge Bot

parent
8e1193b8d3
commit
66669eb529
@@ -636,6 +636,37 @@ nir_lower_io_block(nir_block *block,
|
||||
mode == nir_var_shader_out ||
|
||||
var->data.bindless;
|
||||
|
||||
if (nir_deref_instr_is_known_out_of_bounds(deref)) {
|
||||
/* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
|
||||
*
|
||||
* In the subsections described above for array, vector, matrix and
|
||||
* structure accesses, any out-of-bounds access produced undefined
|
||||
* behavior....
|
||||
* Out-of-bounds reads return undefined values, which
|
||||
* include values from other variables of the active program or zero.
|
||||
* Out-of-bounds writes may be discarded or overwrite
|
||||
* other variables of the active program.
|
||||
*
|
||||
* GL_KHR_robustness and GL_ARB_robustness encourage us to return zero
|
||||
* for reads.
|
||||
*
|
||||
* Otherwise get_io_offset would return out-of-bound offset which may
|
||||
* result in out-of-bound loading/storing of inputs/outputs,
|
||||
* that could cause issues in drivers down the line.
|
||||
*/
|
||||
if (intrin->intrinsic != nir_intrinsic_store_deref) {
|
||||
nir_ssa_def *zero =
|
||||
nir_imm_zero(b, intrin->dest.ssa.num_components,
|
||||
intrin->dest.ssa.bit_size);
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
|
||||
nir_src_for_ssa(zero));
|
||||
}
|
||||
|
||||
nir_instr_remove(&intrin->instr);
|
||||
progress = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = get_io_offset(b, deref, per_vertex ? &vertex_index : NULL,
|
||||
state->type_size, &component_offset,
|
||||
bindless_type_size);
|
||||
|
Reference in New Issue
Block a user