From fd6ed7b5628678ada0db3bf6ae1bcf80628c6947 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 3 Apr 2017 13:25:02 -0400 Subject: [PATCH] freedreno/ir3: resync instr-a3xx.h/disasm-a3xx.c Sync to the same files from freedreno.git to correct decoding of ldgb/ stgb instructions. Signed-off-by: Rob Clark --- .../drivers/freedreno/a2xx/disasm-a2xx.c | 2 +- src/gallium/drivers/freedreno/disasm.h | 3 + .../drivers/freedreno/ir3/disasm-a3xx.c | 83 +++++++++++++++++-- .../drivers/freedreno/ir3/instr-a3xx.h | 77 +++++++++++++++-- src/gallium/drivers/freedreno/ir3/ir3.h | 2 +- src/gallium/drivers/freedreno/ir3/ir3_nir.c | 4 +- .../drivers/freedreno/ir3/ir3_shader.c | 10 ++- 7 files changed, 161 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c b/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c index fc309e8b495..c3804509250 100644 --- a/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c +++ b/src/gallium/drivers/freedreno/a2xx/disasm-a2xx.c @@ -111,7 +111,7 @@ static void print_export_comment(uint32_t num, enum shader_t type) case 0: name = "gl_FragColor"; break; } break; - case SHADER_COMPUTE: + default: unreachable("not reached"); } /* if we had a symbol table here, we could look diff --git a/src/gallium/drivers/freedreno/disasm.h b/src/gallium/drivers/freedreno/disasm.h index e81dd1c8ef4..bac1215accd 100644 --- a/src/gallium/drivers/freedreno/disasm.h +++ b/src/gallium/drivers/freedreno/disasm.h @@ -26,6 +26,9 @@ enum shader_t { SHADER_VERTEX, + SHADER_TCS, + SHADER_TES, + SHADER_GEOM, SHADER_FRAGMENT, SHADER_COMPUTE, }; diff --git a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c index e29d1568256..4685ed6deae 100644 --- a/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c +++ b/src/gallium/drivers/freedreno/ir3/disasm-a3xx.c @@ -159,16 +159,16 @@ static void print_instr_cat0(instr_t *instr) break; case OPC_BR: printf(" %sp0.%c, #%d", cat0->inv ? "!" : "", - component[cat0->comp], cat0->a3xx.immed); + component[cat0->comp], cat0->a5xx.immed); break; case OPC_JUMP: case OPC_CALL: - printf(" #%d", cat0->a3xx.immed); + printf(" #%d", cat0->a5xx.immed); break; } - if ((debug & PRINT_VERBOSE) && (cat0->a3xx.dummy1|cat0->dummy2|cat0->dummy3|cat0->dummy4)) - printf("\t{0: %x,%x,%x,%x}", cat0->a3xx.dummy1, cat0->dummy2, cat0->dummy3, cat0->dummy4); + if ((debug & PRINT_VERBOSE) && (cat0->dummy2|cat0->dummy3|cat0->dummy4)) + printf("\t{0: %x,%x,%x}", cat0->dummy2, cat0->dummy3, cat0->dummy4); } static void print_instr_cat1(instr_t *instr) @@ -506,7 +506,6 @@ static void print_instr_cat6(instr_t *instr) case OPC_STP: case OPC_STI: case OPC_STLW: - case OPC_STGB_4D_4: case OPC_STIB: dst.full = true; src1.full = type_size(cat6->type) == 32; @@ -523,6 +522,18 @@ static void print_instr_cat6(instr_t *instr) case OPC_PREFETCH: case OPC_RESINFO: break; + case OPC_LDGB: + printf(".%s", cat6->ldgb.typed ? "typed" : "untyped"); + printf(".%dd", cat6->ldgb.d + 1); + printf(".%s", type[cat6->type]); + printf(".%d", cat6->ldgb.type_size + 1); + break; + case OPC_STGB: + printf(".%s", cat6->stgb.typed ? "typed" : "untyped"); + printf(".%dd", cat6->stgb.d + 1); + printf(".%s", type[cat6->type]); + printf(".%d", cat6->stgb.type_size + 1); + break; case OPC_ATOMIC_ADD: case OPC_ATOMIC_SUB: case OPC_ATOMIC_XCHG: @@ -558,6 +569,7 @@ static void print_instr_cat6(instr_t *instr) break; case OPC_LDG: + case OPC_LDC: ss = 'g'; break; case OPC_LDP: @@ -589,6 +601,61 @@ static void print_instr_cat6(instr_t *instr) break; } + if (_OPC(6, cat6->opc) == OPC_STGB) { + struct reginfo src3; + + memset(&src3, 0, sizeof(src3)); + + src1.reg = (reg_t)(cat6->stgb.src1); + src2.reg = (reg_t)(cat6->stgb.src2); + src2.im = cat6->stgb.src2_im; + src3.reg = (reg_t)(cat6->stgb.src3); + src3.im = cat6->stgb.src3_im; + src3.full = true; + + printf("g[%u], ", cat6->stgb.dst_ssbo); + print_src(&src1); + printf(", "); + print_src(&src2); + printf(", "); + print_src(&src3); + + if (debug & PRINT_VERBOSE) + printf(" (pad0=%x, pad3=%x)", cat6->stgb.pad0, cat6->stgb.pad3); + + return; + } + + if ((_OPC(6, cat6->opc) == OPC_LDGB) || is_atomic(_OPC(6, cat6->opc))) { + + src1.reg = (reg_t)(cat6->ldgb.src1); + src1.im = cat6->ldgb.src1_im; + src2.reg = (reg_t)(cat6->ldgb.src2); + src2.im = cat6->ldgb.src2_im; + dst.reg = (reg_t)(cat6->ldgb.dst); + + print_src(&dst); + printf(", "); + printf("g[%u], ", cat6->ldgb.src_ssbo); + print_src(&src1); + printf(", "); + print_src(&src2); + + if (is_atomic(_OPC(6, cat6->opc))) { + struct reginfo src3; + memset(&src3, 0, sizeof(src3)); + src3.reg = (reg_t)(cat6->ldgb.src3); + src3.full = true; + + printf(", "); + print_src(&src3); + } + + if (debug & PRINT_VERBOSE) + printf(" (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.pad3, cat6->ldgb.mustbe0); + + return; + } if (cat6->dst_off) { dst.reg = (reg_t)(cat6->c.dst); dstoff = cat6->c.off; @@ -806,10 +873,10 @@ static const struct opc_info { OPC(6, OPC_ATOMIC_AND, atomic.and), OPC(6, OPC_ATOMIC_OR, atomic.or), OPC(6, OPC_ATOMIC_XOR, atomic.xor), - OPC(6, OPC_LDGB_TYPED_4D, ldgb.typed.3d), - OPC(6, OPC_STGB_4D_4, stgb.4d.4), + OPC(6, OPC_LDGB, ldgb), + OPC(6, OPC_STGB, stgb), OPC(6, OPC_STIB, stib), - OPC(6, OPC_LDC_4, ldc.4), + OPC(6, OPC_LDC, ldc), OPC(6, OPC_LDLV, ldlv), diff --git a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h index 0d369b605f7..b429b3b9ffc 100644 --- a/src/gallium/drivers/freedreno/ir3/instr-a3xx.h +++ b/src/gallium/drivers/freedreno/ir3/instr-a3xx.h @@ -189,10 +189,10 @@ typedef enum { OPC_ATOMIC_AND = _OPC(6, 24), OPC_ATOMIC_OR = _OPC(6, 25), OPC_ATOMIC_XOR = _OPC(6, 26), - OPC_LDGB_TYPED_4D = _OPC(6, 27), - OPC_STGB_4D_4 = _OPC(6, 28), + OPC_LDGB = _OPC(6, 27), + OPC_STGB = _OPC(6, 28), OPC_STIB = _OPC(6, 29), - OPC_LDC_4 = _OPC(6, 30), + OPC_LDC = _OPC(6, 30), OPC_LDLV = _OPC(6, 31), /* meta instructions (category -1): */ @@ -639,18 +639,63 @@ typedef struct PACKED { uint32_t dst : 8; uint32_t mustbe0 : 1; - uint32_t pad0 : 23; + uint32_t idx : 8; + uint32_t pad0 : 15; } instr_cat6d_t; -/* I think some of the other cat6 instructions use additional - * sub-encodings.. +/* ldgb and atomics.. atomics use 3rd src and pad0=1, pad3=3. For + * ldgb pad0=0, pad3=2 */ +typedef struct PACKED { + /* dword0: */ + uint32_t pad0 : 1; + uint32_t src3 : 8; + uint32_t d : 2; + uint32_t typed : 1; + uint32_t type_size : 2; + uint32_t src1 : 8; + uint32_t src1_im : 1; + uint32_t src2_im : 1; + uint32_t src2 : 8; + + /* dword1: */ + uint32_t dst : 8; + uint32_t mustbe0 : 1; + uint32_t src_ssbo : 8; + uint32_t pad2 : 3; // type + uint32_t pad3 : 2; + uint32_t pad4 : 10; // opc/jmp_tgt/sync/opc_cat +} instr_cat6ldgb_t; + +/* stgb, pad0=0, pad3=2 + */ +typedef struct PACKED { + /* dword0: */ + uint32_t mustbe1 : 1; // ??? + uint32_t src1 : 8; + uint32_t d : 2; + uint32_t typed : 1; + uint32_t type_size : 2; + uint32_t pad0 : 9; + uint32_t src2_im : 1; + uint32_t src2 : 8; + + /* dword1: */ + uint32_t src3 : 8; + uint32_t src3_im : 1; + uint32_t dst_ssbo : 8; + uint32_t pad2 : 3; // type + uint32_t pad3 : 2; + uint32_t pad4 : 10; // opc/jmp_tgt/sync/opc_cat +} instr_cat6stgb_t; typedef union PACKED { instr_cat6a_t a; instr_cat6b_t b; instr_cat6c_t c; instr_cat6d_t d; + instr_cat6ldgb_t ldgb; + instr_cat6stgb_t stgb; struct PACKED { /* dword0: */ uint32_t src_off : 1; @@ -733,4 +778,24 @@ static inline bool is_madsh(opc_t opc) } } +static inline bool is_atomic(opc_t opc) +{ + switch (opc) { + case OPC_ATOMIC_ADD: + case OPC_ATOMIC_SUB: + case OPC_ATOMIC_XCHG: + case OPC_ATOMIC_INC: + case OPC_ATOMIC_DEC: + case OPC_ATOMIC_CMPXCHG: + case OPC_ATOMIC_MIN: + case OPC_ATOMIC_MAX: + case OPC_ATOMIC_AND: + case OPC_ATOMIC_OR: + case OPC_ATOMIC_XOR: + return true; + default: + return false; + } +} + #endif /* INSTR_A3XX_H_ */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index bbe903d9d15..8d75ec168cb 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -621,7 +621,7 @@ static inline bool is_load(struct ir3_instruction *instr) case OPC_LDP: case OPC_L2G: case OPC_LDLW: - case OPC_LDC_4: + case OPC_LDC: case OPC_LDLV: /* probably some others too.. */ return true; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c index 336fa95ee7d..d0083d8fc8d 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c @@ -114,7 +114,6 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s, if (key) { switch (shader->type) { case SHADER_FRAGMENT: - case SHADER_COMPUTE: tex_options.saturate_s = key->fsaturate_s; tex_options.saturate_t = key->fsaturate_t; tex_options.saturate_r = key->fsaturate_r; @@ -124,6 +123,9 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s, tex_options.saturate_t = key->vsaturate_t; tex_options.saturate_r = key->vsaturate_r; break; + default: + /* TODO */ + break; } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 1d54d5330ad..9133317038b 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -223,7 +223,6 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, */ switch (shader->type) { case SHADER_FRAGMENT: - case SHADER_COMPUTE: key.binning_pass = false; if (key.has_per_samp) { key.vsaturate_s = 0; @@ -243,6 +242,9 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key, key.fastc_srgb = 0; } break; + default: + /* TODO */ + break; } for (v = shader->variants; v; v = v->next) @@ -418,7 +420,8 @@ ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin) } debug_printf("\n"); break; - case SHADER_COMPUTE: + default: + /* TODO */ break; } @@ -462,7 +465,8 @@ ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin) if (so->frag_face) debug_printf("; fragface: hr0.x\n"); break; - case SHADER_COMPUTE: + default: + /* TODO */ break; } -- 2.30.2