Module: Mesa Branch: main Commit: 01ef56a7e49cf0f6c93748333e903ba1776c720f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=01ef56a7e49cf0f6c93748333e903ba1776c720f
Author: Alyssa Rosenzweig <aly...@collabora.com> Date: Wed May 12 13:22:24 2021 -0400 pan/mdg: Use smaller LD_UNIFORM instructions If we only read 8 bytes from a UBO, we need to use LD_UNIFORM.64 as opposed to LD_UNIFORM.128. In addition to probably being faster, this fixes a buffer overrun manifesting as MMU faults with source ID 0x500/0x600/0x700, visible in WebGL Aquarium. This is essentially the same patch as 616394cf31c ("pan/mdg: Use appropriate sizes for global loads/stores"), only this is for UBOs where that was for SSBOs. Before enabling PACKED_UNIFORMS, this bug was not visible since we could guarantee the UBO size was a multiple of 16. We no longer have that invariant, and in rare cases the last 8 bytes of the last 16-byte slot of a mapped uniform buffer would overrun the BO and trigger a fault, even if the result is unused. Fixes: 24d7c413fe7 ("panfrost: Enable packed uniforms.") Signed-off-by: Alyssa Rosenzweig <aly...@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10772> --- src/panfrost/midgard/midgard_compile.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 19bce1b05ea..a4e17ce130b 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -133,6 +133,8 @@ schedule_barrier(compiler_context *ctx) M_LOAD(ld_attr_32, nir_type_uint32); M_LOAD(ld_vary_32, nir_type_uint32); +M_LOAD(ld_ubo_32, nir_type_uint32); +M_LOAD(ld_ubo_64, nir_type_uint32); M_LOAD(ld_ubo_128, nir_type_uint32); M_LOAD(ld_32, nir_type_uint32); M_LOAD(ld_64, nir_type_uint32); @@ -1161,11 +1163,26 @@ emit_ubo_read( unsigned offset, nir_src *indirect_offset, unsigned indirect_shift, - unsigned index) + unsigned index, + unsigned nr_comps) { - /* TODO: half-floats */ + midgard_instruction ins; + + unsigned dest_size = (instr->type == nir_instr_type_intrinsic) ? + nir_dest_bit_size(nir_instr_as_intrinsic(instr)->dest) : 32; + + unsigned bitsize = dest_size * nr_comps; + + /* Pick the smallest intrinsic to avoid out-of-bounds reads */ + if (bitsize <= 32) + ins = m_ld_ubo_32(dest, 0); + else if (bitsize <= 64) + ins = m_ld_ubo_64(dest, 0); + else if (bitsize <= 128) + ins = m_ld_ubo_128(dest, 0); + else + unreachable("Invalid UBO read size"); - midgard_instruction ins = m_ld_ubo_128(dest, 0); ins.constants.u32[0] = offset; if (instr->type == nir_instr_type_intrinsic) @@ -1498,7 +1515,7 @@ emit_sysval_read(compiler_context *ctx, nir_instr *instr, /* Emit the read itself -- this is never indirect */ midgard_instruction *ins = emit_ubo_read(ctx, instr, dest, (uniform * 16) + offset, NULL, 0, - sysval_ubo); + sysval_ubo, nr_components); ins->mask = mask_of(nr_components); } @@ -1752,7 +1769,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr) reg = nir_dest_index(&instr->dest); if (is_kernel) { - emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, 0); + emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, 0, nr_comp); } else if (is_ubo) { nir_src index = instr->src[0]; @@ -1760,7 +1777,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr) assert(nir_src_is_const(index)); uint32_t uindex = nir_src_as_uint(index); - emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, uindex); + emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, uindex, nr_comp); } else if (is_global || is_shared || is_scratch) { unsigned seg = is_global ? LDST_GLOBAL : (is_shared ? LDST_SHARED : LDST_SCRATCH); emit_global(ctx, &instr->instr, true, reg, src_offset, seg); _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-commit