freedreno/ir3: fix half-reg array stores
authorRob Clark <robdclark@chromium.org>
Thu, 16 Jul 2020 22:20:45 +0000 (15:20 -0700)
committerRob Clark <robdclark@chromium.org>
Sat, 18 Jul 2020 16:14:13 +0000 (09:14 -0700)
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5957>

src/freedreno/ir3/ir3_context.c

index 4fe616158009cb9d0972f111da8ea9ad11f9db0a..2d1ed21d9e37ee84d2589e34db64b7dbf0da65a3 100644 (file)
@@ -615,6 +615,7 @@ ir3_create_array_store(struct ir3_context *ctx, struct ir3_array *arr, int n,
        struct ir3_block *block = ctx->block;
        struct ir3_instruction *mov;
        struct ir3_register *dst;
+       unsigned flags = 0;
 
        /* if not relative store, don't create an extra mov, since that
         * ends up being difficult for cp to remove.
@@ -642,17 +643,24 @@ ir3_create_array_store(struct ir3_context *ctx, struct ir3_array *arr, int n,
        }
 
        mov = ir3_instr_create(block, OPC_MOV);
-       mov->cat1.src_type = TYPE_U32;
-       mov->cat1.dst_type = TYPE_U32;
+       if (arr->half) {
+               mov->cat1.src_type = TYPE_U16;
+               mov->cat1.dst_type = TYPE_U16;
+               flags |= IR3_REG_HALF;
+       } else {
+               mov->cat1.src_type = TYPE_U32;
+               mov->cat1.dst_type = TYPE_U32;
+       }
        mov->barrier_class = IR3_BARRIER_ARRAY_W;
        mov->barrier_conflict = IR3_BARRIER_ARRAY_R | IR3_BARRIER_ARRAY_W;
        dst = ir3_reg_create(mov, 0, IR3_REG_ARRAY |
+                       flags |
                        COND(address, IR3_REG_RELATIV));
        dst->instr = arr->last_write;
        dst->size  = arr->length;
        dst->array.id = arr->id;
        dst->array.offset = n;
-       ir3_reg_create(mov, 0, IR3_REG_SSA)->instr = src;
+       ir3_reg_create(mov, 0, IR3_REG_SSA | flags)->instr = src;
 
        if (address)
                ir3_instr_set_address(mov, address);