Exemplo n.º 1
0
/**
 * \param usage_mask  bitfield of TGSI_WRITEMASK_{XYZW} tokens
 */
static struct tgsi_full_declaration
make_output_decl(
   GLuint index,
   GLuint semantic_name,
   GLuint semantic_index,
   GLuint usage_mask,
   GLbitfield output_flags)
{
   struct tgsi_full_declaration decl;

   assert(semantic_name < TGSI_SEMANTIC_COUNT);

   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_OUTPUT;
   decl.Declaration.UsageMask = usage_mask;
   decl.Declaration.Semantic = 1;
   decl.DeclarationRange.First = index;
   decl.DeclarationRange.Last = index;
   decl.Semantic.SemanticName = semantic_name;
   decl.Semantic.SemanticIndex = semantic_index;
   if (output_flags & PROG_PARAM_BIT_CENTROID)
      decl.Declaration.Centroid = 1;
   if (output_flags & PROG_PARAM_BIT_INVARIANT)
      decl.Declaration.Invariant = 1;

   return decl;
}
Exemplo n.º 2
0
static void emit_temp(struct tgsi_transform_context *ctx, unsigned reg)
{
    struct tgsi_full_declaration decl;

    decl = tgsi_default_full_declaration();
    decl.Declaration.File = TGSI_FILE_TEMPORARY;
    decl.Range.First = decl.Range.Last = reg;
    ctx->emit_declaration(ctx, &decl);
}
Exemplo n.º 3
0
/** Reference into a constant buffer */
static struct tgsi_full_declaration
make_constant_decl(GLuint first, GLuint last)
{
   struct tgsi_full_declaration decl;
   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_CONSTANT;
   decl.DeclarationRange.First = first;
   decl.DeclarationRange.Last = last;
   return decl;
}
Exemplo n.º 4
0
static struct tgsi_full_declaration
make_sampler_decl(GLuint index)
{
   struct tgsi_full_declaration decl;
   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_SAMPLER;
   decl.DeclarationRange.First = index;
   decl.DeclarationRange.Last = index;
   return decl;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
static struct tgsi_full_declaration
make_temp_decl(
   GLuint start_index,
   GLuint end_index )
{
   struct tgsi_full_declaration decl;
   decl = tgsi_default_full_declaration();
   decl.Declaration.File = TGSI_FILE_TEMPORARY;
   decl.DeclarationRange.First = start_index;
   decl.DeclarationRange.Last = end_index;
   return decl;
}
Exemplo n.º 7
0
static void emit_output(struct tgsi_transform_context *ctx,
                        unsigned name, unsigned index, unsigned interp,
                        unsigned reg)
{
    struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
    struct tgsi_full_declaration decl;

    decl = tgsi_default_full_declaration();
    decl.Declaration.File = TGSI_FILE_OUTPUT;
    decl.Declaration.Interpolate = interp;
    decl.Declaration.Semantic = TRUE;
    decl.Semantic.Name = name;
    decl.Semantic.Index = index;
    decl.Range.First = decl.Range.Last = reg;
    ctx->emit_declaration(ctx, &decl);
    ++vsctx->num_outputs;
}
Exemplo n.º 8
0
static boolean parse_declaration( struct translate_ctx *ctx )
{
   struct tgsi_full_declaration decl;
   uint file;
   struct parsed_dcl_bracket brackets[2];
   int num_brackets;
   uint writemask;
   const char *cur, *cur2;
   uint advance;
   boolean is_vs_input;

   if (!eat_white( &ctx->cur )) {
      report_error( ctx, "Syntax error" );
      return FALSE;
   }
   if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
      return FALSE;
   if (!parse_opt_writemask( ctx, &writemask ))
      return FALSE;

   decl = tgsi_default_full_declaration();
   decl.Declaration.File = file;
   decl.Declaration.UsageMask = writemask;

   if (num_brackets == 1) {
      decl.Range.First = brackets[0].first;
      decl.Range.Last = brackets[0].last;
   } else {
      decl.Range.First = brackets[1].first;
      decl.Range.Last = brackets[1].last;

      decl.Declaration.Dimension = 1;
      decl.Dim.Index2D = brackets[0].first;
   }

   is_vs_input = (file == TGSI_FILE_INPUT &&
                  ctx->processor == TGSI_PROCESSOR_VERTEX);

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (*cur == ',') {
      cur2 = cur;
      cur2++;
      eat_opt_white( &cur2 );
      if (str_match_nocase_whole( &cur2, "ARRAY" )) {
         int arrayid;
         if (*cur2 != '(') {
            report_error( ctx, "Expected `('" );
            return FALSE;
         }
         cur2++;
         eat_opt_white( &cur2 );
         if (!parse_int( &cur2, &arrayid )) {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         eat_opt_white( &cur2 );
         if (*cur2 != ')') {
            report_error( ctx, "Expected `)'" );
            return FALSE;
         }
         cur2++;
         decl.Declaration.Array = 1;
         decl.Array.ArrayID = arrayid;
         ctx->cur = cur = cur2;
      }
   }

   if (*cur == ',' && !is_vs_input) {
      uint i, j;

      cur++;
      eat_opt_white( &cur );
      if (file == TGSI_FILE_IMAGE) {
         for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
            if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
               decl.Image.Resource = i;
               break;
            }
         }
         if (i == TGSI_TEXTURE_COUNT) {
            report_error(ctx, "Expected texture target");
            return FALSE;
         }

         cur2 = cur;
         eat_opt_white(&cur2);
         while (*cur2 == ',') {
            cur2++;
            eat_opt_white(&cur2);
            if (str_match_nocase_whole(&cur2, "RAW")) {
               decl.Image.Raw = 1;

            } else if (str_match_nocase_whole(&cur2, "WR")) {
               decl.Image.Writable = 1;

            } else {
               for (i = 0; i < PIPE_FORMAT_COUNT; i++) {
                  const struct util_format_description *desc =
                     util_format_description(i);
                  if (desc && str_match_nocase_whole(&cur2, desc->name)) {
                     decl.Image.Format = i;
                     break;
                  }
               }
               if (i == PIPE_FORMAT_COUNT)
                  break;
            }
            cur = cur2;
            eat_opt_white(&cur2);
         }

         ctx->cur = cur;

      } else if (file == TGSI_FILE_SAMPLER_VIEW) {
         for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
            if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) {
               decl.SamplerView.Resource = i;
               break;
            }
         }
         if (i == TGSI_TEXTURE_COUNT) {
            report_error(ctx, "Expected texture target");
            return FALSE;
         }
         eat_opt_white( &cur );
         if (*cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ++cur;
         eat_opt_white( &cur );
         for (j = 0; j < 4; ++j) {
            for (i = 0; i < TGSI_RETURN_TYPE_COUNT; ++i) {
               if (str_match_nocase_whole(&cur, tgsi_return_type_names[i])) {
                  switch (j) {
                  case 0:
                     decl.SamplerView.ReturnTypeX = i;
                     break;
                  case 1:
                     decl.SamplerView.ReturnTypeY = i;
                     break;
                  case 2:
                     decl.SamplerView.ReturnTypeZ = i;
                     break;
                  case 3:
                     decl.SamplerView.ReturnTypeW = i;
                     break;
                  default:
                     assert(0);
                  }
                  break;
               }
            }
            if (i == TGSI_RETURN_TYPE_COUNT) {
               if (j == 0 || j >  2) {
                  report_error(ctx, "Expected type name");
                  return FALSE;
               }
               break;
            } else {
               cur2 = cur;
               eat_opt_white( &cur2 );
               if (*cur2 == ',') {
                  cur2++;
                  eat_opt_white( &cur2 );
                  cur = cur2;
                  continue;
               } else
                  break;
            }
         }
         if (j < 4) {
            decl.SamplerView.ReturnTypeY =
               decl.SamplerView.ReturnTypeZ =
               decl.SamplerView.ReturnTypeW =
               decl.SamplerView.ReturnTypeX;
         }
         ctx->cur = cur;
      } else if (file == TGSI_FILE_BUFFER) {
         if (str_match_nocase_whole(&cur, "ATOMIC")) {
            decl.Declaration.Atomic = 1;
            ctx->cur = cur;
         }
      } else if (file == TGSI_FILE_MEMORY) {
         if (str_match_nocase_whole(&cur, "SHARED")) {
            decl.Declaration.Shared = 1;
            ctx->cur = cur;
         }
      } else {
         if (str_match_nocase_whole(&cur, "LOCAL")) {
            decl.Declaration.Local = 1;
            ctx->cur = cur;
         }

         cur = ctx->cur;
         eat_opt_white( &cur );
         if (*cur == ',') {
            cur++;
            eat_opt_white( &cur );

            for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
               if (str_match_nocase_whole(&cur, tgsi_semantic_names[i])) {
                  uint index;

                  cur2 = cur;
                  eat_opt_white( &cur2 );
                  if (*cur2 == '[') {
                     cur2++;
                     eat_opt_white( &cur2 );
                     if (!parse_uint( &cur2, &index )) {
                        report_error( ctx, "Expected literal integer" );
                        return FALSE;
                     }
                     eat_opt_white( &cur2 );
                     if (*cur2 != ']') {
                        report_error( ctx, "Expected `]'" );
                        return FALSE;
                     }
                     cur2++;

                     decl.Semantic.Index = index;

                     cur = cur2;
                  }

                  decl.Declaration.Semantic = 1;
                  decl.Semantic.Name = i;

                  ctx->cur = cur;
                  break;
               }
            }
         }
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (*cur == ',' && !is_vs_input) {
      uint i;

      cur++;
      eat_opt_white( &cur );
      for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) {
         if (str_match_nocase_whole( &cur, tgsi_interpolate_names[i] )) {
            decl.Declaration.Interpolate = 1;
            decl.Interp.Interpolate = i;

            ctx->cur = cur;
            break;
         }
      }
      if (i == TGSI_INTERPOLATE_COUNT) {
         report_error( ctx, "Expected semantic or interpolate attribute" );
         return FALSE;
      }
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (*cur == ',' && !is_vs_input) {
      uint i;

      cur++;
      eat_opt_white( &cur );
      for (i = 0; i < TGSI_INTERPOLATE_LOC_COUNT; i++) {
         if (str_match_nocase_whole( &cur, tgsi_interpolate_locations[i] )) {
            decl.Interp.Location = i;

            ctx->cur = cur;
            break;
         }
      }
   }

   advance = tgsi_build_full_declaration(
      &decl,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );

   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
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 );
}
Exemplo n.º 11
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;

   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);
   }
}
Exemplo n.º 12
0
static boolean parse_declaration( struct translate_ctx *ctx )
{
   struct tgsi_full_declaration decl;
   uint file;
   struct parsed_dcl_bracket brackets[2];
   int num_brackets;
   uint writemask;
   const char *cur;
   uint advance;
   boolean is_vs_input;
   boolean is_imm_array;

   assert(Elements(semantic_names) == TGSI_SEMANTIC_COUNT);
   assert(Elements(interpolate_names) == TGSI_INTERPOLATE_COUNT);

   if (!eat_white( &ctx->cur )) {
      report_error( ctx, "Syntax error" );
      return FALSE;
   }
   if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
      return FALSE;
   if (!parse_opt_writemask( ctx, &writemask ))
      return FALSE;

   decl = tgsi_default_full_declaration();
   decl.Declaration.File = file;
   decl.Declaration.UsageMask = writemask;

   if (num_brackets == 1) {
      decl.Range.First = brackets[0].first;
      decl.Range.Last = brackets[0].last;
   } else {
      decl.Range.First = brackets[1].first;
      decl.Range.Last = brackets[1].last;

      decl.Declaration.Dimension = 1;
      decl.Dim.Index2D = brackets[0].first;
   }

   is_vs_input = (file == TGSI_FILE_INPUT &&
                  ctx->processor == TGSI_PROCESSOR_VERTEX);
   is_imm_array = (file == TGSI_FILE_IMMEDIATE_ARRAY);

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (*cur == ',' && !is_vs_input) {
      uint i, j;

      cur++;
      eat_opt_white( &cur );
      if (file == TGSI_FILE_RESOURCE) {
         for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
            if (str_match_no_case(&cur, texture_names[i])) {
               if (!is_digit_alpha_underscore(cur)) {
                  decl.Resource.Resource = i;
                  break;
               }
            }
         }
         if (i == TGSI_TEXTURE_COUNT) {
            report_error(ctx, "Expected texture target");
            return FALSE;
         }
         eat_opt_white( &cur );
         if (*cur != ',') {
            report_error( ctx, "Expected `,'" );
            return FALSE;
         }
         ++cur;
         eat_opt_white( &cur );
         for (j = 0; j < 4; ++j) {
            for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
               if (str_match_no_case(&cur, type_names[i])) {
                  if (!is_digit_alpha_underscore(cur)) {
                     switch (j) {
                     case 0:
                        decl.Resource.ReturnTypeX = i;
                        break;
                     case 1:
                        decl.Resource.ReturnTypeY = i;
                        break;
                     case 2:
                        decl.Resource.ReturnTypeZ = i;
                        break;
                     case 3:
                        decl.Resource.ReturnTypeW = i;
                        break;
                     default:
                        assert(0);
                     }
                     break;
                  }
               }
            }
            if (i == PIPE_TYPE_COUNT) {
               if (j == 0 || j >  2) {
                  report_error(ctx, "Expected type name");
                  return FALSE;
               }
               break;
            } else {
               const char *cur2 = cur;
               eat_opt_white( &cur2 );
               if (*cur2 == ',') {
                  cur2++;
                  eat_opt_white( &cur2 );
                  cur = cur2;
                  continue;
               } else
                  break;
            }
         }
         if (j < 4) {
            decl.Resource.ReturnTypeY =
               decl.Resource.ReturnTypeZ =
               decl.Resource.ReturnTypeW =
               decl.Resource.ReturnTypeX;
         }
         ctx->cur = cur;
      } else {
         for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
            if (str_match_no_case( &cur, semantic_names[i] )) {
               const char *cur2 = cur;
               uint index;

               if (is_digit_alpha_underscore( cur ))
                  continue;
               eat_opt_white( &cur2 );
               if (*cur2 == '[') {
                  cur2++;
                  eat_opt_white( &cur2 );
                  if (!parse_uint( &cur2, &index )) {
                     report_error( ctx, "Expected literal integer" );
                     return FALSE;
                  }
                  eat_opt_white( &cur2 );
                  if (*cur2 != ']') {
                     report_error( ctx, "Expected `]'" );
                     return FALSE;
                  }
                  cur2++;

                  decl.Semantic.Index = index;

                  cur = cur2;
               }

               decl.Declaration.Semantic = 1;
               decl.Semantic.Name = i;

               ctx->cur = cur;
               break;
            }
         }
      }
   } else if (is_imm_array) {
      unsigned i;
      float *vals_itr;
      /* we have our immediate data */
      if (*cur != '{') {
         report_error( ctx, "Immediate array without data" );
         return FALSE;
      }
      ++cur;
      ctx->cur = cur;

      decl.ImmediateData.u =
         MALLOC(sizeof(union tgsi_immediate_data) * 4 *
                (decl.Range.Last + 1));
      vals_itr = (float*)decl.ImmediateData.u;
      for (i = 0; i <= decl.Range.Last; ++i) {
         if (!parse_immediate_data(ctx, vals_itr)) {
            FREE(decl.ImmediateData.u);
            return FALSE;
         }
         vals_itr += 4;
         eat_opt_white( &ctx->cur );
         if (*ctx->cur != ',') {
            if (i !=  decl.Range.Last) {
               report_error( ctx, "Not enough data in immediate array!" );
               FREE(decl.ImmediateData.u);
               return FALSE;
            }
         } else
            ++ctx->cur;
      }
      eat_opt_white( &ctx->cur );
      if (*ctx->cur != '}') {
         FREE(decl.ImmediateData.u);
         report_error( ctx, "Immediate array data missing closing '}'" );
         return FALSE;
      }
      ++ctx->cur;
   }

   cur = ctx->cur;
   eat_opt_white( &cur );
   if (*cur == ',' && !is_vs_input) {
      uint i;

      cur++;
      eat_opt_white( &cur );
      for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) {
         if (str_match_no_case( &cur, interpolate_names[i] )) {
            if (is_digit_alpha_underscore( cur ))
               continue;
            decl.Declaration.Interpolate = i;

            ctx->cur = cur;
            break;
         }
      }
      if (i == TGSI_INTERPOLATE_COUNT) {
         report_error( ctx, "Expected semantic or interpolate attribute" );
         return FALSE;
      }
   }

   advance = tgsi_build_full_declaration(
      &decl,
      ctx->tokens_cur,
      ctx->header,
      (uint) (ctx->tokens_end - ctx->tokens_cur) );

   if (is_imm_array)
      FREE(decl.ImmediateData.u);

   if (advance == 0)
      return FALSE;
   ctx->tokens_cur += advance;

   return TRUE;
}