예제 #1
0
/**
 * Create a TGSI ureg_dst register from a Mesa dest register.
 */
static struct ureg_dst
translate_dst( struct st_translate *t,
               const struct prog_dst_register *DstReg,
               boolean saturate,
               boolean clamp_color)
{
   struct ureg_dst dst = dst_register( t, 
                                       DstReg->File,
                                       DstReg->Index );

   dst = ureg_writemask( dst, 
                         DstReg->WriteMask );
   
   if (saturate)
      dst = ureg_saturate( dst );
   else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) {
      /* Clamp colors for ARB_color_buffer_float. */
      switch (t->procType) {
      case TGSI_PROCESSOR_VERTEX:
         /* This can only occur with a compatibility profile, which doesn't
          * support geometry shaders. */
         if (DstReg->Index == VARYING_SLOT_COL0 ||
             DstReg->Index == VARYING_SLOT_COL1 ||
             DstReg->Index == VARYING_SLOT_BFC0 ||
             DstReg->Index == VARYING_SLOT_BFC1) {
            dst = ureg_saturate(dst);
         }
         break;

      case TGSI_PROCESSOR_FRAGMENT:
         if (DstReg->Index >= FRAG_RESULT_COLOR) {
            dst = ureg_saturate(dst);
         }
         break;
      }
   }

   if (DstReg->RelAddr)
      dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );

   return dst;
}
예제 #2
0
/**
 * Create a TGSI ureg_dst register from a Mesa dest register.
 */
static struct ureg_dst
translate_dst( struct st_translate *t,
               const struct prog_dst_register *DstReg,
               boolean saturate,
               boolean clamp_color)
{
   struct ureg_dst dst = dst_register( t, 
                                       DstReg->File,
                                       DstReg->Index );

   dst = ureg_writemask( dst, 
                         DstReg->WriteMask );
   
   if (saturate)
      dst = ureg_saturate( dst );
   else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) {
      /* Clamp colors for ARB_color_buffer_float. */
      switch (t->procType) {
      case TGSI_PROCESSOR_VERTEX:
         /* XXX if the geometry shader is present, this must be done there
          * instead of here. */
         if (DstReg->Index == VARYING_SLOT_COL0 ||
             DstReg->Index == VARYING_SLOT_COL1 ||
             DstReg->Index == VARYING_SLOT_BFC0 ||
             DstReg->Index == VARYING_SLOT_BFC1) {
            dst = ureg_saturate(dst);
         }
         break;

      case TGSI_PROCESSOR_FRAGMENT:
         if (DstReg->Index >= FRAG_RESULT_COLOR) {
            dst = ureg_saturate(dst);
         }
         break;
      }
   }

   if (DstReg->RelAddr)
      dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );

   return dst;
}
예제 #3
0
/**
 * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
 * TGSI uses +1 for front, -1 for back.
 * This function converts the TGSI value to the GL value.  Simply clamping/
 * saturating the value to [0,1] does the job.
 */
static void
emit_face_var( struct st_translate *t,
               const struct gl_program *program )
{
   struct ureg_program *ureg = t->ureg;
   struct ureg_dst face_temp = ureg_DECL_temporary( ureg );
   struct ureg_src face_input = t->inputs[t->inputMapping[VARYING_SLOT_FACE]];

   /* MOV_SAT face_temp, input[face]
    */
   face_temp = ureg_saturate( face_temp );
   ureg_MOV( ureg, face_temp, face_input );

   /* Use face_temp as face input from here on:
    */
   t->inputs[t->inputMapping[VARYING_SLOT_FACE]] = ureg_src(face_temp);
}
예제 #4
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);
}
예제 #5
0
/**
 * Create a TGSI ureg_dst register from a Mesa dest register.
 */
static struct ureg_dst
translate_dst( struct st_translate *t,
               const struct prog_dst_register *DstReg,
               boolean saturate)
{
   struct ureg_dst dst = dst_register( t, 
                                       DstReg->File,
                                       DstReg->Index );

   dst = ureg_writemask( dst, 
                         DstReg->WriteMask );
   
   if (saturate)
      dst = ureg_saturate( dst );

   if (DstReg->RelAddr)
      dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );

   return dst;
}
예제 #6
0
static void *
create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field,
                         struct vertex2f *sizes, bool spatial_filter)
{
   struct ureg_program *shader;
   struct ureg_src i_vtex;
   struct ureg_src sampler_cur;
   struct ureg_src sampler_prevprev;
   struct ureg_src sampler_prev;
   struct ureg_src sampler_next;
   struct ureg_dst o_fragment;
   struct ureg_dst t_tex;
   struct ureg_dst t_comp_top, t_comp_bot;
   struct ureg_dst t_diff;
   struct ureg_dst t_a, t_b;
   struct ureg_dst t_weave, t_linear;

   shader = ureg_create(PIPE_SHADER_FRAGMENT);
   if (!shader) {
      return NULL;
   }

   t_tex = ureg_DECL_temporary(shader);
   t_comp_top = ureg_DECL_temporary(shader);
   t_comp_bot = ureg_DECL_temporary(shader);
   t_diff = ureg_DECL_temporary(shader);
   t_a = ureg_DECL_temporary(shader);
   t_b = ureg_DECL_temporary(shader);
   t_weave = ureg_DECL_temporary(shader);
   t_linear = ureg_DECL_temporary(shader);

   i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
   sampler_prevprev = ureg_DECL_sampler(shader, 0);
   sampler_prev = ureg_DECL_sampler(shader, 1);
   sampler_cur = ureg_DECL_sampler(shader, 2);
   sampler_next = ureg_DECL_sampler(shader, 3);
   o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);

   // we don't care about ZW interpolation (allows better optimization)
   ureg_MOV(shader, t_tex, i_vtex);
   ureg_MOV(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_ZW),
            ureg_imm1f(shader, 0));

   // sample between texels for cheap lowpass
   ureg_ADD(shader, t_comp_top, ureg_src(t_tex),
            ureg_imm4f(shader, sizes->x * 0.5f, sizes->y * -0.5f, 0, 0));
   ureg_ADD(shader, t_comp_bot, ureg_src(t_tex),
            ureg_imm4f(shader, sizes->x * -0.5f, sizes->y * 0.5f, 1.0f, 0));

   if (field == 0) {
      /* interpolating top field -> current field is a bottom field */
      // cur vs prev2
      ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur);
      ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prevprev);
      ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b)));
      // prev vs next
      ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prev);
      ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_next);
      ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b)));
   } else {
      /* interpolating bottom field -> current field is a top field */
      // cur vs prev2
      ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur);
      ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prevprev);
      ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b)));
      // prev vs next
      ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev);
      ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_next);
      ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b)));
   }

   // absolute maximum of differences
   ureg_MAX(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_abs(ureg_src(t_diff)),
            ureg_scalar(ureg_abs(ureg_src(t_diff)), TGSI_SWIZZLE_Y));

   if (field == 0) {
      /* weave with prev top field */
      ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_tex), sampler_prev);
      /* get linear interpolation from current bottom field */
      ureg_ADD(shader, t_comp_top, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * -1.0f, 1.0f, 0));
      ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur);
   } else {
      /* weave with prev bottom field */
      ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, 0, 1.0f, 0));
      ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev);
      /* get linear interpolation from current top field */
      ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * 1.0f, 0, 0));
      ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur);
   }

   // mix between weave and linear
   // fully weave if diff < 6 (0.02353), fully interpolate if diff > 14 (0.05490)
   ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_diff),
            ureg_imm4f(shader, -0.02353f, 0, 0, 0));
   ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)),
            ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0));
   ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff),
            ureg_src(t_linear), ureg_src(t_weave));
   ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X));

   ureg_release_temporary(shader, t_tex);
   ureg_release_temporary(shader, t_comp_top);
   ureg_release_temporary(shader, t_comp_bot);
   ureg_release_temporary(shader, t_diff);
   ureg_release_temporary(shader, t_a);
   ureg_release_temporary(shader, t_b);
   ureg_release_temporary(shader, t_weave);
   ureg_release_temporary(shader, t_linear);
   ureg_END(shader);

   return ureg_create_shader_and_destroy(shader, filter->pipe);
}