* implicitly */
bool
-mir_op_computes_derivatives(unsigned op)
+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)
+ return false;
+
switch (op) {
case TEXTURE_OP_NORMAL:
case TEXTURE_OP_DFDX:
case TEXTURE_OP_DFDY:
+ assert(stage == MESA_SHADER_FRAGMENT);
return true;
default:
return false;
midgard_instruction ins = {
.type = TAG_TEXTURE_4,
.mask = mask_of(nr_components),
- .dest = nir_dest_index(ctx, &instr->dest.dest),
- .src = { nir_alu_src_index(ctx, &instr->src[0]), ~0, ~0 },
+ .dest = nir_dest_index(&instr->dest.dest),
+ .dest_type = nir_type_float32,
+ .src = { ~0, nir_src_index(ctx, &instr->src[0].src), ~0, ~0 },
+ .swizzle = SWIZZLE_IDENTITY_4,
+ .src_types = { nir_type_float32, nir_type_float32 },
.texture = {
.op = mir_derivative_op(instr->op),
.format = MALI_TEX_2D,
- .swizzle = SWIZZLE_XYXX,
- .in_reg_swizzle = SWIZZLE_XYXX,
-
.in_reg_full = 1,
.out_full = 1,
.sampler_type = MALI_SAMPLER_FLOAT,
ins.mask &= instr->dest.write_mask;
emit_mir_instruction(ctx, ins);
-
- /* TODO: Set .cont/.last automatically via dataflow analysis */
- ctx->texture_op_count++;
}
void
dup.mask &= 0b1100;
/* Fixup swizzles */
- assert(ins->texture.swizzle == SWIZZLE_XYXX);
- assert(ins->texture.in_reg_swizzle == SWIZZLE_XYXX);
- dup.texture.swizzle = SWIZZLE_XXXY;
- dup.texture.in_reg_swizzle = SWIZZLE_ZWWW;
+ dup.swizzle[0][0] = dup.swizzle[0][1] = dup.swizzle[0][2] = COMPONENT_X;
+ dup.swizzle[0][3] = COMPONENT_Y;
+
+ dup.swizzle[1][0] = COMPONENT_Z;
+ dup.swizzle[1][1] = dup.swizzle[1][2] = dup.swizzle[1][3] = COMPONENT_W;
/* Insert the new instruction */
mir_insert_instruction_before(ctx, mir_next_op(ins), dup);
- /* TODO: Set .cont/.last automatically via dataflow analysis */
- ctx->texture_op_count++;
-
/* We'll need both instructions to write to the same index, so
* rewrite to use a register */