From c4d84a86753e34a25f2d49f3c9b3b935581e8bb1 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Wed, 22 Jan 2025 15:33:47 +0100 Subject: [PATCH] ir3/a7xx: properly handle alias scope and type The alias scope and type bits are intertwined in the encoding: - bit 47: low scope - bit 48: type - bit 49: high scope - bit 50: type size Combining the low and high scope bits, the value is used as follows: - 0: tex - 1: rt - 2: mem - 3: mem I don't know what the difference between 2 and 3 is. The blob currently doesn't use mem at all. The type bit seems to be used to make a distinction between floating point (f) and integer (b) sources. There doesn't seem to be any functional difference and it only affects how immediates are displayed. Note that I haven't exactly mimicked the blob in these cases: - alias.tex.f16/32: the blob uses b16/32 while printing immediates in floating point notation. I think it make more sense to use f16/32. - alias.rt.b16/32: the blob uses i16/32 here. I think it makes more sense to stick to a single notation (b). Signed-off-by: Job Noorman Part-of: --- src/freedreno/ir3/ir3.h | 5 ++- src/freedreno/ir3/ir3_lexer.l | 4 +- src/freedreno/ir3/ir3_parser.y | 15 +++++-- src/freedreno/ir3/tests/disasm.c | 6 ++- src/freedreno/isa/ir3-cat7.xml | 75 ++++++++++++++++++++------------ 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index b962afe84c5..65734ea1d13 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -258,8 +258,8 @@ typedef enum { typedef enum { ALIAS_TEX = 0, - ALIAS_RT = 3, - ALIAS_MEM = 4, + ALIAS_RT = 1, + ALIAS_MEM = 2, } ir3_alias_scope; typedef enum { @@ -435,6 +435,7 @@ struct ir3_instruction { unsigned g : 1; /* global */ ir3_alias_scope alias_scope; + bool alias_type_float; } cat7; /* for meta-instructions, just used to hold extra data * before instruction scheduling, etc diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index 962ca66e2eb..ff518c1ae97 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -426,8 +426,6 @@ static int parse_reg(const char *str) "ray_intersection" return TOKEN(T_OP_RAY_INTERSECTION); -("b16"|"b32"){1} ir3_yylval.str = yytext; return T_INSTR_TYPE; - /* category 7: */ "bar" return TOKEN(T_OP_BAR); "fence" return TOKEN(T_OP_FENCE); @@ -452,6 +450,8 @@ static int parse_reg(const char *str) "u8" return TOKEN(T_TYPE_U8); "u8_32" return TOKEN(T_TYPE_U8_32); "u64" return TOKEN(T_TYPE_U64); +"b16" return TOKEN(T_TYPE_B16); +"b32" return TOKEN(T_TYPE_B32); "untyped" return TOKEN(T_UNTYPED); "typed" return TOKEN(T_TYPED); diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index af74aa364cd..d457d0de6dc 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -711,6 +711,8 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_TYPE_U8 %token T_TYPE_U8_32 %token T_TYPE_U64 +%token T_TYPE_B16 +%token T_TYPE_B32 %token T_UNTYPED %token T_TYPED @@ -749,7 +751,6 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_P0 %token T_W %token T_CAT1_TYPE_TYPE -%token T_INSTR_TYPE %token T_MOD_TEX %token T_MOD_MEM @@ -1449,6 +1450,15 @@ cat7_alias_scope: T_MOD_TEX { instr->cat7.alias_scope = ALIAS_TEX; } | T_MOD_MEM { instr->cat7.alias_scope = ALIAS_MEM; } | T_MOD_RT { instr->cat7.alias_scope = ALIAS_RT; } +cat7_alias_int_type: T_TYPE_B16 +| T_TYPE_B32 + +cat7_alias_float_type: T_TYPE_F16 +| T_TYPE_F32 + +cat7_alias_type: cat7_alias_int_type +| cat7_alias_float_type { instr->cat7.alias_type_float = true; } + cat7_instr: cat7_barrier | cat7_data_cache | T_OP_SLEEP { new_instr(OPC_SLEEP); } @@ -1457,9 +1467,8 @@ cat7_instr: cat7_barrier | T_OP_LOCK { new_instr(OPC_LOCK); } | T_OP_UNLOCK { new_instr(OPC_UNLOCK); } | T_OP_ALIAS { - /* TODO: handle T_INSTR_TYPE */ new_instr(OPC_ALIAS); - } '.' cat7_alias_scope '.' T_INSTR_TYPE '.' integer dst_reg ',' cat7_alias_src { + } '.' cat7_alias_scope '.' cat7_alias_type '.' integer dst_reg ',' cat7_alias_src { new_src(0, IR3_REG_IMMED)->uim_val = $8; } diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 2b20acee091..7291aad78de 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -500,9 +500,11 @@ static const struct test { INSTR_7XX(fbc21000_00000000, "(sy)(ss)(jp)lock"), /* dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r4g4b4a4_unorm_pack16.rg1a.opaque_white.gather_1.no_swizzle_hint */ - INSTR_7XX(e45401a0_bfba7736, "alias.tex.b32.1 r40.x, (-1.456763)"), + INSTR_7XX(e45401a0_bfba7736, "alias.tex.f32.1 r40.x, (-1.456763)"), /* dEQP-VK.synchronization.op.single_queue.event.write_draw_indexed_read_image_geometry.image_128x128_r32g32b32a32_sfloat */ - INSTR_7XX(e44c0009_00000007, "alias.tex.b32.0 r2.y, c1.w"), + INSTR_7XX(e44c0009_00000007, "alias.tex.f32.0 r2.y, c1.w"), + /* dEQP-VK.binding_model.shader_access.primary_cmd_buf.storage_image.geometry.single_descriptor.2d_base_mip */ + INSTR_7XX(ec5501a0_00000006, "(jp)alias.tex.b32.1 r40.x, (0x6)"), INSTR_6XX(ffffffff_ffffffff, "raw 0xFFFFFFFFFFFFFFFF"), /* clang-format on */ diff --git a/src/freedreno/isa/ir3-cat7.xml b/src/freedreno/isa/ir3-cat7.xml index 0de4d3d2cfd..f313a0d8d97 100644 --- a/src/freedreno/isa/ir3-cat7.xml +++ b/src/freedreno/isa/ir3-cat7.xml @@ -187,7 +187,7 @@ SOFTWARE. - {SRC_TYPE} == 0 /* b16 */ + {TYPE} == 0 && {TYPE_SIZE} == 0 /* f16 */ h({IMMED}) @@ -196,19 +196,28 @@ SOFTWARE. - {SRC_TYPE} == 1 /* b32 */ + {TYPE} == 0 && {TYPE_SIZE} == 1 /* f32 */ ({IMMED}) + + + {TYPE_SIZE} == 0 /* b16 */ + + + h(0x{IMMED}) + + + - {IMMED} + (0x{IMMED}) - + extract_reg_uim(src) @@ -221,7 +230,7 @@ SOFTWARE. - ({SRC_TYPE} == 0) /* b16 */ + ({TYPE_SIZE} == 0) /* b16 */ @@ -236,7 +245,7 @@ SOFTWARE. - ({SRC_TYPE} == 0) /* b16 */ + ({TYPE_SIZE} == 0) /* b16 */ @@ -245,24 +254,28 @@ SOFTWARE. - - TODO: Yes, something is wrong here, needs to be tested. - - - - + + + - + + + + + + - These types are clearly used by the blob. - However, it seems that there may be f32/f16/i32/i16 - types but they are interwind with the _scope_ bitfield. - TODO: Check if it does matter. + The type (float or int) of sources. This seems to have no + functional effect and only changes how immediates are displayed. + Note that the blob uses i16/i32 when the scope is rt or the 2nd + mem, but this is not implemented here. Also note that the blob + uses b16/b32 for alias.tex when the type is 0, even though it + still prints immediates as floats in that case. - - + + @@ -296,45 +309,53 @@ SOFTWARE. - {SY}{SS}{JP}{NAME}.{SCOPE}.{SRC_TYPE}.{UNK} {DST}, {SRC} + {SY}{SS}{JP}{NAME}.{SCOPE}.{TYPE}{TYPE_SIZE}.{UNK} {DST}, {SRC} {SRC_REG_TYPE} == 0 - + 000000000000000000000000 {SRC_REG_TYPE} == 1 - + 000000000000000000000 - + + xx - - + + + + 1x 1000 111 + + ({SCOPE_HI} << 1) | {SCOPE_LO} + src->srcs[0] (src->srcs[0]->flags & IR3_REG_CONST) ? 1 : ((src->srcs[0]->flags & IR3_REG_IMMED) ? 2 : 0) - 1 extract_reg_uim(src->srcs[1]) - src->cat7.alias_scope + (src->srcs[0]->flags & IR3_REG_HALF) ? 0 : 1 + src->cat7.alias_scope & 0x1 + src->cat7.alias_scope >> 1 + !src->cat7.alias_type_float