Path: blob/21.2-virgl/src/broadcom/compiler/v3d_nir_lower_robust_buffer_access.c
4564 views
/*1* Copyright © 2020 Raspberry Pi2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "compiler/v3d_compiler.h"24#include "compiler/nir/nir_builder.h"2526static void27rewrite_offset(nir_builder *b,28nir_intrinsic_instr *instr,29uint32_t buffer_idx,30uint32_t offset_src,31nir_intrinsic_op buffer_size_op)32{33b->cursor = nir_before_instr(&instr->instr);3435/* Get size of the buffer */36nir_intrinsic_instr *size =37nir_intrinsic_instr_create(b->shader, buffer_size_op);38size->src[0] = nir_src_for_ssa(nir_imm_int(b, buffer_idx));39nir_ssa_dest_init(&size->instr, &size->dest, 1, 32, NULL);40nir_builder_instr_insert(b, &size->instr);4142/* All out TMU accesses are 32-bit aligned */43nir_ssa_def *aligned_buffer_size =44nir_iand(b, &size->dest.ssa, nir_imm_int(b, 0xfffffffc));4546/* Rewrite offset */47nir_ssa_def *offset =48nir_umin(b, instr->src[offset_src].ssa, aligned_buffer_size);49nir_instr_rewrite_src(&instr->instr, &instr->src[offset_src],50nir_src_for_ssa(offset));51}5253static void54lower_load(struct v3d_compile *c,55nir_builder *b,56nir_intrinsic_instr *instr)57{58uint32_t index = nir_src_comp_as_uint(instr->src[0], 0);5960nir_intrinsic_op op;61if (instr->intrinsic == nir_intrinsic_load_ubo) {62op = nir_intrinsic_get_ubo_size;63if (c->key->environment == V3D_ENVIRONMENT_VULKAN)64index--;65} else {66op = nir_intrinsic_get_ssbo_size;67}6869rewrite_offset(b, instr, index, 1, op);70}7172static void73lower_store(struct v3d_compile *c,74nir_builder *b,75nir_intrinsic_instr *instr)76{77uint32_t index = nir_src_comp_as_uint(instr->src[1], 0);78rewrite_offset(b, instr, index, 2, nir_intrinsic_get_ssbo_size);79}8081static void82lower_atomic(struct v3d_compile *c,83nir_builder *b,84nir_intrinsic_instr *instr)85{86uint32_t index = nir_src_comp_as_uint(instr->src[0], 0);87rewrite_offset(b, instr, index, 1, nir_intrinsic_get_ssbo_size);88}8990static void91lower_shared(struct v3d_compile *c,92nir_builder *b,93nir_intrinsic_instr *instr)94{95b->cursor = nir_before_instr(&instr->instr);96nir_ssa_def *aligned_size =97nir_imm_int(b, c->s->info.shared_size & 0xfffffffc);98nir_ssa_def *offset = nir_umin(b, instr->src[0].ssa, aligned_size);99nir_instr_rewrite_src(&instr->instr, &instr->src[0],100nir_src_for_ssa(offset));101}102103static void104lower_instr(struct v3d_compile *c, nir_builder *b, struct nir_instr *instr)105{106if (instr->type != nir_instr_type_intrinsic)107return;108nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);109110switch (intr->intrinsic) {111case nir_intrinsic_load_ubo:112case nir_intrinsic_load_ssbo:113lower_load(c, b, intr);114break;115case nir_intrinsic_store_ssbo:116lower_store(c, b, intr);117break;118case nir_intrinsic_ssbo_atomic_add:119case nir_intrinsic_ssbo_atomic_imin:120case nir_intrinsic_ssbo_atomic_umin:121case nir_intrinsic_ssbo_atomic_imax:122case nir_intrinsic_ssbo_atomic_umax:123case nir_intrinsic_ssbo_atomic_and:124case nir_intrinsic_ssbo_atomic_or:125case nir_intrinsic_ssbo_atomic_xor:126case nir_intrinsic_ssbo_atomic_exchange:127case nir_intrinsic_ssbo_atomic_comp_swap:128lower_atomic(c, b, intr);129break;130case nir_intrinsic_load_shared:131case nir_intrinsic_shared_atomic_add:132case nir_intrinsic_shared_atomic_imin:133case nir_intrinsic_shared_atomic_umin:134case nir_intrinsic_shared_atomic_imax:135case nir_intrinsic_shared_atomic_umax:136case nir_intrinsic_shared_atomic_and:137case nir_intrinsic_shared_atomic_or:138case nir_intrinsic_shared_atomic_xor:139case nir_intrinsic_shared_atomic_exchange:140case nir_intrinsic_shared_atomic_comp_swap:141lower_shared(c, b, intr);142break;143default:144break;145}146}147148void149v3d_nir_lower_robust_buffer_access(nir_shader *s, struct v3d_compile *c)150{151nir_foreach_function(function, s) {152if (function->impl) {153nir_builder b;154nir_builder_init(&b, function->impl);155156nir_foreach_block(block, function->impl) {157nir_foreach_instr_safe(instr, block)158lower_instr(c, &b, instr);159}160161nir_metadata_preserve(function->impl,162nir_metadata_block_index |163nir_metadata_dominance);164}165}166}167168169