}
static bool
-midgard_op_has_helpers(unsigned op, bool gather)
+midgard_op_has_helpers(unsigned op)
{
- if (gather)
- return true;
-
switch (op) {
case TEXTURE_OP_NORMAL:
- case TEXTURE_OP_DFDX:
- case TEXTURE_OP_DFDY:
+ case TEXTURE_OP_DERIVATIVE:
return true;
default:
return false;
}
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) {
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_DFDX, "dFdx");
- DEFINE_CASE(TEXTURE_OP_DFDY, "dFdy");
+ DEFINE_CASE(TEXTURE_OP_DERIVATIVE, "derivative");
default:
fprintf(fp, "tex_%X", op);
#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
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;
-
- midg_stats.helper_invocations |=
- midgard_op_has_helpers(texture->op, texture->is_gather);
+ midg_stats.helper_invocations |= midgard_op_has_helpers(texture->op);
/* 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 */
if (texture->op == TEXTURE_OP_BARRIER) {
else if (texture->type == TAG_TEXTURE_4_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 */
print_texture_format(fp, texture->format);
/* Instruction "modifiers" parallel the ALU instructions. */
- if (texture->shadow)
- fprintf(fp, ".shadow");
-
if (texture->cont)
fprintf(fp, ".cont");
op == midgard_alu_op_fcsel \
)
-#define OP_IS_DERIVATIVE(op) ( \
- op == TEXTURE_OP_DFDX || \
- op == TEXTURE_OP_DFDY \
- )
-
#define OP_IS_UNSIGNED_CMP(op) ( \
op == midgard_alu_op_ult || \
op == midgard_alu_op_ule \
/* Texture pipeline results are in r28-r29 */
#define REG_TEX_BASE 28
-/* Texture opcodes... maybe? */
-#define TEXTURE_OP_NORMAL 0x11 /* texture */
-#define TEXTURE_OP_LOD 0x12 /* textureLod */
-#define TEXTURE_OP_TEXEL_FETCH 0x14 /* texelFetch */
-
-/* Implements barrier() */
-#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_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
+};
enum mali_sampler_type {
MALI_SAMPLER_UNK = 0x0,
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
__attribute__((__packed__))
{
unsigned type : 4;
unsigned next_type : 4;
- unsigned op : 6;
- unsigned shadow : 1;
- unsigned is_gather : 1;
+ enum mali_texture_op op : 4;
+ unsigned mode : 4;
/* 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,
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
emit_texop_native(compiler_context *ctx, nir_tex_instr *instr,
unsigned midgard_texop)
.format = midgard_tex_format(instr->sampler_dim),
.texture_handle = texture_index,
.sampler_handle = sampler_index,
- .shadow = instr->is_shadow,
+ .mode = mdg_texture_mode(instr)
}
};
*/
static unsigned
-mir_derivative_op(nir_op op)
+mir_derivative_mode(nir_op op)
{
switch (op) {
case nir_op_fddx:
case nir_op_fddx_fine:
case nir_op_fddx_coarse:
- return TEXTURE_OP_DFDX;
+ return TEXTURE_DFDX;
case nir_op_fddy:
case nir_op_fddy_fine:
case nir_op_fddy_coarse:
- return TEXTURE_OP_DFDY;
+ return TEXTURE_DFDY;
default:
unreachable("Invalid derivative op");
switch (op) {
case TEXTURE_OP_NORMAL:
- case TEXTURE_OP_DFDX:
- case TEXTURE_OP_DFDY:
+ case TEXTURE_OP_DERIVATIVE:
assert(stage == MESA_SHADER_FRAGMENT);
return true;
default:
.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 = mir_derivative_op(instr->op),
+ .op = TEXTURE_OP_DERIVATIVE,
.texture = {
+ .mode = mir_derivative_mode(instr->op),
.format = 2,
.in_reg_full = 1,
.out_full = 1,
{
mir_foreach_instr_in_block_safe(block, ins) {
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 */