pan/mdg: improve tex opcode decoding and add missing ops

Signed-off-by: Italo Nicola <italonicola@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9461>
This commit is contained in:
Italo Nicola 2021-04-01 12:05:38 +00:00 committed by Marge Bot
parent 6a12ea02fe
commit 337957956e
11 changed files with 97 additions and 49 deletions

View file

@ -111,6 +111,15 @@ print_ld_st_opcode(FILE *fp, midgard_load_store_op op)
fprintf(fp, "ldst_op_%02X", 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. */

View file

@ -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;

View file

@ -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 */

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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 */

View file

@ -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 }