Example #1
0
/**
 * TGSI transform prolog callback.
 */
static void
aa_transform_prolog(struct tgsi_transform_context *ctx)
{
   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
   uint i;

   /* find free sampler */
   aactx->freeSampler = free_bit(aactx->samplersUsed);
   if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
      aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;

   /* find two free temp regs */
   for (i = 0; i < 32; i++) {
      if ((aactx->tempsUsed & (1 << i)) == 0) {
      /* found a free temp */
      if (aactx->colorTemp < 0)
         aactx->colorTemp  = i;
      else if (aactx->texTemp < 0)
         aactx->texTemp  = i;
      else
         break;
      }
   }
   assert(aactx->colorTemp >= 0);
   assert(aactx->texTemp >= 0);

   /* declare new generic input/texcoord */
   tgsi_transform_input_decl(ctx, aactx->maxInput + 1,
                             TGSI_SEMANTIC_GENERIC, aactx->maxGeneric + 1,
                             TGSI_INTERPOLATE_LINEAR);

   /* declare new sampler */
   tgsi_transform_sampler_decl(ctx, aactx->freeSampler);

   /* declare new temp regs */
   tgsi_transform_temp_decl(ctx, aactx->texTemp);
   tgsi_transform_temp_decl(ctx, aactx->colorTemp);
}
Example #2
0
static void
transform_instr(struct tgsi_transform_context *tctx,
                struct tgsi_full_instruction *current_inst)
{
   struct tgsi_atifs_transform *ctx = tgsi_atifs_transform(tctx);

   if (ctx->first_instruction_emitted)
      goto transform_inst;

   ctx->first_instruction_emitted = true;

   if (ctx->key->fog) {
      /* add a new temp for the fog factor */
      ctx->fog_factor_temp = ctx->info.file_max[TGSI_FILE_TEMPORARY] + 1;
      tgsi_transform_temp_decl(tctx, ctx->fog_factor_temp);

      /* add immediates for clamp */
      ctx->fog_clamp_imm = ctx->info.immediate_count;
      tgsi_transform_immediate_decl(tctx, 1.0f, 0.0f, 0.0f, 0.0f);
   }

transform_inst:
   if (current_inst->Instruction.Opcode == TGSI_OPCODE_TEX) {
      /* fix texture target */
      unsigned newtarget = ctx->key->texture_targets[current_inst->Src[1].Register.Index];
      if (newtarget)
         current_inst->Texture.Texture = newtarget;

   } else if (ctx->key->fog && current_inst->Instruction.Opcode == TGSI_OPCODE_MOV &&
              current_inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) {
      struct tgsi_full_instruction inst;
      unsigned i;
      int fogc_index = -1;
      int reg0_index = current_inst->Src[0].Register.Index;

      /* find FOGC input */
      for (i = 0; i < ctx->info.num_inputs; i++) {
         if (ctx->info.input_semantic_name[i] == TGSI_SEMANTIC_FOG) {
            fogc_index = i;
            break;
         }
      }
      if (fogc_index < 0) {
         /* should never be reached, because fog coord input is always declared */
         tctx->emit_instruction(tctx, current_inst);
         return;
      }

      /* compute the 1 component fog factor f */
      if (ctx->key->fog == 1) {
         /* LINEAR formula: f = (end - z) / (end - start)
          * with optimized parameters:
          *    f = MAD(fogcoord, oparams.x, oparams.y)
          */
         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_MAD;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 3;
         SET_SRC(&inst, 0, TGSI_FILE_INPUT, fogc_index, X, Y, Z, W);
         SET_SRC(&inst, 1, TGSI_FILE_CONSTANT, MAX_NUM_FRAGMENT_CONSTANTS_ATI, X, X, X, X);
         SET_SRC(&inst, 2, TGSI_FILE_CONSTANT, MAX_NUM_FRAGMENT_CONSTANTS_ATI, Y, Y, Y, Y);
         tctx->emit_instruction(tctx, &inst);
      } else if (ctx->key->fog == 2) {
         /* EXP formula: f = exp(-dens * z)
          * with optimized parameters:
          *    f = MUL(fogcoord, oparams.z); f= EX2(-f)
          */
         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_MUL;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 2;
         SET_SRC(&inst, 0, TGSI_FILE_INPUT, fogc_index, X, Y, Z, W);
         SET_SRC(&inst, 1, TGSI_FILE_CONSTANT, MAX_NUM_FRAGMENT_CONSTANTS_ATI, Z, Z, Z, Z);
         tctx->emit_instruction(tctx, &inst);

         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_EX2;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 1;
         SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, Y, Z, W);
         inst.Src[0].Register.Negate = 1;
         tctx->emit_instruction(tctx, &inst);
      } else if (ctx->key->fog == 3) {
         /* EXP2 formula: f = exp(-(dens * z)^2)
          * with optimized parameters:
          *    f = MUL(fogcoord, oparams.w); f=MUL(f, f); f= EX2(-f)
          */
         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_MUL;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 2;
         SET_SRC(&inst, 0, TGSI_FILE_INPUT, fogc_index, X, Y, Z, W);
         SET_SRC(&inst, 1, TGSI_FILE_CONSTANT, MAX_NUM_FRAGMENT_CONSTANTS_ATI, W, W, W, W);
         tctx->emit_instruction(tctx, &inst);

         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_MUL;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 2;
         SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, Y, Z, W);
         SET_SRC(&inst, 1, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, Y, Z, W);
         tctx->emit_instruction(tctx, &inst);

         inst = tgsi_default_full_instruction();
         inst.Instruction.Opcode = TGSI_OPCODE_EX2;
         inst.Instruction.NumDstRegs = 1;
         inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
         inst.Dst[0].Register.Index = ctx->fog_factor_temp;
         inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
         inst.Instruction.NumSrcRegs = 1;
         SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, Y, Z, W);
         inst.Src[0].Register.Negate ^= 1;
         tctx->emit_instruction(tctx, &inst);
      }
      /* f = CLAMP(f, 0.0, 1.0) */
      inst = tgsi_default_full_instruction();
      inst.Instruction.Opcode = TGSI_OPCODE_CLAMP;
      inst.Instruction.NumDstRegs = 1;
      inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
      inst.Dst[0].Register.Index = ctx->fog_factor_temp;
      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
      inst.Instruction.NumSrcRegs = 3;
      SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, Y, Z, W);
      SET_SRC(&inst, 1, TGSI_FILE_IMMEDIATE, ctx->fog_clamp_imm, Y, Y, Y, Y); // 0.0
      SET_SRC(&inst, 2, TGSI_FILE_IMMEDIATE, ctx->fog_clamp_imm, X, X, X, X); // 1.0
      tctx->emit_instruction(tctx, &inst);

      /* REG0 = LRP(f, REG0, fogcolor) */
      inst = tgsi_default_full_instruction();
      inst.Instruction.Opcode = TGSI_OPCODE_LRP;
      inst.Instruction.NumDstRegs = 1;
      inst.Dst[0].Register.File  = TGSI_FILE_TEMPORARY;
      inst.Dst[0].Register.Index = reg0_index;
      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
      inst.Instruction.NumSrcRegs = 3;
      SET_SRC(&inst, 0, TGSI_FILE_TEMPORARY, ctx->fog_factor_temp, X, X, X, Y);
      SET_SRC(&inst, 1, TGSI_FILE_TEMPORARY, reg0_index, X, Y, Z, W);
      SET_SRC(&inst, 2, TGSI_FILE_CONSTANT, MAX_NUM_FRAGMENT_CONSTANTS_ATI + 1, X, Y, Z, W);
      tctx->emit_instruction(tctx, &inst);
   }

   tctx->emit_instruction(tctx, current_inst);
}
Example #3
0
/**
 * TGSI transform callback.
 * Insert new declarations and instructions before first instruction.
 */
static void
aa_transform_prolog(struct tgsi_transform_context *ctx)
{
   /* emit our new declarations before the first instruction */
   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
   struct tgsi_full_instruction newInst;
   const int texInput = aactx->maxInput + 1;
   int tmp0;
   uint i;

   /* find two free temp regs */
   for (i = 0; i < 32; i++) {
      if ((aactx->tempsUsed & (1 << i)) == 0) {
         /* found a free temp */
         if (aactx->tmp0 < 0)
            aactx->tmp0 = i;
         else if (aactx->colorTemp < 0)
            aactx->colorTemp = i;
         else
            break;
      }
   }

   assert(aactx->colorTemp != aactx->tmp0);

   tmp0 = aactx->tmp0;

   /* declare new generic input/texcoord */
   tgsi_transform_input_decl(ctx, texInput,
                             TGSI_SEMANTIC_GENERIC, aactx->maxGeneric + 1,
                             TGSI_INTERPOLATE_LINEAR);

   /* declare new temp regs */
   tgsi_transform_temp_decl(ctx, tmp0);
   tgsi_transform_temp_decl(ctx, aactx->colorTemp);

   /*
    * Emit code to compute fragment coverage, kill if outside point radius
    *
    * Temp reg0 usage:
    *  t0.x = distance of fragment from center point
    *  t0.y = boolean, is t0.x > 1.0, also misc temp usage
    *  t0.z = temporary for computing 1/(1-k) value
    *  t0.w = final coverage value
    */

   /* MUL t0.xy, tex, tex;  # compute x^2, y^2 */
   tgsi_transform_op2_inst(ctx, TGSI_OPCODE_MUL,
                           TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_XY,
                           TGSI_FILE_INPUT, texInput,
                           TGSI_FILE_INPUT, texInput);

   /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_ADD,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_X,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_X,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y);

#if NORMALIZE  /* OPTIONAL normalization of length */
   /* RSQ t0.x, t0.x; */
   tgsi_transform_op1_inst(ctx, TGSI_OPCODE_RSQ,
                           TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_X,
                           TGSI_FILE_TEMPORARY, tmp0);

   /* RCP t0.x, t0.x; */
   tgsi_transform_op1_inst(ctx, TGSI_OPCODE_RCP,
                           TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_X,
                           TGSI_FILE_TEMPORARY, tmp0);
#endif

   /* SGT t0.y, t0.xxxx, tex.wwww;  # bool b = d > 1 (NOTE tex.w == 1) */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SGT,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_Y,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_X,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W);

   /* KILL_IF -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
   tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y);

   /* compute coverage factor = (1-d)/(1-k) */

   /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SUB,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_Z,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_Z);

   /* RCP t0.z, t0.z;  # t0.z = 1 / m */
   newInst = tgsi_default_full_instruction();
   newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
   newInst.Instruction.NumDstRegs = 1;
   newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
   newInst.Dst[0].Register.Index = tmp0;
   newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Z;
   newInst.Instruction.NumSrcRegs = 1;
   newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
   newInst.Src[0].Register.Index = tmp0;
   newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Z;
   ctx->emit_instruction(ctx, &newInst);

   /* SUB t0.y, 1, t0.x;  # d = 1 - d */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SUB,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_Y,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_X);

   /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MUL,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_W,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Z);

   /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
   tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SLE,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_Y,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_X,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_Z);

   /* CMP t0.w, -t0.y, tex.w, t0.w;
    *  # if -t0.y < 0 then
    *       t0.w = 1
    *    else
    *       t0.w = t0.w
    */
   tgsi_transform_op3_swz_inst(ctx, TGSI_OPCODE_CMP,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_W,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y, 1,
                               TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W,
                               TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_W);
}