From 337957956e26890347deb98e8f3b558aa8f4329c Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Thu, 1 Apr 2021 12:05:38 +0000 Subject: [PATCH] pan/mdg: improve tex opcode decoding and add missing ops Signed-off-by: Italo Nicola Reviewed-by: Alyssa Rosenzweig Part-of: --- src/panfrost/midgard/disassemble.c | 56 ++++++++++++++++-------------- src/panfrost/midgard/helpers.h | 5 +++ src/panfrost/midgard/midgard.h | 39 +++++++++++++++++---- src/panfrost/midgard/midgard_compile.c | 14 ++++---- src/panfrost/midgard/midgard_derivatives.c | 10 +++--- src/panfrost/midgard/midgard_emit.c | 2 +- src/panfrost/midgard/midgard_ops.c | 11 ++++++ src/panfrost/midgard/midgard_ops.h | 1 + src/panfrost/midgard/midgard_opt_dce.c | 2 +- src/panfrost/midgard/midgard_ra.c | 2 +- src/panfrost/midgard/midgard_schedule.c | 4 +-- 11 files changed, 97 insertions(+), 49 deletions(-) diff --git a/src/panfrost/midgard/disassemble.c b/src/panfrost/midgard/disassemble.c index 1e8e8a4..2abaea8 100644 --- a/src/panfrost/midgard/disassemble.c +++ b/src/panfrost/midgard/disassemble.c @@ -112,6 +112,15 @@ print_ld_st_opcode(FILE *fp, midgard_load_store_op op) } static void +validate_sampler_type(enum mali_texture_op op, enum mali_sampler_type sampler_type) +{ + if (op == midgard_tex_op_mov || op == midgard_tex_op_barrier) + assert(sampler_type == 0); + else + assert(sampler_type > 0); +} + +static void validate_expand_mode(midgard_src_expand_mode expand_mode, midgard_reg_mode reg_mode) { @@ -782,12 +791,8 @@ print_ldst_mask(FILE *fp, unsigned mask, unsigned swizzle) { } } -/* Prints the 4-bit masks found in texture and load/store ops, as opposed to - * the 8-bit masks found in (vector) ALU ops. Supports texture-style 16-bit - * mode as well, but not load/store-style 16-bit mode. */ - static void -print_mask_4(FILE *fp, unsigned mask, bool upper) +print_tex_mask(FILE *fp, unsigned mask, bool upper) { if (mask == 0xF) { if (upper) @@ -1537,7 +1542,7 @@ print_texture_reg_select(FILE *fp, uint8_t u, unsigned base) component += 4; } - fprintf(fp, ".%c", components[component]); + fprintf(fp, ".%c.%d", components[component], sel.full ? 32 : 16); assert(sel.zero == 0); } @@ -1563,8 +1568,8 @@ static bool midgard_op_has_helpers(unsigned op) { switch (op) { - case TEXTURE_OP_NORMAL: - case TEXTURE_OP_DERIVATIVE: + case midgard_tex_op_normal: + case midgard_tex_op_derivative: return true; default: return false; @@ -1574,23 +1579,16 @@ midgard_op_has_helpers(unsigned op) static void print_texture_op(FILE *fp, unsigned op) { - switch (op) { - DEFINE_CASE(TEXTURE_OP_NORMAL, "texture"); - DEFINE_CASE(TEXTURE_OP_LOD, "textureLod"); - DEFINE_CASE(TEXTURE_OP_TEXEL_FETCH, "texelFetch"); - DEFINE_CASE(TEXTURE_OP_BARRIER, "barrier"); - DEFINE_CASE(TEXTURE_OP_DERIVATIVE, "derivative"); - - default: - fprintf(fp, "tex_%X", op); - break; - } + if (tex_opcode_props[op].name) + fprintf(fp, "%s", tex_opcode_props[op].name); + else + fprintf(fp, "tex_op_%02X", op); } static bool texture_op_takes_bias(unsigned op) { - return op == TEXTURE_OP_NORMAL; + return op == midgard_tex_op_normal; } static char @@ -1676,12 +1674,13 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base { midgard_texture_word *texture = (midgard_texture_word *) word; midg_stats.helper_invocations |= midgard_op_has_helpers(texture->op); + validate_sampler_type(texture->op, texture->sampler_type); /* Broad category of texture operation in question */ print_texture_op(fp, texture->op); /* Barriers use a dramatically different code path */ - if (texture->op == TEXTURE_OP_BARRIER) { + if (texture->op == midgard_tex_op_barrier) { print_texture_barrier(fp, word); return; } else if (texture->type == TAG_TEXTURE_4_BARRIER) @@ -1689,7 +1688,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base else if (texture->type == TAG_TEXTURE_4_VTX) fprintf (fp, ".vtx"); - if (texture->op == TEXTURE_OP_DERIVATIVE) + if (texture->op == midgard_tex_op_derivative) fprintf(fp, "%s", derivative_mode(texture->mode)); else fprintf(fp, "%s", texture_mode(texture->mode)); @@ -1709,8 +1708,10 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base fprintf(fp, ".ooo%u", texture->out_of_order); fprintf(fp, " "); - print_tex_reg(fp, texture->out_reg_select, true); - print_mask_4(fp, texture->mask, texture->out_upper); + print_tex_reg(fp, out_reg_base + texture->out_reg_select, true); + print_tex_mask(fp, texture->mask, texture->out_upper); + fprintf(fp, ".%c%d", texture->sampler_type == MALI_SAMPLER_FLOAT ? 'f' : 'i', + texture->out_full ? 32 : 16); assert(!(texture->out_full && texture->out_upper)); /* Output modifiers are only valid for float texture operations */ @@ -1756,6 +1757,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base texture->in_reg_upper ? midgard_src_expand_high : midgard_src_passthrough; print_tex_reg(fp, in_reg_base + texture->in_reg_select, false); print_vec_swizzle(fp, texture->in_reg_swizzle, exp, midgard_reg_mode_32, 0xFF); + fprintf(fp, ".%d", texture->in_reg_full ? 32 : 16); assert(!(texture->in_reg_full && texture->in_reg_upper)); /* There is *always* an offset attached. Of @@ -1771,6 +1773,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base if (texture->offset_register) { fprintf(fp, " + "); + bool full = texture->offset & 1; bool select = texture->offset & 2; bool upper = texture->offset & 4; unsigned swizzle = texture->offset >> 3; @@ -1779,6 +1782,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base print_tex_reg(fp, in_reg_base + select, false); print_vec_swizzle(fp, swizzle, exp, midgard_reg_mode_32, 0xFF); + fprintf(fp, ".%d", full ? 32 : 16); assert(!(texture->out_full && texture->out_upper)); fprintf(fp, ", "); @@ -1794,7 +1798,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base bool neg_z = offset_z < 0; bool any_neg = neg_x || neg_y || neg_z; - if (any_neg && texture->op != TEXTURE_OP_TEXEL_FETCH) + if (any_neg && texture->op != midgard_tex_op_fetch) fprintf(fp, "/* invalid negative */ "); /* Regardless, just print the immediate offset */ @@ -1813,7 +1817,7 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base if (texture->bias_int) fprintf(fp, " /* bias_int = 0x%X */", texture->bias_int); - } else if (texture->op == TEXTURE_OP_TEXEL_FETCH) { + } else if (texture->op == midgard_tex_op_fetch) { /* For texel fetch, the int LOD is in the fractional place and * there is no fraction. We *always* have an explicit LOD, even * if it's zero. */ diff --git a/src/panfrost/midgard/helpers.h b/src/panfrost/midgard/helpers.h index c8efbf6..4a4e51f 100644 --- a/src/panfrost/midgard/helpers.h +++ b/src/panfrost/midgard/helpers.h @@ -261,6 +261,11 @@ struct mir_ldst_op_props { unsigned props; }; +struct mir_tex_op_props { + const char *name; + unsigned props; +}; + struct mir_tag_props { const char *name; unsigned size; diff --git a/src/panfrost/midgard/midgard.h b/src/panfrost/midgard/midgard.h index 1d873de..0bb08d7 100644 --- a/src/panfrost/midgard/midgard.h +++ b/src/panfrost/midgard/midgard.h @@ -807,15 +807,42 @@ midgard_tex_register_select; #define REG_TEX_BASE 28 enum mali_texture_op { - TEXTURE_OP_NORMAL = 1, /* texture */ - TEXTURE_OP_LOD = 2, /* textureLod */ - TEXTURE_OP_TEXEL_FETCH = 4, - TEXTURE_OP_BARRIER = 11, - TEXTURE_OP_DERIVATIVE = 13 + /* [texture + LOD bias] + * If the texture is mipmapped, barriers must be enabled in the + * instruction word in order for this opcode to compute the output + * correctly. */ + midgard_tex_op_normal = 1, + + /* [texture + gradient for LOD and anisotropy] + * Unlike midgard_tex_op_normal, this opcode does not require barriers + * to compute the output correctly. */ + midgard_tex_op_gradient = 2, + + /* [unfiltered texturing] + * Unlike midgard_tex_op_normal, this opcode does not require barriers + * to compute the output correctly. */ + midgard_tex_op_fetch = 4, + + /* [gradient from derivative] */ + midgard_tex_op_grad_from_derivative = 9, + + /* [mov] */ + midgard_tex_op_mov = 10, + + /* [noop] + * Mostly used for barriers. */ + midgard_tex_op_barrier = 11, + + /* [gradient from coords] */ + midgard_tex_op_grad_from_coords = 12, + + /* [derivative] + * Computes derivatives in 2x2 fragment blocks. */ + midgard_tex_op_derivative = 13 }; enum mali_sampler_type { - MALI_SAMPLER_UNK = 0x0, + /* 0 is reserved */ MALI_SAMPLER_FLOAT = 0x1, /* sampler */ MALI_SAMPLER_UNSIGNED = 0x2, /* usampler */ MALI_SAMPLER_SIGNED = 0x3, /* isampler */ diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 1e17f6c..42a656d 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -1619,7 +1619,7 @@ emit_control_barrier(compiler_context *ctx) .type = TAG_TEXTURE_4, .dest = ~0, .src = { ~0, ~0, ~0, ~0 }, - .op = TEXTURE_OP_BARRIER, + .op = midgard_tex_op_barrier, }; emit_mir_instruction(ctx, ins); @@ -2213,7 +2213,7 @@ set_tex_coord(compiler_context *ctx, nir_tex_instr *instr, if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) { /* texelFetch is undefined on samplerCube */ - assert(ins->op != TEXTURE_OP_TEXEL_FETCH); + assert(ins->op != midgard_tex_op_fetch); ins->src[1] = make_compiler_temp_reg(ctx); @@ -2268,7 +2268,7 @@ set_tex_coord(compiler_context *ctx, nir_tex_instr *instr, * of texture dimensionality, which means it's necessary to zero the * unused components to keep everything happy. */ - if (ins->op == TEXTURE_OP_TEXEL_FETCH && + if (ins->op == midgard_tex_op_fetch && (written_mask | write_mask) != 0xF) { if (ins->src[1] == ~0) ins->src[1] = make_compiler_temp_reg(ctx); @@ -2361,7 +2361,7 @@ emit_texop_native(compiler_context *ctx, nir_tex_instr *instr, case nir_tex_src_lod: { /* Try as a constant if we can */ - bool is_txf = midgard_texop == TEXTURE_OP_TEXEL_FETCH; + bool is_txf = midgard_texop == midgard_tex_op_fetch; if (!is_txf && pan_attach_constant_bias(ctx, instr->src[i].src, &ins.texture)) break; @@ -2410,15 +2410,15 @@ emit_tex(compiler_context *ctx, nir_tex_instr *instr) switch (instr->op) { case nir_texop_tex: case nir_texop_txb: - emit_texop_native(ctx, instr, TEXTURE_OP_NORMAL); + emit_texop_native(ctx, instr, midgard_tex_op_normal); break; case nir_texop_txl: case nir_texop_tg4: - emit_texop_native(ctx, instr, TEXTURE_OP_LOD); + emit_texop_native(ctx, instr, midgard_tex_op_gradient); break; case nir_texop_txf: case nir_texop_txf_ms: - emit_texop_native(ctx, instr, TEXTURE_OP_TEXEL_FETCH); + emit_texop_native(ctx, instr, midgard_tex_op_fetch); break; case nir_texop_txs: emit_sysval_read(ctx, &instr->instr, 4, 0); diff --git a/src/panfrost/midgard/midgard_derivatives.c b/src/panfrost/midgard/midgard_derivatives.c index 0bc8362..d493bd4 100644 --- a/src/panfrost/midgard/midgard_derivatives.c +++ b/src/panfrost/midgard/midgard_derivatives.c @@ -78,12 +78,12 @@ mir_op_computes_derivatives(gl_shader_stage stage, unsigned op) /* Only fragment shaders may compute derivatives, but the sense of * "normal" changes in vertex shaders on certain GPUs */ - if (op == TEXTURE_OP_NORMAL && stage != MESA_SHADER_FRAGMENT) + if (op == midgard_tex_op_normal && stage != MESA_SHADER_FRAGMENT) return false; switch (op) { - case TEXTURE_OP_NORMAL: - case TEXTURE_OP_DERIVATIVE: + case midgard_tex_op_normal: + case midgard_tex_op_derivative: assert(stage == MESA_SHADER_FRAGMENT); return true; default: @@ -106,7 +106,7 @@ midgard_emit_derivatives(compiler_context *ctx, nir_alu_instr *instr) .src = { ~0, nir_src_index(ctx, &instr->src[0].src), ~0, ~0 }, .swizzle = SWIZZLE_IDENTITY_4, .src_types = { nir_type_float32, nir_type_float32 }, - .op = TEXTURE_OP_DERIVATIVE, + .op = midgard_tex_op_derivative, .texture = { .mode = mir_derivative_mode(instr->op), .format = 2, @@ -127,7 +127,7 @@ midgard_lower_derivatives(compiler_context *ctx, midgard_block *block) { mir_foreach_instr_in_block_safe(block, ins) { if (ins->type != TAG_TEXTURE_4) continue; - if (ins->op != TEXTURE_OP_DERIVATIVE) continue; + if (ins->op != midgard_tex_op_derivative) continue; /* Check if we need to split */ diff --git a/src/panfrost/midgard/midgard_emit.c b/src/panfrost/midgard/midgard_emit.c index 057a1f4..6177e6d 100644 --- a/src/panfrost/midgard/midgard_emit.c +++ b/src/panfrost/midgard/midgard_emit.c @@ -1029,7 +1029,7 @@ emit_binary_bundle(compiler_context *ctx, ins->texture.next_type = next_tag; /* Nothing else to pack for barriers */ - if (ins->op == TEXTURE_OP_BARRIER) { + if (ins->op == midgard_tex_op_barrier) { ins->texture.cont = ins->texture.last = 1; ins->texture.op = ins->op; util_dynarray_append(emission, midgard_texture_word, ins->texture); diff --git a/src/panfrost/midgard/midgard_ops.c b/src/panfrost/midgard/midgard_ops.c index 441aa0f..c255c04 100644 --- a/src/panfrost/midgard/midgard_ops.c +++ b/src/panfrost/midgard/midgard_ops.c @@ -360,6 +360,17 @@ struct mir_ldst_op_props load_store_opcode_props[256] = { [midgard_op_st_tilebuffer_raw] = {"ST_TILEBUFFER.raw", M32}, }; +struct mir_tex_op_props tex_opcode_props[256] = { + [midgard_tex_op_normal] = {"TEX", M32}, + [midgard_tex_op_gradient] = {"TEX_GRAD", M32}, + [midgard_tex_op_fetch] = {"TEX_FETCH", M32}, + [midgard_tex_op_grad_from_derivative] = {"DER_TO_GRAD", M32}, + [midgard_tex_op_grad_from_coords] = {"COORDS_TO_GRAD", M32}, + [midgard_tex_op_mov] = {"MOV", M32}, + [midgard_tex_op_barrier] = {"BARRIER", M32}, + [midgard_tex_op_derivative] = {"DERIVATIVE", M32} +}; + #undef M8 #undef M16 #undef M32 diff --git a/src/panfrost/midgard/midgard_ops.h b/src/panfrost/midgard/midgard_ops.h index c953816..761cd4b 100644 --- a/src/panfrost/midgard/midgard_ops.h +++ b/src/panfrost/midgard/midgard_ops.h @@ -29,6 +29,7 @@ extern struct mir_op_props alu_opcode_props[256]; extern struct mir_ldst_op_props load_store_opcode_props[256]; +extern struct mir_tex_op_props tex_opcode_props[16]; extern struct mir_tag_props midgard_tag_props[16]; #define OP_IS_ATOMIC(op) (load_store_opcode_props[op].props & LDST_ATOMIC) diff --git a/src/panfrost/midgard/midgard_opt_dce.c b/src/panfrost/midgard/midgard_opt_dce.c index da3f0b7..c43c4eb 100644 --- a/src/panfrost/midgard/midgard_opt_dce.c +++ b/src/panfrost/midgard/midgard_opt_dce.c @@ -60,7 +60,7 @@ can_dce(midgard_instruction *ins) return false; if (ins->type == TAG_TEXTURE_4) - if (ins->op == TEXTURE_OP_BARRIER) + if (ins->op == midgard_tex_op_barrier) return false; return true; diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c index 9a53727..fc893ba 100644 --- a/src/panfrost/midgard/midgard_ra.c +++ b/src/panfrost/midgard/midgard_ra.c @@ -744,7 +744,7 @@ install_registers_instr( } case TAG_TEXTURE_4: { - if (ins->op == TEXTURE_OP_BARRIER) + if (ins->op == midgard_tex_op_barrier) break; /* Grab RA results */ diff --git a/src/panfrost/midgard/midgard_schedule.c b/src/panfrost/midgard/midgard_schedule.c index 17ad243..f890d20 100644 --- a/src/panfrost/midgard/midgard_schedule.c +++ b/src/panfrost/midgard/midgard_schedule.c @@ -1001,9 +1001,9 @@ mir_schedule_texture( mir_update_worklist(worklist, len, instructions, ins); struct midgard_bundle out = { - .tag = ins->op == TEXTURE_OP_BARRIER ? + .tag = ins->op == midgard_tex_op_barrier ? TAG_TEXTURE_4_BARRIER : - (ins->op == TEXTURE_OP_TEXEL_FETCH) || is_vertex ? + (ins->op == midgard_tex_op_fetch) || is_vertex ? TAG_TEXTURE_4_VTX : TAG_TEXTURE_4, .instruction_count = 1, .instructions = { ins } -- 2.7.4