Mesa (master): pan/mdg: fix midgard writemask encoding for stores
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Apr 21 21:39:45 UTC 2021
Module: Mesa
Branch: master
Commit: 9703ca56991c0a74aeb240477a21c074ff156244
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=9703ca56991c0a74aeb240477a21c074ff156244
Author: Italo Nicola <italonicola at collabora.com>
Date: Wed Apr 7 00:05:35 2021 +0000
pan/mdg: fix midgard writemask encoding for stores
This commits fixes a regression caused by commit
616394cf31cecc0165857dd032a316da5b0a2440.
Fixes dEQP-GLES31.functional.compute.shared_var.atomic.min.*,
dEQP-GLES31.functional.ssbo.atomic.min.*,
dEQP-GLES31.functional.compute.shared_var.atomic.max.* and
dEQP-GLES31.functional.ssbo.atomic.max.*.
Midgard's non-image and non-varying store operations have a unique
behavior for the load/store writemask, with each bit being responsible
for 1/4th of the size of the total write operation. This means that we
have to pack the writemask differently since we stopped using st_u128
for everything.
Signed-off-by: Italo Nicola <italonicola at collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10067>
---
src/panfrost/midgard/helpers.h | 5 ++
src/panfrost/midgard/midgard_emit.c | 96 ++++++++++++++++++++++++++++++-------
2 files changed, 84 insertions(+), 17 deletions(-)
diff --git a/src/panfrost/midgard/helpers.h b/src/panfrost/midgard/helpers.h
index e3fce61e01e..f89e7520454 100644
--- a/src/panfrost/midgard/helpers.h
+++ b/src/panfrost/midgard/helpers.h
@@ -79,6 +79,11 @@
OP_IS_UNSIGNED_CMP(op) \
)
+#define OP_IS_COMMON_STORE(op) ( \
+ op >= midgard_op_st_u8 && \
+ op <= midgard_op_st_u128 \
+ )
+
/* ALU control words are single bit fields with a lot of space */
#define ALU_ENAB_VEC_MUL (1 << 17)
diff --git a/src/panfrost/midgard/midgard_emit.c b/src/panfrost/midgard/midgard_emit.c
index 7f320a98226..53e227d8ed0 100644
--- a/src/panfrost/midgard/midgard_emit.c
+++ b/src/panfrost/midgard/midgard_emit.c
@@ -401,32 +401,94 @@ mir_pack_tex_ooo(midgard_block *block, midgard_bundle *bundle, midgard_instructi
ins->texture.out_of_order = count;
}
-/* Load store masks are 4-bits. Load/store ops pack for that. vec4 is the
- * natural mask width; vec8 is constrained to be in pairs, vec2 is duplicated. TODO: 8-bit?
+/* Load store masks are 4-bits. Load/store ops pack for that.
+ * For most operations, vec4 is the natural mask width; vec8 is constrained to
+ * be in pairs, vec2 is duplicated. TODO: 8-bit?
+ * For common stores (i.e. ST.*), each bit masks a single byte in the 32-bit
+ * case, 2 bytes in the 64-bit case and 4 bytes in the 128-bit case.
*/
+static unsigned
+midgard_pack_common_store_mask(midgard_instruction *ins) {
+ unsigned comp_sz = nir_alu_type_get_type_size(ins->dest_type);
+ unsigned mask = ins->mask;
+ unsigned packed = 0;
+ unsigned nr_comp;
+
+ switch (ins->op) {
+ case midgard_op_st_u8:
+ packed |= mask & 1;
+ break;
+ case midgard_op_st_u16:
+ nr_comp = 16 / comp_sz;
+ for (int i = 0; i < nr_comp; i++) {
+ if (mask & (1 << i)) {
+ if (comp_sz == 16)
+ packed |= 0x3;
+ else if (comp_sz == 8)
+ packed |= 1 << i;
+ }
+ }
+ break;
+ case midgard_op_st_u32:
+ case midgard_op_st_u64:
+ case midgard_op_st_u128: {
+ unsigned total_sz = 32;
+ if (ins->op == midgard_op_st_u128)
+ total_sz = 128;
+ else if (ins->op == midgard_op_st_u64)
+ total_sz = 64;
+
+ nr_comp = total_sz / comp_sz;
+
+ /* Each writemask bit masks 1/4th of the value to be stored. */
+ assert(comp_sz >= total_sz / 4);
+
+ for (int i = 0; i < nr_comp; i++) {
+ if (mask & (1 << i)) {
+ if (comp_sz == total_sz)
+ packed |= 0xF;
+ else if (comp_sz == total_sz / 2)
+ packed |= 0x3 << i;
+ else if (comp_sz == total_sz / 4)
+ packed |= 0x1 << i;
+ }
+ }
+ break;
+ }
+ default:
+ unreachable("unexpected ldst opcode");
+ }
+
+ return packed;
+}
+
static void
mir_pack_ldst_mask(midgard_instruction *ins)
{
unsigned sz = nir_alu_type_get_type_size(ins->dest_type);
unsigned packed = ins->mask;
- if (sz == 64) {
- packed = ((ins->mask & 0x2) ? (0x8 | 0x4) : 0) |
- ((ins->mask & 0x1) ? (0x2 | 0x1) : 0);
- } else if (sz == 16) {
- packed = 0;
-
- for (unsigned i = 0; i < 4; ++i) {
- /* Make sure we're duplicated */
- bool u = (ins->mask & (1 << (2*i + 0))) != 0;
- ASSERTED bool v = (ins->mask & (1 << (2*i + 1))) != 0;
- assert(u == v);
-
- packed |= (u << i);
- }
+ if (OP_IS_COMMON_STORE(ins->op)) {
+ packed = midgard_pack_common_store_mask(ins);
} else {
- assert(sz == 32);
+ if (sz == 64) {
+ packed = ((ins->mask & 0x2) ? (0x8 | 0x4) : 0) |
+ ((ins->mask & 0x1) ? (0x2 | 0x1) : 0);
+ } else if (sz == 16) {
+ packed = 0;
+
+ for (unsigned i = 0; i < 4; ++i) {
+ /* Make sure we're duplicated */
+ bool u = (ins->mask & (1 << (2*i + 0))) != 0;
+ ASSERTED bool v = (ins->mask & (1 << (2*i + 1))) != 0;
+ assert(u == v);
+
+ packed |= (u << i);
+ }
+ } else {
+ assert(sz == 32);
+ }
}
ins->load_store.mask = packed;
More information about the mesa-commit
mailing list