draw: use tgsi transform prolog callback in polygon stipple code
authorBrian Paul <brianp@vmware.com>
Fri, 19 Sep 2014 19:24:20 +0000 (13:24 -0600)
committerBrian Paul <brianp@vmware.com>
Mon, 22 Sep 2014 22:56:24 +0000 (16:56 -0600)
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
src/gallium/auxiliary/draw/draw_pipe_pstipple.c

index d2167879318d59cbd239925580548312f3cea93f..7ef86a61df4ae411ccd148629b2d47d01a95c60d 100644 (file)
@@ -129,7 +129,6 @@ struct pstip_transform_context {
    int freeSampler;  /** an available sampler for the pstipple */
    int texTemp;  /**< temp registers */
    int numImmed;
-   boolean firstInstruction;
 };
 
 
@@ -192,147 +191,134 @@ free_bit(uint bitfield)
 
 
 /**
- * TGSI instruction transform callback.
- * Replace writes to result.color w/ a temp reg.
- * Upon END instruction, insert texture sampling code for antialiasing.
+ * TGSI transform prolog callback.
  */
 static void
-pstip_transform_inst(struct tgsi_transform_context *ctx,
-                     struct tgsi_full_instruction *inst)
+pstip_transform_prolog(struct tgsi_transform_context *ctx)
 {
    struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
+   struct tgsi_full_declaration decl;
+   struct tgsi_full_instruction newInst;
+   uint i;
+   int wincoordInput;
 
-   if (pctx->firstInstruction) {
-      /* emit our new declarations before the first instruction */
+   /* find free sampler */
+   pctx->freeSampler = free_bit(pctx->samplersUsed);
+   if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+      pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
 
-      struct tgsi_full_declaration decl;
-      struct tgsi_full_instruction newInst;
-      uint i;
-      int wincoordInput;
+   if (pctx->wincoordInput < 0)
+      wincoordInput = pctx->maxInput + 1;
+   else
+      wincoordInput = pctx->wincoordInput;
 
-      /* find free sampler */
-      pctx->freeSampler = free_bit(pctx->samplersUsed);
-      if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
-         pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
-
-      if (pctx->wincoordInput < 0)
-         wincoordInput = pctx->maxInput + 1;
+   /* find one free temp reg */
+   for (i = 0; i < 32; i++) {
+      if ((pctx->tempsUsed & (1 << i)) == 0) {
+      /* found a free temp */
+      if (pctx->texTemp < 0)
+         pctx->texTemp  = i;
       else
-         wincoordInput = pctx->wincoordInput;
-
-      /* find one free temp reg */
-      for (i = 0; i < 32; i++) {
-         if ((pctx->tempsUsed & (1 << i)) == 0) {
-            /* found a free temp */
-            if (pctx->texTemp < 0)
-               pctx->texTemp  = i;
-            else
-               break;
-         }
-      }
-      assert(pctx->texTemp >= 0);
-
-      if (pctx->wincoordInput < 0) {
-         /* declare new position input reg */
-         decl = tgsi_default_full_declaration();
-         decl.Declaration.File = TGSI_FILE_INPUT;
-         decl.Declaration.Interpolate = 1;
-         decl.Declaration.Semantic = 1;
-         decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
-         decl.Semantic.Index = 0;
-         decl.Range.First = 
-            decl.Range.Last = wincoordInput;
-         decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
-         ctx->emit_declaration(ctx, &decl);
+         break;
       }
+   }
+   assert(pctx->texTemp >= 0);
 
-      /* declare new sampler */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_SAMPLER;
-      decl.Range.First = 
-      decl.Range.Last = pctx->freeSampler;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* declare new temp regs */
+   if (pctx->wincoordInput < 0) {
+      /* declare new position input reg */
       decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.Declaration.File = TGSI_FILE_INPUT;
+      decl.Declaration.Interpolate = 1;
+      decl.Declaration.Semantic = 1;
+      decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
+      decl.Semantic.Index = 0;
       decl.Range.First = 
-      decl.Range.Last = pctx->texTemp;
+      decl.Range.Last = wincoordInput;
+      decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
       ctx->emit_declaration(ctx, &decl);
+   }
 
-      /* emit immediate = {1/32, 1/32, 1, 1}
-       * The index/position of this immediate will be pctx->numImmed
-       */
-      {
-         static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
-         struct tgsi_full_immediate immed;
-         uint size = 4;
-         immed = tgsi_default_full_immediate();
-         immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
-         immed.u[0].Float = value[0];
-         immed.u[1].Float = value[1];
-         immed.u[2].Float = value[2];
-         immed.u[3].Float = value[3];
-         ctx->emit_immediate(ctx, &immed);
-      }
-
-      pctx->firstInstruction = FALSE;
-
-
-      /* 
-       * Insert new MUL/TEX/KILL_IF instructions at start of program
-       * Take gl_FragCoord, divide by 32 (stipple size), sample the
-       * texture and kill fragment if needed.
-       *
-       * We'd like to use non-normalized texcoords to index into a RECT
-       * texture, but we can only use GL_REPEAT wrap mode with normalized
-       * texcoords.  Darn.
-       */
-
-      /* MUL texTemp, INPUT[wincoord], 1/32; */
-      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 = pctx->texTemp;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
-      newInst.Src[0].Register.Index = wincoordInput;
-      newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
-      newInst.Src[1].Register.Index = pctx->numImmed;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* TEX texTemp, texTemp, sampler; */
-      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 = pctx->texTemp;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.Instruction.Texture = TRUE;
-      newInst.Texture.Texture = TGSI_TEXTURE_2D;
-      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
-      newInst.Src[0].Register.Index = pctx->texTemp;
-      newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
-      newInst.Src[1].Register.Index = pctx->freeSampler;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* KILL_IF -texTemp;   # if -texTemp < 0, KILL fragment */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
-      newInst.Instruction.NumDstRegs = 0;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
-      newInst.Src[0].Register.Index = pctx->texTemp;
-      newInst.Src[0].Register.Negate = 1;
-      ctx->emit_instruction(ctx, &newInst);
+   /* declare new sampler */
+   decl = tgsi_default_full_declaration();
+   decl.Declaration.File = TGSI_FILE_SAMPLER;
+   decl.Range.First = 
+   decl.Range.Last = pctx->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 = pctx->texTemp;
+   ctx->emit_declaration(ctx, &decl);
+
+   /* emit immediate = {1/32, 1/32, 1, 1}
+    * The index/position of this immediate will be pctx->numImmed
+    */
+   {
+      static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
+      struct tgsi_full_immediate immed;
+      uint size = 4;
+      immed = tgsi_default_full_immediate();
+      immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
+      immed.u[0].Float = value[0];
+      immed.u[1].Float = value[1];
+      immed.u[2].Float = value[2];
+      immed.u[3].Float = value[3];
+      ctx->emit_immediate(ctx, &immed);
    }
 
-   /* emit this instruction */
-   ctx->emit_instruction(ctx, inst);
+   /* 
+    * Insert new MUL/TEX/KILL_IF instructions at start of program
+    * Take gl_FragCoord, divide by 32 (stipple size), sample the
+    * texture and kill fragment if needed.
+    *
+    * We'd like to use non-normalized texcoords to index into a RECT
+    * texture, but we can only use GL_REPEAT wrap mode with normalized
+    * texcoords.  Darn.
+    */
+
+   /* MUL texTemp, INPUT[wincoord], 1/32; */
+   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 = pctx->texTemp;
+   newInst.Instruction.NumSrcRegs = 2;
+   newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+   newInst.Src[0].Register.Index = wincoordInput;
+   newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
+   newInst.Src[1].Register.Index = pctx->numImmed;
+   ctx->emit_instruction(ctx, &newInst);
+
+   /* TEX texTemp, texTemp, sampler; */
+   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 = pctx->texTemp;
+   newInst.Instruction.NumSrcRegs = 2;
+   newInst.Instruction.Texture = TRUE;
+   newInst.Texture.Texture = TGSI_TEXTURE_2D;
+   newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+   newInst.Src[0].Register.Index = pctx->texTemp;
+   newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
+   newInst.Src[1].Register.Index = pctx->freeSampler;
+   ctx->emit_instruction(ctx, &newInst);
+
+   /* KILL_IF -texTemp;   # if -texTemp < 0, KILL fragment */
+   newInst = tgsi_default_full_instruction();
+   newInst.Instruction.Opcode = TGSI_OPCODE_KILL_IF;
+   newInst.Instruction.NumDstRegs = 0;
+   newInst.Instruction.NumSrcRegs = 1;
+   newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+   newInst.Src[0].Register.Index = pctx->texTemp;
+   newInst.Src[0].Register.Negate = 1;
+   ctx->emit_instruction(ctx, &newInst);
 }
 
 
+
 /**
  * Generate the frag shader we'll use for doing polygon stipple.
  * This will be the user's shader prefixed with a TEX and KIL instruction.
@@ -355,8 +341,7 @@ generate_pstip_fs(struct pstip_stage *pstip)
    transform.wincoordInput = -1;
    transform.maxInput = -1;
    transform.texTemp = -1;
-   transform.firstInstruction = TRUE;
-   transform.base.transform_instruction = pstip_transform_inst;
+   transform.base.prolog = pstip_transform_prolog;
    transform.base.transform_declaration = pstip_transform_decl;
    transform.base.transform_immediate = pstip_transform_immed;