示例#1
0
/** helper for building simple TGSI instruction, one src register */
static void
build_tgsi_instruction1(struct tgsi_full_instruction *inst,
                        int opcode,
                        int dstFile, int dstIndex, int writemask,
                        int srcFile1, int srcIndex1)
{
   *inst = tgsi_default_full_instruction();

   inst->Instruction.Opcode = opcode;

   inst->Instruction.NumDstRegs = 1;
   inst->FullDstRegisters[0].DstRegister.File = dstFile;
   inst->FullDstRegisters[0].DstRegister.Index = dstIndex;
   inst->FullDstRegisters[0].DstRegister.WriteMask = writemask;

   inst->Instruction.NumSrcRegs = 1;
   inst->FullSrcRegisters[0].SrcRegister.File = srcFile1;
   inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1;
}
示例#2
0
static void
passthrough_edgeflag(struct tgsi_transform_context *tctx)
{
   struct tgsi_emulation_context *ctx = tgsi_emulation_context(tctx);
   struct tgsi_full_declaration decl;
   struct tgsi_full_instruction new_inst;

   /* Input */
   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_INPUT;
   decl.Range.First = decl.Range.Last = ctx->info.num_inputs;
   tctx->emit_declaration(tctx, &decl);

   /* Output */
   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_OUTPUT;
   decl.Declaration.Semantic = true;
   decl.Range.First = decl.Range.Last = ctx->info.num_outputs;
   decl.Semantic.Name = TGSI_SEMANTIC_EDGEFLAG;
   decl.Semantic.Index = 0;
   tctx->emit_declaration(tctx, &decl);

   /* MOV */
   new_inst = tgsi_default_full_instruction();
   new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;

   new_inst.Instruction.NumDstRegs = 1;
   new_inst.Dst[0].Register.File  = TGSI_FILE_OUTPUT;
   new_inst.Dst[0].Register.Index = ctx->info.num_outputs;
   new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;

   new_inst.Instruction.NumSrcRegs = 1;
   new_inst.Src[0].Register.File  = TGSI_FILE_INPUT;
   new_inst.Src[0].Register.Index = ctx->info.num_inputs;
   new_inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
   new_inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
   new_inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
   new_inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X;

   tctx->emit_instruction(tctx, &new_inst);
}
示例#3
0
static boolean
parse_instruction(
   struct translate_ctx *ctx,
   boolean has_label )
{
   uint i;
   uint saturate = 0;
   const struct tgsi_opcode_info *info;
   struct tgsi_full_instruction inst;
   const char *cur;
   uint advance;

   inst = tgsi_default_full_instruction();

   /* Parse predicate.
    */
   eat_opt_white( &ctx->cur );
   if (*ctx->cur == '(') {
      uint file;
      int index;
      uint swizzle[4];
      boolean parsed_swizzle;

      inst.Instruction.Predicate = 1;

      ctx->cur++;
      if (*ctx->cur == '!') {
         ctx->cur++;
         inst.Predicate.Negate = 1;
      }

      if (!parse_register_1d( ctx, &file, &index ))
         return FALSE;

      if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) {
         if (parsed_swizzle) {
            inst.Predicate.SwizzleX = swizzle[0];
            inst.Predicate.SwizzleY = swizzle[1];
            inst.Predicate.SwizzleZ = swizzle[2];
            inst.Predicate.SwizzleW = swizzle[3];
         }
      }

      if (*ctx->cur != ')') {
         report_error( ctx, "Expected `)'" );
         return FALSE;
      }

      ctx->cur++;
   }

   /* Parse instruction name.
    */
   eat_opt_white( &ctx->cur );
   for (i = 0; i < TGSI_OPCODE_LAST; i++) {
      cur = ctx->cur;

      info = tgsi_get_opcode_info( i );
      if (match_inst(&cur, &saturate, info)) {
         if (info->num_dst + info->num_src + info->is_tex == 0) {
            ctx->cur = cur;
            break;
         }
         else if (*cur == '\0' || eat_white( &cur )) {
            ctx->cur = cur;
            break;
         }
      }
   }
   if (i == TGSI_OPCODE_LAST) {
      if (has_label)
         report_error( ctx, "Unknown opcode" );
      else
         report_error( ctx, "Expected `DCL', `IMM' or a label" );
      return FALSE;
   }

   inst.Instruction.Opcode = i;
   inst.Instruction.Saturate = saturate;
   inst.Instruction.NumDstRegs = info->num_dst;
   inst.Instruction.NumSrcRegs = info->num_src;

   if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
      /*
       * These are not considered tex opcodes here (no additional
       * target argument) however we're required to set the Texture
       * bit so we can set the number of tex offsets.
       */
      inst.Instruction.Texture = 1;
      inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
   }

   if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
       i == TGSI_OPCODE_RESQ) {
      inst.Instruction.Memory = 1;
      inst.Memory.Qualifier = 0;
   }

   /* Parse instruction operands.
    */
   for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
      if (i > 0) {
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ctx->cur++;
         eat_opt_white( &ctx->cur );
      }

      if (i < info->num_dst) {
         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
            return FALSE;
      }
      else if (i < info->num_dst + info->num_src) {
         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
            return FALSE;
      }
      else {
         uint j;

         for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
            if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
               inst.Instruction.Texture = 1;
               inst.Texture.Texture = j;
               break;
            }
         }
         if (j == TGSI_TEXTURE_COUNT) {
            report_error( ctx, "Expected texture target" );
            return FALSE;
         }
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   for (i = 0; inst.Instruction.Texture && *cur == ','; i++) {
         cur++;
         eat_opt_white( &cur );
         ctx->cur = cur;
         if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] ))
            return FALSE;
         cur = ctx->cur;
         eat_opt_white( &cur );
   }
   inst.Texture.NumOffsets = i;

   cur = ctx->cur;
   eat_opt_white(&cur);
   for (i = 0; inst.Instruction.Memory && *cur == ','; i++) {
      uint j;
      cur++;
      eat_opt_white(&cur);
      ctx->cur = cur;
      for (j = 0; j < 3; j++) {
         if (str_match_nocase_whole(&ctx->cur, tgsi_memory_names[j])) {
            inst.Memory.Qualifier |= 1U << j;
            break;
         }
      }
      if (j == 3) {
         report_error(ctx, "Expected memory qualifier");
         return FALSE;
      }
      cur = ctx->cur;
      eat_opt_white(&cur);
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (info->is_branch && *cur == ':') {
      uint target;

      cur++;
      eat_opt_white( &cur );
      if (!parse_uint( &cur, &target )) {
         report_error( ctx, "Expected a label" );
         return FALSE;
      }
      inst.Instruction.Label = 1;
      inst.Label.Label = target;
      ctx->cur = cur;
   }

   advance = tgsi_build_full_instruction(
      &inst,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );
   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}
示例#4
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);
}
示例#5
0
/**
 * TGSI instruction transform callback.
 * Replace writes to result.color w/ a temp reg.
 * Upon END instruction, insert texture sampling code for antialiasing.
 */
static void
aa_transform_inst(struct tgsi_transform_context *ctx,
                  struct tgsi_full_instruction *inst)
{
   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
   struct tgsi_full_instruction newInst;

   if (aactx->firstInstruction) {
      /* emit our new declarations before the first instruction */

      struct tgsi_full_declaration decl;
      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 */
      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_INPUT;
      /* XXX this could be linear... */
      decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
      decl.Declaration.Semantic = 1;
      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
      decl.Semantic.Index = aactx->maxGeneric + 1;
      decl.Range.First = 
      decl.Range.Last = texInput;
      ctx->emit_declaration(ctx, &decl);

      /* declare new temp regs */
      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_TEMPORARY;
      decl.Range.First = 
      decl.Range.Last = tmp0;
      ctx->emit_declaration(ctx, &decl);

      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_TEMPORARY;
      decl.Range.First = 
      decl.Range.Last = aactx->colorTemp;
      ctx->emit_declaration(ctx, &decl);

      aactx->firstInstruction = FALSE;


      /*
       * 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 */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
      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_XY;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
      newInst.Src[0].Register.Index = texInput;
      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
      newInst.Src[1].Register.Index = texInput;
      ctx->emit_instruction(ctx, &newInst);

      /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
      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_X;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[1].Register.Index = tmp0;
      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_Y;
      ctx->emit_instruction(ctx, &newInst);

#if NORMALIZE  /* OPTIONAL normalization of length */
      /* RSQ t0.x, t0.x; */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
      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_X;
      newInst.Instruction.NumSrcRegs = 1;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      ctx->emit_instruction(ctx, &newInst);

      /* RCP t0.x, t0.x; */
      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_X;
      newInst.Instruction.NumSrcRegs = 1;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      ctx->emit_instruction(ctx, &newInst);
#endif

      /* SGT t0.y, t0.xxxx, tex.wwww;  # bool b = d > 1 (NOTE tex.w == 1) */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
      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_Y;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
      newInst.Src[1].Register.Index = texInput;
      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
      ctx->emit_instruction(ctx, &newInst);

      /* KIL -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
      newInst.Instruction.NumDstRegs = 0;
      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_Y;
      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.Negate = 1;
      ctx->emit_instruction(ctx, &newInst);


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

      /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
      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 = 2;
      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
      newInst.Src[0].Register.Index = texInput;
      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_W;
      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
      newInst.Src[1].Register.Index = texInput;
      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z;
      ctx->emit_instruction(ctx, &newInst);

      /* 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 */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
      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_Y;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
      newInst.Src[0].Register.Index = texInput;
      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_W;
      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[1].Register.Index = tmp0;
      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_X;
      ctx->emit_instruction(ctx, &newInst);

      /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
      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_W;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[1].Register.Index = tmp0;
      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_Z;
      ctx->emit_instruction(ctx, &newInst);

      /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
      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_Y;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
      newInst.Src[1].Register.Index = texInput;
      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Z;
      ctx->emit_instruction(ctx, &newInst);

      /* CMP t0.w, -t0.y, tex.w, t0.w;
       *  # if -t0.y < 0 then
       *       t0.w = 1
       *    else
       *       t0.w = t0.w
       */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
      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_W;
      newInst.Instruction.NumSrcRegs = 3;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = tmp0;
      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
      newInst.Src[0].Register.Negate = 1;
      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
      newInst.Src[1].Register.Index = texInput;
      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_W;
      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_W;
      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W;
      newInst.Src[2].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[2].Register.Index = tmp0;
      newInst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_W;
      newInst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_W;
      newInst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_W;
      newInst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W;
      ctx->emit_instruction(ctx, &newInst);

   }

   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
      /* add alpha modulation code at tail of program */

      /* MOV result.color.xyz, colorTemp; */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
      newInst.Instruction.NumDstRegs = 1;
      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
      newInst.Dst[0].Register.Index = aactx->colorOutput;
      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
      newInst.Instruction.NumSrcRegs = 1;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = aactx->colorTemp;
      ctx->emit_instruction(ctx, &newInst);

      /* MUL result.color.w, colorTemp, tmp0.w; */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
      newInst.Instruction.NumDstRegs = 1;
      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
      newInst.Dst[0].Register.Index = aactx->colorOutput;
      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = aactx->colorTemp;
      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[1].Register.Index = aactx->tmp0;
      ctx->emit_instruction(ctx, &newInst);
   }
   else {
      /* Not an END instruction.
       * Look for writes to result.color and replace with colorTemp reg.
       */
      uint i;

      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
         struct tgsi_full_dst_register *dst = &inst->Dst[i];
         if (dst->Register.File == TGSI_FILE_OUTPUT &&
             dst->Register.Index == aactx->colorOutput) {
            dst->Register.File = TGSI_FILE_TEMPORARY;
            dst->Register.Index = aactx->colorTemp;
         }
      }
   }

   ctx->emit_instruction(ctx, inst);
}
示例#6
0
void
tgsi_dump_c(
   const struct tgsi_token *tokens,
   uint flags )
{
   struct tgsi_parse_context parse;
   struct tgsi_full_instruction fi;
   struct tgsi_full_declaration fd;
   uint ignored = flags & TGSI_DUMP_C_IGNORED;
   uint deflt = flags & TGSI_DUMP_C_DEFAULT;
   uint instno = 0;

   tgsi_parse_init( &parse, tokens );

   TXT( "tgsi-dump begin -----------------" );

   TXT( "\nMajorVersion: " );
   UID( parse.FullVersion.Version.MajorVersion );
   TXT( "\nMinorVersion: " );
   UID( parse.FullVersion.Version.MinorVersion );
   EOL();

   TXT( "\nHeaderSize: " );
   UID( parse.FullHeader.Header.HeaderSize );
   TXT( "\nBodySize  : " );
   UID( parse.FullHeader.Header.BodySize );
   TXT( "\nProcessor : " );
   ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES );
   EOL();

   fi = tgsi_default_full_instruction();
   fd = tgsi_default_full_declaration();

   while( !tgsi_parse_end_of_tokens( &parse ) ) {
      tgsi_parse_token( &parse );

      TXT( "\nType       : " );
      ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES );
      if( ignored ) {
         TXT( "\nSize       : " );
         UID( parse.FullToken.Token.Size );
         if( deflt || parse.FullToken.Token.Extended ) {
            TXT( "\nExtended   : " );
            UID( parse.FullToken.Token.Extended );
         }
      }

      switch( parse.FullToken.Token.Type ) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         dump_declaration_verbose(
            &parse.FullToken.FullDeclaration,
            ignored,
            deflt,
            &fd );
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         dump_immediate_verbose(
            &parse.FullToken.FullImmediate,
            ignored );
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         dump_instruction_verbose(
            &parse.FullToken.FullInstruction,
            ignored,
            deflt,
            &fi );
         break;

      default:
         assert( 0 );
      }

      EOL();
   }

   TXT( "\ntgsi-dump end -------------------\n" );

   tgsi_parse_free( &parse );
}
/**
 * TGSI instruction transform callback.
 * Replace writes to result.color w/ a temp reg.
 * Upon END instruction, insert texture sampling code for antialiasing.
 */
static void
aa_transform_inst(struct tgsi_transform_context *ctx,
                  struct tgsi_full_instruction *inst)
{
   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;

   if (aactx->firstInstruction) {
      /* emit our new declarations before the first instruction */

      struct tgsi_full_declaration decl;
      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 */
      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_INPUT;
      /* XXX this could be linear... */
      decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
      decl.Declaration.Semantic = 1;
      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
      decl.Semantic.Index = aactx->maxGeneric + 1;
      decl.Range.First = 
      decl.Range.Last = aactx->maxInput + 1;
      ctx->emit_declaration(ctx, &decl);

      /* declare new sampler */
      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_SAMPLER;
      decl.Range.First = 
      decl.Range.Last = aactx->freeSampler;
      ctx->emit_declaration(ctx, &decl);

      /* declare new temp regs */
      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_TEMPORARY;
      decl.Range.First = 
      decl.Range.Last = aactx->texTemp;
      ctx->emit_declaration(ctx, &decl);

      decl = tgsi_default_full_declaration();
      decl.Declaration.File = TGSI_FILE_TEMPORARY;
      decl.Range.First = 
      decl.Range.Last = aactx->colorTemp;
      ctx->emit_declaration(ctx, &decl);

      aactx->firstInstruction = FALSE;
   }

   if (inst->Instruction.Opcode == TGSI_OPCODE_END &&
       aactx->colorOutput != -1) {
      struct tgsi_full_instruction newInst;

      /* TEX */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
      newInst.Instruction.NumDstRegs = 1;
      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Dst[0].Register.Index = aactx->texTemp;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Instruction.Texture = TRUE;
      newInst.Texture.Texture = TGSI_TEXTURE_2D;
      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
      newInst.Src[0].Register.Index = aactx->maxInput + 1;
      newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
      newInst.Src[1].Register.Index = aactx->freeSampler;

      ctx->emit_instruction(ctx, &newInst);

      /* MOV rgb */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
      newInst.Instruction.NumDstRegs = 1;
      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
      newInst.Dst[0].Register.Index = aactx->colorOutput;
      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
      newInst.Instruction.NumSrcRegs = 1;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = aactx->colorTemp;
      ctx->emit_instruction(ctx, &newInst);

      /* MUL alpha */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
      newInst.Instruction.NumDstRegs = 1;
      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
      newInst.Dst[0].Register.Index = aactx->colorOutput;
      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
      newInst.Instruction.NumSrcRegs = 2;
      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[0].Register.Index = aactx->colorTemp;
      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
      newInst.Src[1].Register.Index = aactx->texTemp;
      ctx->emit_instruction(ctx, &newInst);

      /* END */
      newInst = tgsi_default_full_instruction();
      newInst.Instruction.Opcode = TGSI_OPCODE_END;
      newInst.Instruction.NumDstRegs = 0;
      newInst.Instruction.NumSrcRegs = 0;
      ctx->emit_instruction(ctx, &newInst);
   }
   else {
      /* Not an END instruction.
       * Look for writes to result.color and replace with colorTemp reg.
       */
      uint i;

      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
         struct tgsi_full_dst_register *dst = &inst->Dst[i];
         if (dst->Register.File == TGSI_FILE_OUTPUT &&
             dst->Register.Index == aactx->colorOutput) {
            dst->Register.File = TGSI_FILE_TEMPORARY;
            dst->Register.Index = aactx->colorTemp;
         }
      }

      ctx->emit_instruction(ctx, inst);
   }
}
示例#8
0
static void transform_inst(struct tgsi_transform_context *ctx,
                           struct tgsi_full_instruction *inst)
{
    struct vs_transform_context *vsctx = (struct vs_transform_context *) ctx;
    struct tgsi_full_instruction new_inst;
    unsigned i;

    if (!vsctx->first_instruction) {
        vsctx->first_instruction = TRUE;

        /* Insert the generic output for WPOS. */
        emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1,
                    TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs);

        /* Find a free temp for POSITION. */
        for (i = 0; i < Elements(vsctx->temp_used); i++) {
            if (!vsctx->temp_used[i]) {
                emit_temp(ctx, i);
                vsctx->pos_temp = i;
                break;
            }
        }
    }

    if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
        /* MOV OUT[pos_output], TEMP[pos_temp]; */
        new_inst = tgsi_default_full_instruction();
        new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
        new_inst.Instruction.NumDstRegs = 1;
        new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
        new_inst.Dst[0].Register.Index = vsctx->pos_output;
        new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
        new_inst.Instruction.NumSrcRegs = 1;
        new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
        new_inst.Src[0].Register.Index = vsctx->pos_temp;
        ctx->emit_instruction(ctx, &new_inst);

        /* MOV OUT[n-1], TEMP[pos_temp]; */
        new_inst = tgsi_default_full_instruction();
        new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
        new_inst.Instruction.NumDstRegs = 1;
        new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
        new_inst.Dst[0].Register.Index = vsctx->num_outputs - 1;
        new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
        new_inst.Instruction.NumSrcRegs = 1;
        new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
        new_inst.Src[0].Register.Index = vsctx->pos_temp;
        ctx->emit_instruction(ctx, &new_inst);

        vsctx->end_instruction = TRUE;
    } else {
        /* Not an END instruction. */
        /* Fix writes to outputs. */
        for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
            struct tgsi_full_dst_register *dst = &inst->Dst[i];
            if (dst->Register.File == TGSI_FILE_OUTPUT) {
                if (dst->Register.Index == vsctx->pos_output) {
                    /* Replace writes to OUT[pos_output] with TEMP[pos_temp]. */
                    dst->Register.File = TGSI_FILE_TEMPORARY;
                    dst->Register.Index = vsctx->pos_temp;
                } else {
                    /* Not a position, good...
                     * Since we were changing the indices of output decls,
                     * we must redirect writes into them too. */
                    dst->Register.Index = vsctx->out_remap[dst->Register.Index];
                }
            }
        }

        /* Inserting 2 instructions before the END opcode moves all following
         * labels by 2. Subroutines are always after the END opcode so
         * they're always moved. */
        if (inst->Instruction.Opcode == TGSI_OPCODE_CAL) {
            inst->Label.Label += 2;
        }
        /* The labels of the following opcodes are moved only after
         * the END opcode. */
        if (vsctx->end_instruction &&
            (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
             inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
             inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP ||
             inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP)) {
            inst->Label.Label += 2;
        }
    }

    ctx->emit_instruction(ctx, inst);
}
示例#9
0
static boolean
parse_instruction(
   struct translate_ctx *ctx,
   boolean has_label )
{
   uint i;
   uint saturate = TGSI_SAT_NONE;
   const struct tgsi_opcode_info *info;
   struct tgsi_full_instruction inst;
   uint advance;

   inst = tgsi_default_full_instruction();

   /* Parse predicate.
    */
   eat_opt_white( &ctx->cur );
   if (*ctx->cur == '(') {
      uint file;
      int index;
      uint swizzle[4];
      boolean parsed_swizzle;

      inst.Instruction.Predicate = 1;

      ctx->cur++;
      if (*ctx->cur == '!') {
         ctx->cur++;
         inst.Predicate.Negate = 1;
      }

      if (!parse_register_1d( ctx, &file, &index ))
         return FALSE;

      if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
         if (parsed_swizzle) {
            inst.Predicate.SwizzleX = swizzle[0];
            inst.Predicate.SwizzleY = swizzle[1];
            inst.Predicate.SwizzleZ = swizzle[2];
            inst.Predicate.SwizzleW = swizzle[3];
         }
      }

      if (*ctx->cur != ')') {
         report_error( ctx, "Expected `)'" );
         return FALSE;
      }

      ctx->cur++;
   }

   /* Parse instruction name.
    */
   eat_opt_white( &ctx->cur );
   for (i = 0; i < TGSI_OPCODE_LAST; i++) {
      const char *cur = ctx->cur;

      info = tgsi_get_opcode_info( i );
      if (match_inst_mnemonic(&cur, info)) {
         if (str_match_no_case( &cur, "_SATNV" ))
            saturate = TGSI_SAT_MINUS_PLUS_ONE;
         else if (str_match_no_case( &cur, "_SAT" ))
            saturate = TGSI_SAT_ZERO_ONE;

         if (info->num_dst + info->num_src + info->is_tex == 0) {
            if (!is_digit_alpha_underscore( cur )) {
               ctx->cur = cur;
               break;
            }
         }
         else if (*cur == '\0' || eat_white( &cur )) {
            ctx->cur = cur;
            break;
         }
      }
   }
   if (i == TGSI_OPCODE_LAST) {
      if (has_label)
         report_error( ctx, "Unknown opcode" );
      else
         report_error( ctx, "Expected `DCL', `IMM' or a label" );
      return FALSE;
   }

   inst.Instruction.Opcode = i;
   inst.Instruction.Saturate = saturate;
   inst.Instruction.NumDstRegs = info->num_dst;
   inst.Instruction.NumSrcRegs = info->num_src;

   /* Parse instruction operands.
    */
   for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
      if (i > 0) {
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ctx->cur++;
         eat_opt_white( &ctx->cur );
      }

      if (i < info->num_dst) {
         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
            return FALSE;
      }
      else if (i < info->num_dst + info->num_src) {
         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
            return FALSE;
      }
      else {
         uint j;

         for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
            if (str_match_no_case( &ctx->cur, texture_names[j] )) {
               if (!is_digit_alpha_underscore( ctx->cur )) {
                  inst.Instruction.Texture = 1;
                  inst.Texture.Texture = j;
                  break;
               }
            }
         }
         if (j == TGSI_TEXTURE_COUNT) {
            report_error( ctx, "Expected texture target" );
            return FALSE;
         }
      }
   }

   if (info->is_branch) {
      uint target;

      eat_opt_white( &ctx->cur );
      if (*ctx->cur != ':') {
         report_error( ctx, "Expected `:'" );
         return FALSE;
      }
      ctx->cur++;
      eat_opt_white( &ctx->cur );
      if (!parse_uint( &ctx->cur, &target )) {
         report_error( ctx, "Expected a label" );
         return FALSE;
      }
      inst.Instruction.Label = 1;
      inst.Label.Label = target;
   }

   advance = tgsi_build_full_instruction(
      &inst,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );
   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}
示例#10
0
static void
compile_instruction(
   const struct prog_instruction *inst,
   struct tgsi_full_instruction *fullinst,
   const GLuint inputMapping[],
   const GLuint outputMapping[],
   const GLuint immediateMapping[],
   GLboolean indirectAccess,
   GLuint preamble_size,
   GLuint procType,
   GLboolean *insideSubroutine,
   GLint wposTemp)
{
   GLuint i;
   struct tgsi_full_dst_register *fulldst;
   struct tgsi_full_src_register *fullsrc;

   *fullinst = tgsi_default_full_instruction();

   fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );
   fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );
   fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );

   fulldst = &fullinst->FullDstRegisters[0];
   fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL, GL_FALSE );
   fulldst->DstRegister.Index = map_register_file_index(
      fulldst->DstRegister.File,
      inst->DstReg.Index,
      inputMapping,
      outputMapping,
      NULL,
      GL_FALSE );
   fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );

   for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
      GLuint j;

      fullsrc = &fullinst->FullSrcRegisters[i];

      if (procType == TGSI_PROCESSOR_FRAGMENT &&
          inst->SrcReg[i].File == PROGRAM_INPUT &&
          inst->SrcReg[i].Index == FRAG_ATTRIB_WPOS) {
         /* special case of INPUT[WPOS] */
         fullsrc->SrcRegister.File = TGSI_FILE_TEMPORARY;
         fullsrc->SrcRegister.Index = wposTemp;
      }
      else {
         /* any other src register */
         fullsrc->SrcRegister.File = map_register_file(
            inst->SrcReg[i].File,
            inst->SrcReg[i].Index,
            immediateMapping,
            indirectAccess );
         fullsrc->SrcRegister.Index = map_register_file_index(
            fullsrc->SrcRegister.File,
            inst->SrcReg[i].Index,
            inputMapping,
            outputMapping,
            immediateMapping,
            indirectAccess );
      }

      /* swizzle (ext swizzle also depends on negation) */
      {
         GLuint swz[4];
         GLboolean extended = (inst->SrcReg[i].Negate != NEGATE_NONE &&
                               inst->SrcReg[i].Negate != NEGATE_XYZW);
         for( j = 0; j < 4; j++ ) {
            swz[j] = GET_SWZ( inst->SrcReg[i].Swizzle, j );
            if (swz[j] > SWIZZLE_W)
               extended = GL_TRUE;
         }
         if (extended) {
            for (j = 0; j < 4; j++) {
               tgsi_util_set_src_register_extswizzle(&fullsrc->SrcRegisterExtSwz,
                                                     swz[j], j);
            }
         }
         else {
            for (j = 0; j < 4; j++) {
               tgsi_util_set_src_register_swizzle(&fullsrc->SrcRegister,
                                                  swz[j], j);
            }
         }
      }

      if( inst->SrcReg[i].Negate == NEGATE_XYZW ) {
         fullsrc->SrcRegister.Negate = 1;
      }
      else if( inst->SrcReg[i].Negate != NEGATE_NONE ) {
         if( inst->SrcReg[i].Negate & NEGATE_X ) {
            fullsrc->SrcRegisterExtSwz.NegateX = 1;
         }
         if( inst->SrcReg[i].Negate & NEGATE_Y ) {
            fullsrc->SrcRegisterExtSwz.NegateY = 1;
         }
         if( inst->SrcReg[i].Negate & NEGATE_Z ) {
            fullsrc->SrcRegisterExtSwz.NegateZ = 1;
         }
         if( inst->SrcReg[i].Negate & NEGATE_W ) {
            fullsrc->SrcRegisterExtSwz.NegateW = 1;
         }
      }

      if( inst->SrcReg[i].Abs ) {
         fullsrc->SrcRegisterExtMod.Absolute = 1;
      }

      if( inst->SrcReg[i].RelAddr ) {
         fullsrc->SrcRegister.Indirect = 1;

         fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
         fullsrc->SrcRegisterInd.Index = 0;
      }
   }

   switch( inst->Opcode ) {
   case OPCODE_ARL:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
      break;
   case OPCODE_ABS:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
      break;
   case OPCODE_ADD:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
      break;
   case OPCODE_BGNLOOP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP2;
      fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
      break;
   case OPCODE_BGNSUB:
      fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;
      *insideSubroutine = GL_TRUE;
      break;
   case OPCODE_BRA:
      fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;
      break;
   case OPCODE_BRK:
      fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
      break;
   case OPCODE_CAL:
      fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;
      fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
      break;
   case OPCODE_CMP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
      break;
   case OPCODE_CONT:
      fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;
      break;
   case OPCODE_COS:
      fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
      break;
   case OPCODE_DDX:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;
      break;
   case OPCODE_DDY:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;
      break;
   case OPCODE_DP2:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DP2;
      break;
   case OPCODE_DP2A:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DP2A;
      break;
   case OPCODE_DP3:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
      break;
   case OPCODE_DP4:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
      break;
   case OPCODE_DPH:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
      break;
   case OPCODE_DST:
      fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
      break;
   case OPCODE_ELSE:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;
      fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
      break;
   case OPCODE_ENDIF:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;
      break;
   case OPCODE_ENDLOOP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP2;
      fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
      break;
   case OPCODE_ENDSUB:
      fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;
      *insideSubroutine = GL_FALSE;
      break;
   case OPCODE_EX2:
      fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
      break;
   case OPCODE_EXP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;
      break;
   case OPCODE_FLR:
      fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
      break;
   case OPCODE_FRC:
      fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
      break;
   case OPCODE_IF:
      fullinst->Instruction.Opcode = TGSI_OPCODE_IF;
      fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
      break;
   case OPCODE_TRUNC:
      fullinst->Instruction.Opcode = TGSI_OPCODE_TRUNC;
      break;
   case OPCODE_KIL:
      /* conditional */
      fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
      break;
   case OPCODE_KIL_NV:
      /* predicated */
      assert(inst->DstReg.CondMask == COND_TR);
      fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;
      break;
   case OPCODE_LG2:
      fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
      break;
   case OPCODE_LOG:
      fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;
      break;
   case OPCODE_LIT:
      fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
      break;
   case OPCODE_LRP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
      break;
   case OPCODE_MAD:
      fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
      break;
   case OPCODE_MAX:
      fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
      break;
   case OPCODE_MIN:
      fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
      break;
   case OPCODE_MOV:
      fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
      break;
   case OPCODE_MUL:
      fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
      break;
   case OPCODE_NOISE1:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;
      break;
   case OPCODE_NOISE2:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;
      break;
   case OPCODE_NOISE3:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;
      break;
   case OPCODE_NOISE4:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;
      break;
   case OPCODE_NOP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;
      break;
   case OPCODE_NRM3:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NRM;
      break;
   case OPCODE_NRM4:
      fullinst->Instruction.Opcode = TGSI_OPCODE_NRM4;
      break;
   case OPCODE_POW:
      fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
      break;
   case OPCODE_RCP:
      fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
      break;
   case OPCODE_RET:
      /* If RET is used inside main (not a real subroutine) we may want
       * to execute END instead of RET.  TBD...
       */
      if (1 /*  *insideSubroutine */) {
         fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
      }
      else {
         /* inside main() pseudo-function */
         fullinst->Instruction.Opcode = TGSI_OPCODE_END;
      }
      break;
   case OPCODE_RSQ:
      fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
      break;
   case OPCODE_SCS:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
      fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
      break;
   case OPCODE_SEQ:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;
      break;
   case OPCODE_SGE:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
      break;
   case OPCODE_SGT:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;
      break;
   case OPCODE_SIN:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
      break;
   case OPCODE_SLE:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;
      break;
   case OPCODE_SLT:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
      break;
   case OPCODE_SNE:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;
      break;
   case OPCODE_SSG:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SSG;
      break;
   case OPCODE_SUB:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
      break;
   case OPCODE_SWZ:
      fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
      break;
   case OPCODE_TEX:
      /* ordinary texture lookup */
      fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
      fullinst->Instruction.NumSrcRegs = 2;
      fullinst->InstructionExtTexture.Texture =
         map_texture_target( inst->TexSrcTarget, inst->TexShadow );
      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
      break;
   case OPCODE_TXB:
      /* texture lookup with LOD bias */
      fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
      fullinst->Instruction.NumSrcRegs = 2;
      fullinst->InstructionExtTexture.Texture =
         map_texture_target( inst->TexSrcTarget, inst->TexShadow );
      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
      break;
   case OPCODE_TXD:
      /* texture lookup with explicit partial derivatives */
      fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;
      fullinst->Instruction.NumSrcRegs = 4;
      fullinst->InstructionExtTexture.Texture =
         map_texture_target( inst->TexSrcTarget, inst->TexShadow );
      /* src[0] = coord, src[1] = d[strq]/dx, src[2] = d[strq]/dy */
      fullinst->FullSrcRegisters[3].SrcRegister.File = TGSI_FILE_SAMPLER;
      fullinst->FullSrcRegisters[3].SrcRegister.Index = inst->TexSrcUnit;
      break;
   case OPCODE_TXL:
      /* texture lookup with explicit LOD */
      fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;
      fullinst->Instruction.NumSrcRegs = 2;
      fullinst->InstructionExtTexture.Texture =
         map_texture_target( inst->TexSrcTarget, inst->TexShadow );
      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
      break;
   case OPCODE_TXP:
      /* texture lookup with divide by Q component */
      /* convert to TEX w/ special flag for division */
      fullinst->Instruction.Opcode = TGSI_OPCODE_TXP;
      fullinst->Instruction.NumSrcRegs = 2;
      fullinst->InstructionExtTexture.Texture =
         map_texture_target( inst->TexSrcTarget, inst->TexShadow );
      fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
      fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
      break;
   case OPCODE_XPD:
      fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
      fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
      break;
   case OPCODE_END:
      fullinst->Instruction.Opcode = TGSI_OPCODE_END;
      break;
   default:
      assert( 0 );
   }
}
示例#11
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);
}
示例#12
0
文件: tgsi_text.c 项目: chemecse/mesa
static boolean
parse_instruction(
   struct translate_ctx *ctx,
   boolean has_label )
{
   uint i;
   uint saturate = 0;
   uint precise = 0;
   const struct tgsi_opcode_info *info;
   struct tgsi_full_instruction inst;
   const char *cur;
   uint advance;

   inst = tgsi_default_full_instruction();

   /* Parse instruction name.
    */
   eat_opt_white( &ctx->cur );
   for (i = 0; i < TGSI_OPCODE_LAST; i++) {
      cur = ctx->cur;

      info = tgsi_get_opcode_info( i );
      if (match_inst(&cur, &saturate, &precise, info)) {
         if (info->num_dst + info->num_src + info->is_tex == 0) {
            ctx->cur = cur;
            break;
         }
         else if (*cur == '\0' || eat_white( &cur )) {
            ctx->cur = cur;
            break;
         }
      }
   }
   if (i == TGSI_OPCODE_LAST) {
      if (has_label)
         report_error( ctx, "Unknown opcode" );
      else
         report_error( ctx, "Expected `DCL', `IMM' or a label" );
      return FALSE;
   }

   inst.Instruction.Opcode = i;
   inst.Instruction.Saturate = saturate;
   inst.Instruction.Precise = precise;
   inst.Instruction.NumDstRegs = info->num_dst;
   inst.Instruction.NumSrcRegs = info->num_src;

   if (i >= TGSI_OPCODE_SAMPLE && i <= TGSI_OPCODE_GATHER4) {
      /*
       * These are not considered tex opcodes here (no additional
       * target argument) however we're required to set the Texture
       * bit so we can set the number of tex offsets.
       */
      inst.Instruction.Texture = 1;
      inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN;
   }

   if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) ||
       i == TGSI_OPCODE_RESQ) {
      inst.Instruction.Memory = 1;
      inst.Memory.Qualifier = 0;
   }

   assume(info->num_dst <= TGSI_FULL_MAX_DST_REGISTERS);
   assume(info->num_src <= TGSI_FULL_MAX_SRC_REGISTERS);

   /* Parse instruction operands.
    */
   for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) {
      if (i > 0) {
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ctx->cur++;
         eat_opt_white( &ctx->cur );
      }

      if (i < info->num_dst) {
         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
            return FALSE;
      }
      else if (i < info->num_dst + info->num_src) {
         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
            return FALSE;
      }
      else {
         uint j;

         for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
            if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
               inst.Instruction.Texture = 1;
               inst.Texture.Texture = j;
               break;
            }
         }
         if (j == TGSI_TEXTURE_COUNT) {
            report_error( ctx, "Expected texture target" );
            return FALSE;
         }
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   for (i = 0; inst.Instruction.Texture && *cur == ',' && i < TGSI_FULL_MAX_TEX_OFFSETS; i++) {
         cur++;
         eat_opt_white( &cur );
         ctx->cur = cur;
         if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] ))
            return FALSE;
         cur = ctx->cur;
         eat_opt_white( &cur );
   }
   inst.Texture.NumOffsets = i;

   cur = ctx->cur;
   eat_opt_white(&cur);

   for (; inst.Instruction.Memory && *cur == ',';
        ctx->cur = cur, eat_opt_white(&cur)) {
      int j;

      cur++;
      eat_opt_white(&cur);

      j = str_match_name_from_array(&cur, tgsi_memory_names,
                                    ARRAY_SIZE(tgsi_memory_names));
      if (j >= 0) {
         inst.Memory.Qualifier |= 1U << j;
         continue;
      }

      j = str_match_name_from_array(&cur, tgsi_texture_names,
                                    ARRAY_SIZE(tgsi_texture_names));
      if (j >= 0) {
         inst.Memory.Texture = j;
         continue;
      }

      j = str_match_format(&cur);
      if (j >= 0) {
         inst.Memory.Format = j;
         continue;
      }

      ctx->cur = cur;
      report_error(ctx, "Expected memory qualifier, texture target, or format\n");
      return FALSE;
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (info->is_branch && *cur == ':') {
      uint target;

      cur++;
      eat_opt_white( &cur );
      if (!parse_uint( &cur, &target )) {
         report_error( ctx, "Expected a label" );
         return FALSE;
      }
      inst.Instruction.Label = 1;
      inst.Label.Label = target;
      ctx->cur = cur;
   }

   advance = tgsi_build_full_instruction(
      &inst,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );
   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}