示例#1
0
/* These instructions need special treatment */
static void
emit_special_inst(struct st_translate *t, const struct instruction_desc *desc,
                  struct ureg_dst *dst, struct ureg_src *args, unsigned argcount)
{
   struct ureg_dst tmp[1];
   struct ureg_src src[3];

   if (!strcmp(desc->name, "CND")) {
      tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI + 2); /* re-purpose a3 */
      src[0] = ureg_imm1f(t->ureg, 0.5f);
      src[1] = args[2];
      ureg_insn(t->ureg, TGSI_OPCODE_SUB, tmp, 1, src, 2);
      src[0] = ureg_src(tmp[0]);
      src[1] = args[0];
      src[2] = args[1];
      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
   } else if (!strcmp(desc->name, "CND0")) {
      src[0] = args[2];
      src[1] = args[1];
      src[2] = args[0];
      ureg_insn(t->ureg, TGSI_OPCODE_CMP, dst, 1, src, 3);
   } else if (!strcmp(desc->name, "DOT2_ADD")) {
      /* note: DP2A is not implemented in most pipe drivers */
      tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI); /* re-purpose a1 */
      src[0] = args[0];
      src[1] = args[1];
      ureg_insn(t->ureg, TGSI_OPCODE_DP2, tmp, 1, src, 2);
      src[0] = ureg_src(tmp[0]);
      src[1] = ureg_scalar(args[2], TGSI_SWIZZLE_Z);
      ureg_insn(t->ureg, TGSI_OPCODE_ADD, dst, 1, src, 2);
   }
}
示例#2
0
static struct ureg_src
prepare_argument(struct st_translate *t, const unsigned argId,
                 const struct atifragshader_src_register *srcReg)
{
   struct ureg_src src = get_source(t, srcReg->Index);
   struct ureg_dst arg = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI + argId);

   switch (srcReg->argRep) {
   case GL_NONE:
      break;
   case GL_RED:
      src = ureg_scalar(src, TGSI_SWIZZLE_X);
      break;
   case GL_GREEN:
      src = ureg_scalar(src, TGSI_SWIZZLE_Y);
      break;
   case GL_BLUE:
      src = ureg_scalar(src, TGSI_SWIZZLE_Z);
      break;
   case GL_ALPHA:
      src = ureg_scalar(src, TGSI_SWIZZLE_W);
      break;
   }
   ureg_insn(t->ureg, TGSI_OPCODE_MOV, &arg, 1, &src, 1);

   if (srcReg->argMod & GL_COMP_BIT_ATI) {
      struct ureg_src modsrc[2];
      modsrc[0] = ureg_imm1f(t->ureg, 1.0f);
      modsrc[1] = ureg_src(arg);

      ureg_insn(t->ureg, TGSI_OPCODE_SUB, &arg, 1, modsrc, 2);
   }
   if (srcReg->argMod & GL_BIAS_BIT_ATI) {
      struct ureg_src modsrc[2];
      modsrc[0] = ureg_src(arg);
      modsrc[1] = ureg_imm1f(t->ureg, 0.5f);

      ureg_insn(t->ureg, TGSI_OPCODE_SUB, &arg, 1, modsrc, 2);
   }
   if (srcReg->argMod & GL_2X_BIT_ATI) {
      struct ureg_src modsrc[2];
      modsrc[0] = ureg_src(arg);
      modsrc[1] = ureg_src(arg);

      ureg_insn(t->ureg, TGSI_OPCODE_ADD, &arg, 1, modsrc, 2);
   }
   if (srcReg->argMod & GL_NEGATE_BIT_ATI) {
      struct ureg_src modsrc[2];
      modsrc[0] = ureg_src(arg);
      modsrc[1] = ureg_imm1f(t->ureg, -1.0f);

      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &arg, 1, modsrc, 2);
   }
   return  ureg_src(arg);
}
示例#3
0
static void
finalize_shader(struct st_translate *t, unsigned numPasses)
{
   struct ureg_dst dst[1] = { { 0 } };
   struct ureg_src src[1] = { { 0 } };

   if (t->regs_written[numPasses-1][0]) {
      /* copy the result into the OUT slot */
      dst[0] = t->outputs[t->outputMapping[FRAG_RESULT_COLOR]];
      src[0] = ureg_src(t->temps[0]);
      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
   }

   /* signal the end of the program */
   ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0);
}
示例#4
0
static void
emit_arith_inst(struct st_translate *t,
                const struct instruction_desc *desc,
                struct ureg_dst *dst, struct ureg_src *args, unsigned argcount)
{
   if (desc->TGSI_opcode == TGSI_OPCODE_NOP) {
      return emit_special_inst(t, desc, dst, args, argcount);
   }

   ureg_insn(t->ureg, desc->TGSI_opcode, dst, 1, args, argcount);
}
示例#5
0
static struct ureg_src
apply_swizzle(struct st_translate *t,
              struct ureg_src src, GLuint swizzle)
{
   if (swizzle == GL_SWIZZLE_STR_ATI) {
      return src;
   } else if (swizzle == GL_SWIZZLE_STQ_ATI) {
      return ureg_swizzle(src,
                          TGSI_SWIZZLE_X,
                          TGSI_SWIZZLE_Y,
                          TGSI_SWIZZLE_W,
                          TGSI_SWIZZLE_Z);
   } else {
      struct ureg_dst tmp[2];
      struct ureg_src imm[3];

      tmp[0] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI);
      tmp[1] = get_temp(t, MAX_NUM_FRAGMENT_REGISTERS_ATI + 1);
      imm[0] = src;
      imm[1] = ureg_imm4f(t->ureg, 1.0f, 1.0f, 0.0f, 0.0f);
      imm[2] = ureg_imm4f(t->ureg, 0.0f, 0.0f, 1.0f, 1.0f);
      ureg_insn(t->ureg, TGSI_OPCODE_MAD, &tmp[0], 1, imm, 3);

      if (swizzle == GL_SWIZZLE_STR_DR_ATI) {
         imm[0] = ureg_scalar(src, TGSI_SWIZZLE_Z);
      } else {
         imm[0] = ureg_scalar(src, TGSI_SWIZZLE_W);
      }
      ureg_insn(t->ureg, TGSI_OPCODE_RCP, &tmp[1], 1, &imm[0], 1);

      imm[0] = ureg_src(tmp[0]);
      imm[1] = ureg_src(tmp[1]);
      ureg_insn(t->ureg, TGSI_OPCODE_MUL, &tmp[0], 1, imm, 2);

      return ureg_src(tmp[0]);
   }
}
示例#6
0
void *
util_make_geometry_passthrough_shader(struct pipe_context *pipe,
                                      uint num_attribs,
                                      const ubyte *semantic_names,
                                      const ubyte *semantic_indexes)
{
   static const unsigned zero[4] = {0, 0, 0, 0};

   struct ureg_program *ureg;
   struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
   struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
   struct ureg_src imm;

   unsigned i;

   ureg = ureg_create(PIPE_SHADER_GEOMETRY);
   if (!ureg)
      return NULL;

   ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS);
   ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS);
   ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1);
   ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1);
   imm = ureg_DECL_immediate_uint(ureg, zero, 4);

   /**
    * Loop over all the attribs and declare the corresponding
    * declarations in the geometry shader
    */
   for (i = 0; i < num_attribs; i++) {
      src[i] = ureg_DECL_input(ureg, semantic_names[i],
                               semantic_indexes[i], 0, 1);
      src[i] = ureg_src_dimension(src[i], 0);
      dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]);
   }

   /* MOV dst[i] src[i] */
   for (i = 0; i < num_attribs; i++) {
      ureg_MOV(ureg, dst[i], src[i]);
   }

   /* EMIT IMM[0] */
   ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1, 0);

   /* END */
   ureg_END(ureg);

   return ureg_create_shader_and_destroy(ureg, pipe);
}
示例#7
0
/**
 * Compile one setup instruction to TGSI instructions.
 */
static void
compile_setupinst(struct st_translate *t,
                  const unsigned r,
                  const struct atifs_setupinst *texinst)
{
   struct ureg_dst dst[1];
   struct ureg_src src[2];

   if (!texinst->Opcode)
      return;

   dst[0] = get_temp(t, r);

   GLuint pass_tex = texinst->src;

   if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
      unsigned attr = pass_tex - GL_TEXTURE0_ARB + VARYING_SLOT_TEX0;

      src[0] = t->inputs[t->inputMapping[attr]];
   } else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) {
      unsigned reg = pass_tex - GL_REG_0_ATI;

      /* the frontend already validated that REG is only allowed in second pass */
      if (t->regs_written[0][reg]) {
         src[0] = ureg_src(t->temps[reg]);
      } else {
         src[0] = ureg_imm1f(t->ureg, 0.0f);
      }
   }
   src[0] = apply_swizzle(t, src[0], texinst->swizzle);

   if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) {
      /* by default texture and sampler indexes are the same */
      src[1] = t->samplers[r];
      /* the texture target is still unknown, it will be fixed in the draw call */
      ureg_tex_insn(t->ureg, TGSI_OPCODE_TEX, dst, 1, TGSI_TEXTURE_2D,
                    NULL, 0, src, 2);
   } else if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
      ureg_insn(t->ureg, TGSI_OPCODE_MOV, dst, 1, src, 1);
   }

   t->regs_written[t->current_pass][r] = true;
}
示例#8
0
static void
emit_dstmod(struct st_translate *t,
            struct ureg_dst dst, GLuint dstMod)
{
   float imm;
   struct ureg_src src[3];
   GLuint scale = dstMod & ~GL_SATURATE_BIT_ATI;

   if (dstMod == GL_NONE) {
      return;
   }

   switch (scale) {
   case GL_2X_BIT_ATI:
      imm = 2.0f;
      break;
   case GL_4X_BIT_ATI:
      imm = 4.0f;
      break;
   case GL_8X_BIT_ATI:
      imm = 8.0f;
      break;
   case GL_HALF_BIT_ATI:
      imm = 0.5f;
      break;
   case GL_QUARTER_BIT_ATI:
      imm = 0.25f;
      break;
   case GL_EIGHTH_BIT_ATI:
      imm = 0.125f;
      break;
   default:
      imm = 1.0f;
   }

   src[0] = ureg_src(dst);
   src[1] = ureg_imm1f(t->ureg, imm);
   if (dstMod & GL_SATURATE_BIT_ATI) {
      dst = ureg_saturate(dst);
   }
   ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2);
}
示例#9
0
static void
compile_instruction(
   struct gl_context *ctx,
   struct st_translate *t,
   const struct prog_instruction *inst,
   boolean clamp_dst_color_output)
{
   struct ureg_program *ureg = t->ureg;
   GLuint i;
   struct ureg_dst dst[1] = { { 0 } };
   struct ureg_src src[4];
   unsigned num_dst;
   unsigned num_src;

   num_dst = _mesa_num_inst_dst_regs( inst->Opcode );
   num_src = _mesa_num_inst_src_regs( inst->Opcode );

   if (num_dst) 
      dst[0] = translate_dst( t, 
                              &inst->DstReg,
                              inst->Saturate,
                              clamp_dst_color_output);

   for (i = 0; i < num_src; i++) 
      src[i] = translate_src( t, &inst->SrcReg[i] );

   switch( inst->Opcode ) {
   case OPCODE_SWZ:
      emit_swz( t, dst[0], &inst->SrcReg[0] );
      return;

   case OPCODE_BGNLOOP:
   case OPCODE_CAL:
   case OPCODE_ELSE:
   case OPCODE_ENDLOOP:
      debug_assert(num_dst == 0);
      ureg_label_insn( ureg,
                       translate_opcode( inst->Opcode ),
                       src, num_src,
                       get_label( t, inst->BranchTarget ));
      return;

   case OPCODE_IF:
      debug_assert(num_dst == 0);
      ureg_label_insn( ureg,
                       ctx->Const.NativeIntegers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF,
                       src, num_src,
                       get_label( t, inst->BranchTarget ));
      return;

   case OPCODE_TEX:
   case OPCODE_TXB:
   case OPCODE_TXD:
   case OPCODE_TXL:
   case OPCODE_TXP:
      src[num_src++] = t->samplers[inst->TexSrcUnit];
      ureg_tex_insn( ureg,
                     translate_opcode( inst->Opcode ),
                     dst, num_dst, 
                     st_translate_texture_target( inst->TexSrcTarget,
                                               inst->TexShadow ),
                     NULL, 0,
                     src, num_src );
      return;

   case OPCODE_SCS:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_XPD:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_NOISE1:
   case OPCODE_NOISE2:
   case OPCODE_NOISE3:
   case OPCODE_NOISE4:
      /* At some point, a motivated person could add a better
       * implementation of noise.  Currently not even the nvidia
       * binary drivers do anything more than this.  In any case, the
       * place to do this is in the GL state tracker, not the poor
       * driver.
       */
      ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) );
      break;
		 
   case OPCODE_DDY:
      emit_ddy( t, dst[0], &inst->SrcReg[0] );
      break;

   case OPCODE_RSQ:
      ureg_RSQ( ureg, dst[0], ureg_abs(src[0]) );
      break;

   default:
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;
   }
}
示例#10
0
static void
compile_instruction(
   struct gl_context *ctx,
   struct st_translate *t,
   const struct prog_instruction *inst)
{
   struct ureg_program *ureg = t->ureg;
   GLuint i;
   struct ureg_dst dst[1] = { { 0 } };
   struct ureg_src src[4];
   unsigned num_dst;
   unsigned num_src;

   num_dst = _mesa_num_inst_dst_regs( inst->Opcode );
   num_src = _mesa_num_inst_src_regs( inst->Opcode );

   if (num_dst) 
      dst[0] = translate_dst( t, 
                              &inst->DstReg,
                              inst->Saturate);

   for (i = 0; i < num_src; i++) 
      src[i] = translate_src( t, &inst->SrcReg[i] );

   switch( inst->Opcode ) {
   case OPCODE_SWZ:
      emit_swz( t, dst[0], &inst->SrcReg[0] );
      return;

   case OPCODE_TEX:
   case OPCODE_TXB:
   case OPCODE_TXP:
      src[num_src++] = t->samplers[inst->TexSrcUnit];
      ureg_tex_insn( ureg,
                     translate_opcode( inst->Opcode ),
                     dst, num_dst, 
                     st_translate_texture_target( inst->TexSrcTarget,
                                               inst->TexShadow ),
                     NULL, 0,
                     src, num_src );
      return;

   case OPCODE_SCS:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_XPD:
      dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ );
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;

   case OPCODE_RSQ:
      ureg_RSQ( ureg, dst[0], ureg_abs(src[0]) );
      break;

   case OPCODE_ABS:
      ureg_MOV(ureg, dst[0], ureg_abs(src[0]));
      break;

   case OPCODE_SUB:
      ureg_ADD(ureg, dst[0], src[0], ureg_negate(src[1]));
      break;

   default:
      ureg_insn( ureg, 
                 translate_opcode( inst->Opcode ), 
                 dst, num_dst, 
                 src, num_src );
      break;
   }
}