mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
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:
parent
6a12ea02fe
commit
337957956e
11 changed files with 97 additions and 49 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue