pan/mdg: Refactor texture op/mode handling
We reduce the op to 4-bits, such that the derivative mode becomes its own adjacent parameter. This cleans up handling of texture gathers, but does not affect functionality. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6516>
This commit is contained in:
parent
80ebf110ae
commit
f6e19dd3f4
|
@ -1293,15 +1293,11 @@ print_texture_format(FILE *fp, int format)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
midgard_op_has_helpers(unsigned op, bool gather)
|
midgard_op_has_helpers(unsigned op)
|
||||||
{
|
{
|
||||||
if (gather)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case TEXTURE_OP_NORMAL:
|
case TEXTURE_OP_NORMAL:
|
||||||
case TEXTURE_OP_DFDX:
|
case TEXTURE_OP_DERIVATIVE:
|
||||||
case TEXTURE_OP_DFDY:
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -1309,30 +1305,14 @@ midgard_op_has_helpers(unsigned op, bool gather)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_texture_op(FILE *fp, unsigned op, bool gather)
|
print_texture_op(FILE *fp, unsigned op)
|
||||||
{
|
{
|
||||||
/* Act like a bare name, like ESSL functions */
|
|
||||||
|
|
||||||
if (gather) {
|
|
||||||
fprintf(fp, "textureGather");
|
|
||||||
|
|
||||||
unsigned component = op >> 4;
|
|
||||||
unsigned bottom = op & 0xF;
|
|
||||||
|
|
||||||
if (bottom != 0x2)
|
|
||||||
fprintf(fp, "_unk%u", bottom);
|
|
||||||
|
|
||||||
fprintf(fp, ".%c", components[component]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
DEFINE_CASE(TEXTURE_OP_NORMAL, "texture");
|
DEFINE_CASE(TEXTURE_OP_NORMAL, "texture");
|
||||||
DEFINE_CASE(TEXTURE_OP_LOD, "textureLod");
|
DEFINE_CASE(TEXTURE_OP_LOD, "textureLod");
|
||||||
DEFINE_CASE(TEXTURE_OP_TEXEL_FETCH, "texelFetch");
|
DEFINE_CASE(TEXTURE_OP_TEXEL_FETCH, "texelFetch");
|
||||||
DEFINE_CASE(TEXTURE_OP_BARRIER, "barrier");
|
DEFINE_CASE(TEXTURE_OP_BARRIER, "barrier");
|
||||||
DEFINE_CASE(TEXTURE_OP_DFDX, "dFdx");
|
DEFINE_CASE(TEXTURE_OP_DERIVATIVE, "derivative");
|
||||||
DEFINE_CASE(TEXTURE_OP_DFDY, "dFdy");
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "tex_%X", op);
|
fprintf(fp, "tex_%X", op);
|
||||||
|
@ -1399,16 +1379,38 @@ print_texture_barrier(FILE *fp, uint32_t *word)
|
||||||
|
|
||||||
#undef DEFINE_CASE
|
#undef DEFINE_CASE
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
texture_mode(enum mali_texture_mode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case TEXTURE_NORMAL: return "";
|
||||||
|
case TEXTURE_SHADOW: return ".shadow";
|
||||||
|
case TEXTURE_GATHER_X: return ".gatherX";
|
||||||
|
case TEXTURE_GATHER_Y: return ".gatherY";
|
||||||
|
case TEXTURE_GATHER_Z: return ".gatherZ";
|
||||||
|
case TEXTURE_GATHER_W: return ".gatherW";
|
||||||
|
default: return "unk";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
derivative_mode(enum mali_derivative_mode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case TEXTURE_DFDX: return ".x";
|
||||||
|
case TEXTURE_DFDY: return ".y";
|
||||||
|
default: return "unk";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base, unsigned out_reg_base)
|
print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base, unsigned out_reg_base)
|
||||||
{
|
{
|
||||||
midgard_texture_word *texture = (midgard_texture_word *) word;
|
midgard_texture_word *texture = (midgard_texture_word *) word;
|
||||||
|
midg_stats.helper_invocations |= midgard_op_has_helpers(texture->op);
|
||||||
midg_stats.helper_invocations |=
|
|
||||||
midgard_op_has_helpers(texture->op, texture->is_gather);
|
|
||||||
|
|
||||||
/* Broad category of texture operation in question */
|
/* Broad category of texture operation in question */
|
||||||
print_texture_op(fp, texture->op, texture->is_gather);
|
print_texture_op(fp, texture->op);
|
||||||
|
|
||||||
/* Barriers use a dramatically different code path */
|
/* Barriers use a dramatically different code path */
|
||||||
if (texture->op == TEXTURE_OP_BARRIER) {
|
if (texture->op == TEXTURE_OP_BARRIER) {
|
||||||
|
@ -1419,14 +1421,16 @@ print_texture_word(FILE *fp, uint32_t *word, unsigned tabs, unsigned in_reg_base
|
||||||
else if (texture->type == TAG_TEXTURE_4_VTX)
|
else if (texture->type == TAG_TEXTURE_4_VTX)
|
||||||
fprintf (fp, ".vtx");
|
fprintf (fp, ".vtx");
|
||||||
|
|
||||||
|
if (texture->op == TEXTURE_OP_DERIVATIVE)
|
||||||
|
fprintf(fp, "%s", derivative_mode(texture->mode));
|
||||||
|
else
|
||||||
|
fprintf(fp, "%s", texture_mode(texture->mode));
|
||||||
|
|
||||||
/* Specific format in question */
|
/* Specific format in question */
|
||||||
print_texture_format(fp, texture->format);
|
print_texture_format(fp, texture->format);
|
||||||
|
|
||||||
/* Instruction "modifiers" parallel the ALU instructions. */
|
/* Instruction "modifiers" parallel the ALU instructions. */
|
||||||
|
|
||||||
if (texture->shadow)
|
|
||||||
fprintf(fp, ".shadow");
|
|
||||||
|
|
||||||
if (texture->cont)
|
if (texture->cont)
|
||||||
fprintf(fp, ".cont");
|
fprintf(fp, ".cont");
|
||||||
|
|
||||||
|
|
|
@ -65,11 +65,6 @@
|
||||||
op == midgard_alu_op_fcsel \
|
op == midgard_alu_op_fcsel \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define OP_IS_DERIVATIVE(op) ( \
|
|
||||||
op == TEXTURE_OP_DFDX || \
|
|
||||||
op == TEXTURE_OP_DFDY \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define OP_IS_UNSIGNED_CMP(op) ( \
|
#define OP_IS_UNSIGNED_CMP(op) ( \
|
||||||
op == midgard_alu_op_ult || \
|
op == midgard_alu_op_ult || \
|
||||||
op == midgard_alu_op_ule \
|
op == midgard_alu_op_ule \
|
||||||
|
|
|
@ -632,23 +632,13 @@ midgard_tex_register_select;
|
||||||
/* Texture pipeline results are in r28-r29 */
|
/* Texture pipeline results are in r28-r29 */
|
||||||
#define REG_TEX_BASE 28
|
#define REG_TEX_BASE 28
|
||||||
|
|
||||||
/* Texture opcodes... maybe? */
|
enum mali_texture_op {
|
||||||
#define TEXTURE_OP_NORMAL 0x11 /* texture */
|
TEXTURE_OP_NORMAL = 1, /* texture */
|
||||||
#define TEXTURE_OP_LOD 0x12 /* textureLod */
|
TEXTURE_OP_LOD = 2, /* textureLod */
|
||||||
#define TEXTURE_OP_TEXEL_FETCH 0x14 /* texelFetch */
|
TEXTURE_OP_TEXEL_FETCH = 4,
|
||||||
|
TEXTURE_OP_BARRIER = 11,
|
||||||
/* Implements barrier() */
|
TEXTURE_OP_DERIVATIVE = 13
|
||||||
#define TEXTURE_OP_BARRIER 0x0B
|
};
|
||||||
|
|
||||||
/* Computes horizontal and vertical derivatives respectively. Use with a float
|
|
||||||
* sampler and a "2D" texture. Leave texture/sampler IDs as zero; they ought
|
|
||||||
* to be ignored. Only works for fp32 on 64-bit at a time, so derivatives of a
|
|
||||||
* vec4 require 2 texture ops. For some reason, the blob computes both X and Y
|
|
||||||
* derivatives at the same time and just throws out whichever is unused; it's
|
|
||||||
* not known if this is a quirk of the hardware or just of the blob. */
|
|
||||||
|
|
||||||
#define TEXTURE_OP_DFDX 0x0D
|
|
||||||
#define TEXTURE_OP_DFDY 0x1D
|
|
||||||
|
|
||||||
enum mali_sampler_type {
|
enum mali_sampler_type {
|
||||||
MALI_SAMPLER_UNK = 0x0,
|
MALI_SAMPLER_UNK = 0x0,
|
||||||
|
@ -657,15 +647,29 @@ enum mali_sampler_type {
|
||||||
MALI_SAMPLER_SIGNED = 0x3, /* isampler */
|
MALI_SAMPLER_SIGNED = 0x3, /* isampler */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Texture modes */
|
||||||
|
enum mali_texture_mode {
|
||||||
|
TEXTURE_NORMAL = 1,
|
||||||
|
TEXTURE_SHADOW = 5,
|
||||||
|
TEXTURE_GATHER_X = 8,
|
||||||
|
TEXTURE_GATHER_Y = 9,
|
||||||
|
TEXTURE_GATHER_Z = 10,
|
||||||
|
TEXTURE_GATHER_W = 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mali_derivative_mode {
|
||||||
|
TEXTURE_DFDX = 0,
|
||||||
|
TEXTURE_DFDY = 1,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
__attribute__((__packed__))
|
__attribute__((__packed__))
|
||||||
{
|
{
|
||||||
unsigned type : 4;
|
unsigned type : 4;
|
||||||
unsigned next_type : 4;
|
unsigned next_type : 4;
|
||||||
|
|
||||||
unsigned op : 6;
|
enum mali_texture_op op : 4;
|
||||||
unsigned shadow : 1;
|
unsigned mode : 4;
|
||||||
unsigned is_gather : 1;
|
|
||||||
|
|
||||||
/* A little obscure, but last is set for the last texture operation in
|
/* A little obscure, but last is set for the last texture operation in
|
||||||
* a shader. cont appears to just be last's opposite (?). Yeah, I know,
|
* a shader. cont appears to just be last's opposite (?). Yeah, I know,
|
||||||
|
|
|
@ -2065,6 +2065,15 @@ pan_attach_constant_bias(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum mali_texture_mode
|
||||||
|
mdg_texture_mode(nir_tex_instr *instr)
|
||||||
|
{
|
||||||
|
if (instr->is_shadow)
|
||||||
|
return TEXTURE_SHADOW;
|
||||||
|
else
|
||||||
|
return TEXTURE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
|
emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
|
||||||
unsigned midgard_texop)
|
unsigned midgard_texop)
|
||||||
|
@ -2099,7 +2108,7 @@ emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
|
||||||
.format = midgard_tex_format(instr->sampler_dim),
|
.format = midgard_tex_format(instr->sampler_dim),
|
||||||
.texture_handle = texture_index,
|
.texture_handle = texture_index,
|
||||||
.sampler_handle = sampler_index,
|
.sampler_handle = sampler_index,
|
||||||
.shadow = instr->is_shadow,
|
.mode = mdg_texture_mode(instr)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,18 +50,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
mir_derivative_op(nir_op op)
|
mir_derivative_mode(nir_op op)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case nir_op_fddx:
|
case nir_op_fddx:
|
||||||
case nir_op_fddx_fine:
|
case nir_op_fddx_fine:
|
||||||
case nir_op_fddx_coarse:
|
case nir_op_fddx_coarse:
|
||||||
return TEXTURE_OP_DFDX;
|
return TEXTURE_DFDX;
|
||||||
|
|
||||||
case nir_op_fddy:
|
case nir_op_fddy:
|
||||||
case nir_op_fddy_fine:
|
case nir_op_fddy_fine:
|
||||||
case nir_op_fddy_coarse:
|
case nir_op_fddy_coarse:
|
||||||
return TEXTURE_OP_DFDY;
|
return TEXTURE_DFDY;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unreachable("Invalid derivative op");
|
unreachable("Invalid derivative op");
|
||||||
|
@ -82,8 +82,7 @@ mir_op_computes_derivatives(gl_shader_stage stage, unsigned op)
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case TEXTURE_OP_NORMAL:
|
case TEXTURE_OP_NORMAL:
|
||||||
case TEXTURE_OP_DFDX:
|
case TEXTURE_OP_DERIVATIVE:
|
||||||
case TEXTURE_OP_DFDY:
|
|
||||||
assert(stage == MESA_SHADER_FRAGMENT);
|
assert(stage == MESA_SHADER_FRAGMENT);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
@ -106,8 +105,9 @@ midgard_emit_derivatives(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
.src = { ~0, nir_src_index(ctx, &instr->src[0].src), ~0, ~0 },
|
.src = { ~0, nir_src_index(ctx, &instr->src[0].src), ~0, ~0 },
|
||||||
.swizzle = SWIZZLE_IDENTITY_4,
|
.swizzle = SWIZZLE_IDENTITY_4,
|
||||||
.src_types = { nir_type_float32, nir_type_float32 },
|
.src_types = { nir_type_float32, nir_type_float32 },
|
||||||
.op = mir_derivative_op(instr->op),
|
.op = TEXTURE_OP_DERIVATIVE,
|
||||||
.texture = {
|
.texture = {
|
||||||
|
.mode = mir_derivative_mode(instr->op),
|
||||||
.format = 2,
|
.format = 2,
|
||||||
.in_reg_full = 1,
|
.in_reg_full = 1,
|
||||||
.out_full = 1,
|
.out_full = 1,
|
||||||
|
@ -126,7 +126,7 @@ midgard_lower_derivatives(compiler_context *ctx, midgard_block *block)
|
||||||
{
|
{
|
||||||
mir_foreach_instr_in_block_safe(block, ins) {
|
mir_foreach_instr_in_block_safe(block, ins) {
|
||||||
if (ins->type != TAG_TEXTURE_4) continue;
|
if (ins->type != TAG_TEXTURE_4) continue;
|
||||||
if (!OP_IS_DERIVATIVE(ins->op)) continue;
|
if (ins->op != TEXTURE_OP_DERIVATIVE) continue;
|
||||||
|
|
||||||
/* Check if we need to split */
|
/* Check if we need to split */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue