From 616394cf31cecc0165857dd032a316da5b0a2440 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Sun, 14 Mar 2021 23:54:27 +1300 Subject: [PATCH] pan/mdg: Use appropriate sizes for global loads/stores When always using 128-bit operations, an access at the end of an SSBO could spill over to the next page and cause a GPU fault. To avoid this, pick the smallest instruction that fits. The if ladder might need extending for sizes of less than 32 bits, but those currently fail in other parts of the compiler so are untested. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/panfrost/midgard/midgard_compile.c | 36 +++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 7f0fe7660e8..b6e6178056d 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -133,7 +133,11 @@ 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_u128, nir_type_uint32); +M_LOAD(ld_u32, nir_type_uint32); +M_LOAD(ld_u64, nir_type_uint32); M_LOAD(ld_u128, nir_type_uint32); +M_STORE(st_u32, nir_type_uint32); +M_STORE(st_u64, nir_type_uint32); M_STORE(st_u128, nir_type_uint32); M_LOAD(ld_color_buffer_32u, nir_type_uint32); M_LOAD(ld_color_buffer_as_fp16, nir_type_float16); @@ -1186,14 +1190,34 @@ emit_global( nir_src *offset, unsigned seg) { - /* TODO: types */ - midgard_instruction ins; - if (is_read) - ins = m_ld_u128(srcdest, 0); - else - ins = m_st_u128(srcdest, 0); + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (is_read) { + unsigned bitsize = nir_dest_bit_size(intr->dest) * + nir_dest_num_components(intr->dest); + + if (bitsize <= 32) + ins = m_ld_u32(srcdest, 0); + else if (bitsize <= 64) + ins = m_ld_u64(srcdest, 0); + else if (bitsize <= 128) + ins = m_ld_u128(srcdest, 0); + else + unreachable("Invalid global read size"); + } else { + unsigned bitsize = nir_src_bit_size(intr->src[0]) * + nir_src_num_components(intr->src[0]); + + if (bitsize <= 32) + ins = m_st_u32(srcdest, 0); + else if (bitsize <= 64) + ins = m_st_u64(srcdest, 0); + else if (bitsize <= 128) + ins = m_st_u128(srcdest, 0); + else + unreachable("Invalid global store size"); + } mir_set_offset(ctx, &ins, offset, seg); mir_set_intr_mask(instr, &ins, is_read);