mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 22:38:05 +02:00
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 as616394cf31("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:24d7c413fe("panfrost: Enable packed uniforms.") Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10772>
This commit is contained in:
parent
df3edfc729
commit
01ef56a7e4
1 changed files with 23 additions and 6 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue