ir3: Delete old packed struct encoding

turnip clear/blit shaders were the last user of these.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12079>
This commit is contained in:
Connor Abbott 2021-07-28 10:50:38 +02:00 committed by Marge Bot
parent fc0c0e9d45
commit 9b0a4cc893
2 changed files with 1 additions and 645 deletions

View File

@ -404,26 +404,6 @@ typedef enum {
ROUND_NEG_INF = 3,
} round_t;
typedef union PACKED {
/* normal gpr or const src register: */
struct PACKED {
uint32_t comp : 2;
uint32_t num : 10;
};
/* for immediate val: */
int32_t iim_val : 11;
/* to make compiler happy: */
uint32_t dummy32;
uint32_t dummy10 : 10;
int32_t idummy10 : 10;
uint32_t dummy11 : 11;
uint32_t dummy12 : 12;
uint32_t dummy13 : 13;
uint32_t dummy8 : 8;
int32_t idummy13 : 13;
int32_t idummy8 : 8;
} reg_t;
/* comp:
* 0 - x
* 1 - y
@ -444,12 +424,6 @@ regid(int num, int comp)
#define REG_A0 61 /* address register */
#define REG_P0 62 /* predicate register */
static inline int
reg_special(reg_t reg)
{
return (reg.num == REG_A0) || (reg.num == REG_P0);
}
typedef enum {
BRANCH_PLAIN = 0, /* br */
BRANCH_OR = 1, /* brao */
@ -460,268 +434,6 @@ typedef enum {
BRANCH_X = 6, /* brax ??? */
} brtype_t;
typedef struct PACKED {
/* dword0: */
union PACKED {
struct PACKED {
int16_t immed : 16;
uint32_t dummy1 : 16;
} a3xx;
struct PACKED {
int32_t immed : 20;
uint32_t dummy1 : 12;
} a4xx;
struct PACKED {
int32_t immed : 32;
} a5xx;
};
/* dword1: */
uint32_t idx : 5; /* brac.N index */
uint32_t brtype : 3; /* branch type, see brtype_t */
uint32_t repeat : 3;
uint32_t dummy3 : 1;
uint32_t ss : 1;
uint32_t inv2 : 1;
uint32_t comp2 : 2;
uint32_t eq : 1;
uint32_t opc_hi : 1; /* at least one bit */
uint32_t dummy4 : 2;
uint32_t inv1 : 1;
uint32_t comp1 : 2; /* component for first src */
uint32_t opc : 4;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat0_t;
typedef struct PACKED {
/* dword0: */
union PACKED {
/* for normal src register: */
struct PACKED {
uint32_t src : 11;
/* at least low bit of pad must be zero or it will
* look like a address relative src
*/
uint32_t pad : 21;
};
/* for address relative: */
struct PACKED {
int32_t off : 10;
uint32_t src_rel_c : 1;
uint32_t src_rel : 1;
uint32_t unknown : 20;
};
/* for immediate: */
int32_t iim_val;
uint32_t uim_val;
float fim_val;
};
/* dword1: */
uint32_t dst : 8;
uint32_t repeat : 3;
uint32_t src_r : 1;
uint32_t ss : 1;
uint32_t ul : 1;
uint32_t dst_type : 3;
uint32_t dst_rel : 1;
uint32_t src_type : 3;
uint32_t src_c : 1;
uint32_t src_im : 1;
uint32_t even : 1;
uint32_t pos_inf : 1;
uint32_t opc : 2;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat1_t;
typedef struct PACKED {
/* dword0: */
union PACKED {
struct PACKED {
uint32_t src1 : 11;
uint32_t must_be_zero1 : 2;
uint32_t src1_im : 1; /* immediate */
uint32_t src1_neg : 1; /* negate */
uint32_t src1_abs : 1; /* absolute value */
};
struct PACKED {
uint32_t src1 : 10;
uint32_t src1_c : 1; /* relative-const */
uint32_t src1_rel : 1; /* relative address */
uint32_t must_be_zero : 1;
uint32_t dummy : 3;
} rel1;
struct PACKED {
uint32_t src1 : 12;
uint32_t src1_c : 1; /* const */
int32_t dummy : 3;
} c1;
};
union PACKED {
struct PACKED {
uint32_t src2 : 11;
uint32_t must_be_zero2 : 2;
uint32_t src2_im : 1; /* immediate */
uint32_t src2_neg : 1; /* negate */
uint32_t src2_abs : 1; /* absolute value */
};
struct PACKED {
uint32_t src2 : 10;
uint32_t src2_c : 1; /* relative-const */
uint32_t src2_rel : 1; /* relative address */
uint32_t must_be_zero : 1;
uint32_t dummy : 3;
} rel2;
struct PACKED {
uint32_t src2 : 12;
uint32_t src2_c : 1; /* const */
uint32_t dummy : 3;
} c2;
};
/* dword1: */
uint32_t dst : 8;
uint32_t repeat : 2;
uint32_t sat : 1;
uint32_t src1_r : 1; /* doubles as nop0 if repeat==0 */
uint32_t ss : 1;
uint32_t ul : 1; /* dunno */
uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
uint32_t ei : 1;
uint32_t cond : 3;
uint32_t src2_r : 1; /* doubles as nop1 if repeat==0 */
uint32_t full : 1; /* not half */
uint32_t opc : 6;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat2_t;
typedef struct PACKED {
/* dword0: */
union PACKED {
struct PACKED {
uint32_t src1 : 11;
uint32_t must_be_zero1 : 2;
uint32_t src2_c : 1;
uint32_t src1_neg : 1;
uint32_t src2_r : 1; /* doubles as nop1 if repeat==0 */
};
struct PACKED {
uint32_t src1 : 10;
uint32_t src1_c : 1;
uint32_t src1_rel : 1;
uint32_t must_be_zero : 1;
uint32_t dummy : 3;
} rel1;
struct PACKED {
uint32_t src1 : 12;
uint32_t src1_c : 1;
uint32_t dummy : 3;
} c1;
};
union PACKED {
struct PACKED {
uint32_t src3 : 11;
uint32_t must_be_zero2 : 2;
uint32_t src3_r : 1;
uint32_t src2_neg : 1;
uint32_t src3_neg : 1;
};
struct PACKED {
uint32_t src3 : 10;
uint32_t src3_c : 1;
uint32_t src3_rel : 1;
uint32_t must_be_zero : 1;
uint32_t dummy : 3;
} rel2;
struct PACKED {
uint32_t src3 : 12;
uint32_t src3_c : 1;
uint32_t dummy : 3;
} c2;
};
/* dword1: */
uint32_t dst : 8;
uint32_t repeat : 2;
uint32_t sat : 1;
uint32_t src1_r : 1; /* doubles as nop0 if repeat==0 */
uint32_t ss : 1;
uint32_t ul : 1;
uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
uint32_t src2 : 8;
uint32_t opc : 4;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat3_t;
static inline bool
instr_cat3_full(instr_cat3_t *cat3)
{
switch (_OPC(3, cat3->opc)) {
case OPC_MAD_F16:
case OPC_MAD_U16:
case OPC_MAD_S16:
case OPC_SEL_B16:
case OPC_SEL_S16:
case OPC_SEL_F16:
case OPC_SAD_S16:
case OPC_SAD_S32: // really??
return false;
default:
return true;
}
}
typedef struct PACKED {
/* dword0: */
union PACKED {
struct PACKED {
uint32_t src : 11;
uint32_t must_be_zero1 : 2;
uint32_t src_im : 1; /* immediate */
uint32_t src_neg : 1; /* negate */
uint32_t src_abs : 1; /* absolute value */
};
struct PACKED {
uint32_t src : 10;
uint32_t src_c : 1; /* relative-const */
uint32_t src_rel : 1; /* relative address */
uint32_t must_be_zero : 1;
uint32_t dummy : 3;
} rel;
struct PACKED {
uint32_t src : 12;
uint32_t src_c : 1; /* const */
uint32_t dummy : 3;
} c;
};
uint32_t dummy1 : 16; /* seem to be ignored */
/* dword1: */
uint32_t dst : 8;
uint32_t repeat : 2;
uint32_t sat : 1;
uint32_t src_r : 1;
uint32_t ss : 1;
uint32_t ul : 1;
uint32_t dst_half : 1; /* or widen/narrow.. ie. dst hrN <-> rN */
uint32_t dummy2 : 5; /* seem to be ignored */
uint32_t full : 1; /* not half */
uint32_t opc : 6;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat4_t;
/* With is_bindless_s2en = 1, this determines whether bindless is enabled and
* if so, how to get the (base, index) pair for both sampler and texture.
* There is a single base embedded in the instruction, which is always used
@ -773,186 +485,6 @@ typedef enum {
CAT5_BINDLESS_A1_IMM = 7,
} cat5_desc_mode_t;
typedef struct PACKED {
/* dword0: */
union PACKED {
/* normal case: */
struct PACKED {
uint32_t full : 1; /* not half */
uint32_t src1 : 8;
uint32_t src2 : 8;
uint32_t dummy1 : 4; /* seem to be ignored */
uint32_t samp : 4;
uint32_t tex : 7;
} norm;
/* s2en case: */
struct PACKED {
uint32_t full : 1; /* not half */
uint32_t src1 : 8;
uint32_t src2 : 8;
uint32_t dummy1 : 2;
uint32_t base_hi : 2;
uint32_t src3 : 8;
uint32_t desc_mode : 3;
} s2en_bindless;
/* same in either case: */
// XXX I think, confirm this
struct PACKED {
uint32_t full : 1; /* not half */
uint32_t src1 : 8;
uint32_t src2 : 8;
uint32_t pad : 15;
};
};
/* dword1: */
uint32_t dst : 8;
uint32_t wrmask : 4; /* write-mask */
uint32_t type : 3;
uint32_t base_lo : 1; /* used with bindless */
uint32_t is_3d : 1;
uint32_t is_a : 1;
uint32_t is_s : 1;
uint32_t is_s2en_bindless : 1;
uint32_t is_o : 1;
uint32_t is_p : 1;
uint32_t opc : 5;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat5_t;
/* dword0 encoding for src_off: [src1 + off], src3: */
typedef struct PACKED {
/* dword0: */
uint32_t mustbe1 : 1;
int32_t off : 13; /* src2 */
uint32_t src1 : 8;
uint32_t src1_im : 1;
uint32_t src3_im : 1;
uint32_t src3 : 8;
/* dword1: */
uint32_t dword1;
} instr_cat6a_t;
/* dword0 encoding for !src_off: [src1], src2 */
typedef struct PACKED {
/* dword0: */
uint32_t mustbe0 : 1;
uint32_t src1 : 8;
uint32_t pad : 5;
uint32_t ignore0 : 8;
uint32_t src1_im : 1;
uint32_t src2_im : 1;
uint32_t src2 : 8;
/* dword1: */
uint32_t dword1;
} instr_cat6b_t;
/* dword1 encoding for dst_off: */
typedef struct PACKED {
/* dword0: */
uint32_t dw0_pad1 : 9;
int32_t off_high : 5;
uint32_t dw0_pad2 : 18;
uint32_t off : 8;
uint32_t mustbe1 : 1;
uint32_t dst : 8;
uint32_t pad1 : 15;
} instr_cat6c_t;
/* dword1 encoding for !dst_off: */
typedef struct PACKED {
/* dword0: */
uint32_t dword0;
uint32_t dst : 8;
uint32_t mustbe0 : 1;
uint32_t idx : 8;
uint32_t pad0 : 15;
} instr_cat6d_t;
/* ldgb and atomics..
*
* ldgb: pad0=0, pad3=1
* atomic .g: pad0=1, pad3=1
* .l: pad0=1, pad3=0
*/
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 g : 1;
uint32_t src_ssbo_im : 1;
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;
uint32_t pad1 : 31;
/* dword1: */
uint32_t pad2 : 8;
uint32_t dst_off : 1;
uint32_t pad3 : 8;
uint32_t type : 3;
uint32_t g : 1; /* or in some cases it means dst immed */
uint32_t pad4 : 1;
uint32_t opc : 5;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
};
} instr_cat6_t;
/* Similar to cat5_desc_mode_t, describes how the descriptor is loaded.
*/
typedef enum {
@ -979,130 +511,6 @@ typedef enum {
CAT6_BINDLESS_NONUNIFORM = 6,
} cat6_desc_mode_t;
/**
* For atomic ops (which return a value):
*
* pad1=1, pad3=6, pad5=3
* src1 - vecN offset/coords
* src2.x - is actually dest register
* src2.y - is 'data' except for cmpxchg where src2.y is 'compare'
* and src2.z is 'data'
*
* For stib (which does not return a value):
* pad1=0, pad3=6, pad5=2
* src1 - vecN offset/coords
* src2 - value to store
*
* For ldib:
* pad1=1, pad3=6, pad5=2
* src1 - vecN offset/coords
*
* for ldc (load from UBO using descriptor):
* pad1=0, pad3=4, pad5=2
*
* pad2 and pad5 are only observed to be 0.
*/
typedef struct PACKED {
/* dword0: */
uint32_t pad1 : 1;
uint32_t base : 3;
uint32_t pad2 : 2;
uint32_t desc_mode : 3;
uint32_t d : 2;
uint32_t typed : 1;
uint32_t type_size : 2;
uint32_t opc : 6;
uint32_t pad3 : 4;
uint32_t src1 : 8; /* coordinate/offset */
/* dword1: */
uint32_t src2 : 8; /* or the dst for load instructions */
uint32_t pad4 : 1; // mustbe0 ??
uint32_t ssbo : 8; /* ssbo/image binding point */
uint32_t type : 3;
uint32_t pad5 : 7;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
} instr_cat6_a6xx_t;
typedef struct PACKED {
/* dword0: */
uint32_t pad1 : 32;
/* dword1: */
uint32_t pad2 : 12;
uint32_t ss : 1; /* maybe in the encoding, but blob only uses (sy) */
uint32_t pad3 : 6;
uint32_t w : 1; /* write */
uint32_t r : 1; /* read */
uint32_t l : 1; /* local */
uint32_t g : 1; /* global */
uint32_t opc : 4; /* presumed, but only a couple known OPCs */
uint32_t jmp_tgt : 1; /* (jp) */
uint32_t sync : 1; /* (sy) */
uint32_t opc_cat : 3;
} instr_cat7_t;
typedef union PACKED {
instr_cat0_t cat0;
instr_cat1_t cat1;
instr_cat2_t cat2;
instr_cat3_t cat3;
instr_cat4_t cat4;
instr_cat5_t cat5;
instr_cat6_t cat6;
instr_cat6_a6xx_t cat6_a6xx;
instr_cat7_t cat7;
struct PACKED {
/* dword0: */
uint32_t pad1 : 32;
/* dword1: */
uint32_t pad2 : 12;
uint32_t ss : 1; /* cat1-cat4 (cat0??) and cat7 (?) */
uint32_t ul : 1; /* cat2-cat4 (and cat1 in blob.. which may be bug??) */
uint32_t pad3 : 13;
uint32_t jmp_tgt : 1;
uint32_t sync : 1;
uint32_t opc_cat : 3;
};
} instr_t;
static inline uint32_t
instr_repeat(instr_t *instr)
{
switch (instr->opc_cat) {
case 0:
return instr->cat0.repeat;
case 1:
return instr->cat1.repeat;
case 2:
return instr->cat2.repeat;
case 3:
return instr->cat3.repeat;
case 4:
return instr->cat4.repeat;
default:
return 0;
}
}
static inline bool
instr_sat(instr_t *instr)
{
switch (instr->opc_cat) {
case 2:
return instr->cat2.sat;
case 3:
return instr->cat3.sat;
case 4:
return instr->cat4.sat;
default:
return false;
}
}
static inline bool
is_sat_compatible(opc_t opc)
{
@ -1126,58 +534,6 @@ is_sat_compatible(opc_t opc)
}
}
/* We can probably drop the gpu_id arg, but keeping it for now so we can
* assert if we see something we think should be new encoding on an older
* gpu.
*/
static inline bool
is_cat6_legacy(instr_t *instr, unsigned gpu_id)
{
instr_cat6_a6xx_t *cat6 = &instr->cat6_a6xx;
if (gpu_id < 600)
return true;
/* At least one of these two bits is pad in all the possible
* "legacy" cat6 encodings, and a analysis of all the pre-a6xx
* cmdstream traces I have indicates that the pad bit is zero
* in all cases. So we can use this to detect new encoding:
*/
if ((cat6->pad3 & 0x4) && (cat6->pad5 & 0x2)) {
ir3_assert(instr->cat6.opc == 0);
return false;
}
return true;
}
static inline uint32_t
instr_opc(instr_t *instr, unsigned gpu_id)
{
switch (instr->opc_cat) {
case 0:
return instr->cat0.opc | instr->cat0.opc_hi << 4;
case 1:
return instr->cat1.opc;
case 2:
return instr->cat2.opc;
case 3:
return instr->cat3.opc;
case 4:
return instr->cat4.opc;
case 5:
return instr->cat5.opc;
case 6:
if (!is_cat6_legacy(instr, gpu_id))
return instr->cat6_a6xx.opc;
return instr->cat6.opc;
case 7:
return instr->cat7.opc;
default:
return 0;
}
}
static inline bool
is_mad(opc_t opc)
{

View File

@ -147,7 +147,7 @@ ir3_shader_assemble(struct ir3_shader_variant *v)
/* Pad out the size so that when turnip uploads the shaders in
* sequence, the starting offset of the next one is properly aligned.
*/
info->size = align(info->size, compiler->instr_align * sizeof(instr_t));
info->size = align(info->size, compiler->instr_align * sizeof(uint64_t));
bin = isa_assemble(v);
if (!bin)