Beispiel #1
0
/**
 * Create a simple vertex shader that passes through position and the given
 * attribute.
 */
static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name)
{
   struct ureg_program *ureg;
   struct ureg_src src[2], constants[3];
   struct ureg_dst dst[2], tmp;
   int i;

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

   /* position is in user coordinates */
   src[0] = ureg_DECL_vs_input(ureg, 0);
   dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
   tmp = ureg_DECL_temporary(ureg);
   for (i = 0; i < Elements(constants); i++)
      constants[i] = ureg_DECL_constant(ureg, i);

   /* transform to clipped coordinates */
   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]);
   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]);
   ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]);
   ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]);
   ureg_MOV(ureg, dst[0], ureg_src(tmp));

   if (semantic_name >= 0) {
      src[1] = ureg_DECL_vs_input(ureg, 1);
      dst[1] = ureg_DECL_output(ureg, semantic_name, 0);
      ureg_MOV(ureg, dst[1], src[1]);
   }

   ureg_END(ureg);

   return ureg_create_shader_and_destroy(ureg, pipe);
}
Beispiel #2
0
/**
 * Create a simple vertex shader that just passes through the
 * vertex position and texcoord (and optionally, color).
 */
static void *
make_passthrough_vertex_shader(struct st_context *st, 
                               GLboolean passColor)
{
   if (!st->drawpix.vert_shaders[passColor]) {
      struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX );

      if (ureg == NULL)
         return NULL;

      /* MOV result.pos, vertex.pos; */
      ureg_MOV(ureg, 
               ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
               ureg_DECL_vs_input( ureg, 0 ));
      
      /* MOV result.texcoord0, vertex.attr[1]; */
      ureg_MOV(ureg, 
               ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ),
               ureg_DECL_vs_input( ureg, 1 ));
      
      if (passColor) {
         /* MOV result.color0, vertex.attr[2]; */
         ureg_MOV(ureg, 
                  ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
                  ureg_DECL_vs_input( ureg, 2 ));
      }

      ureg_END( ureg );
      
      st->drawpix.vert_shaders[passColor] = 
         ureg_create_shader_and_destroy( ureg, st->pipe );
   }

   return st->drawpix.vert_shaders[passColor];
}
static struct ureg_dst
calc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src block_scale)
{
   struct ureg_src vrect, vpos;
   struct ureg_dst t_vpos;
   struct ureg_dst o_vpos;

   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);

   t_vpos = ureg_DECL_temporary(shader);

   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);

   /*
    * block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height)
    *
    * t_vpos = (vpos + vrect) * block_scale
    * o_vpos.xy = t_vpos
    * o_vpos.zw = vpos
    */
   ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
   ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);
   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));

   return t_vpos;
}
Beispiel #4
0
static void *
create_vs(struct pipe_context *pipe, unsigned vs_traits)
{
    struct ureg_program *ureg;
    struct ureg_src src;
    struct ureg_dst dst;
    struct ureg_src const0, const1;
    boolean is_fill = (vs_traits & VS_FILL) != 0;
    boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
    boolean has_mask = (vs_traits & VS_MASK) != 0;
    boolean is_yuv = (vs_traits & VS_YUV) != 0;
    unsigned input_slot = 0;

    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
    if (ureg == NULL)
	return 0;

    const0 = ureg_DECL_constant(ureg, 0);
    const1 = ureg_DECL_constant(ureg, 1);

    /* it has to be either a fill or a composite op */
    debug_assert((is_fill ^ is_composite) ^ is_yuv);

    src = ureg_DECL_vs_input(ureg, input_slot++);
    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
    src = vs_normalize_coords(ureg, src, const0, const1);
    ureg_MOV(ureg, dst, src);

    if (is_yuv) {
	src = ureg_DECL_vs_input(ureg, input_slot++);
	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
	ureg_MOV(ureg, dst, src);
    }

    if (is_composite) {
	src = ureg_DECL_vs_input(ureg, input_slot++);
	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
	ureg_MOV(ureg, dst, src);
    }

    if (is_fill) {
	src = ureg_DECL_vs_input(ureg, input_slot++);
	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
	ureg_MOV(ureg, dst, src);
    }

    if (has_mask) {
	src = ureg_DECL_vs_input(ureg, input_slot++);
	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
	ureg_MOV(ureg, dst, src);
    }

    ureg_END(ureg);

    return ureg_create_shader_and_destroy(ureg, pipe);
}
static void *
create_ref_vert_shader(struct vl_mc *r)
{
   struct ureg_program *shader;
   struct ureg_src mv_scale;
   struct ureg_src vmv[2];
   struct ureg_dst t_vpos;
   struct ureg_dst o_vmv[2];
   unsigned i;

   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
   if (!shader)
      return NULL;

   vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP);
   vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM);

   t_vpos = calc_position(r, shader, ureg_imm2f(shader,
      (float)VL_MACROBLOCK_WIDTH / r->buffer_width,
      (float)VL_MACROBLOCK_HEIGHT / r->buffer_height)
   );

   o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP);
   o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM);

   /*
    * mv_scale.xy = 0.5 / (dst.width, dst.height);
    * mv_scale.z = 1.0f / 4.0f
    * mv_scale.w = 1.0f / 255.0f
    *
    * // Apply motion vectors
    * o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos
    * o_vmv[0..1].zw = vmv[0..1] * mv_scale
    *
    */

   mv_scale = ureg_imm4f(shader,
      0.5f / r->buffer_width,
      0.5f / r->buffer_height,
      1.0f / 4.0f,
      1.0f / PIPE_VIDEO_MV_WEIGHT_MAX);

   for (i = 0; i < 2; ++i) {
      ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos));
      ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]);
   }

   ureg_release_temporary(shader, t_vpos);

   ureg_END(shader);

   return ureg_create_shader_and_destroy(shader, r->pipe);
}
Beispiel #6
0
void *
util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
                                    uint num_attribs,
                                    const uint *semantic_names,
                                    const uint *semantic_indexes,
                                    bool window_space,
				    const struct pipe_stream_output_info *so)
{
   struct ureg_program *ureg;
   uint i;

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

   if (window_space)
      ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE);

   for (i = 0; i < num_attribs; i++) {
      struct ureg_src src;
      struct ureg_dst dst;

      src = ureg_DECL_vs_input( ureg, i );
      
      dst = ureg_DECL_output( ureg,
                              semantic_names[i],
                              semantic_indexes[i]);
      
      ureg_MOV( ureg, dst, src );
   }

   ureg_END( ureg );

   return ureg_create_shader_with_so_and_destroy( ureg, pipe, so );
}
void *
util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe,
                                    uint num_attribs,
                                    const uint *semantic_names,
                                    const uint *semantic_indexes,
				    const struct pipe_stream_output_info *so)
{
   struct ureg_program *ureg;
   uint i;

   ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
   if (ureg == NULL)
      return NULL;

   for (i = 0; i < num_attribs; i++) {
      struct ureg_src src;
      struct ureg_dst dst;

      src = ureg_DECL_vs_input( ureg, i );
      
      dst = ureg_DECL_output( ureg,
                              semantic_names[i],
                              semantic_indexes[i]);
      
      ureg_MOV( ureg, dst, src );
   }

   ureg_END( ureg );

   return ureg_create_shader_with_so_and_destroy( ureg, pipe, so );
}
Beispiel #8
0
void *
st_pbo_create_vs(struct st_context *st)
{
   struct pipe_screen *pscreen = st->pipe->screen;
   bool use_nir = PIPE_SHADER_IR_NIR ==
      pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
                                PIPE_SHADER_CAP_PREFERRED_IR);

   if (use_nir) {
      unsigned inputs[] =  {  VERT_ATTRIB_POS, SYSTEM_VALUE_INSTANCE_ID, };
      unsigned outputs[] = { VARYING_SLOT_POS,       VARYING_SLOT_LAYER  };

      return st_nir_make_passthrough_shader(st, "st/pbo VS",
                                            MESA_SHADER_VERTEX,
                                            st->pbo.layers ? 2 : 1,
                                            inputs, outputs, NULL, (1 << 1));
   }

   struct ureg_program *ureg;
   struct ureg_src in_pos;
   struct ureg_src in_instanceid;
   struct ureg_dst out_pos;
   struct ureg_dst out_layer;

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

   in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION);

   out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);

   if (st->pbo.layers) {
      in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);

      if (!st->pbo.use_gs)
         out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
   }

   /* out_pos = in_pos */
   ureg_MOV(ureg, out_pos, in_pos);

   if (st->pbo.layers) {
      if (st->pbo.use_gs) {
         /* out_pos.z = i2f(gl_InstanceID) */
         ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z),
                        ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
      } else {
         /* out_layer = gl_InstanceID */
         ureg_MOV(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X),
                        ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
      }
   }

   ureg_END(ureg);

   return ureg_create_shader_and_destroy(ureg, st->pipe);
}
Beispiel #9
0
void
vl_idct_stage2_vert_shader(struct vl_idct *idct, struct ureg_program *shader,
                           unsigned first_output, struct ureg_dst tex)
{
    struct ureg_src vrect, vpos;
    struct ureg_src scale;
    struct ureg_dst t_start;
    struct ureg_dst o_l_addr[2], o_r_addr[2];

    vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
    vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);

    t_start = ureg_DECL_temporary(shader);

    --first_output;

    o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR0);
    o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_L_ADDR1);

    o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR0);
    o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, first_output + VS_O_R_ADDR1);

    scale = ureg_imm2f(shader,
                       (float)VL_BLOCK_WIDTH / idct->buffer_width,
                       (float)VL_BLOCK_HEIGHT / idct->buffer_height);

    ureg_MUL(shader, ureg_writemask(tex, TGSI_WRITEMASK_Z),
             ureg_scalar(vrect, TGSI_SWIZZLE_X),
             ureg_imm1f(shader, VL_BLOCK_WIDTH / idct->nr_of_render_targets));
    ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale);

    calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, VL_BLOCK_WIDTH / 4);
    calc_addr(shader, o_r_addr, ureg_src(tex), ureg_src(t_start), true, false, idct->buffer_height / 4);

    ureg_MOV(shader, ureg_writemask(o_r_addr[0], TGSI_WRITEMASK_Z), ureg_src(tex));
    ureg_MOV(shader, ureg_writemask(o_r_addr[1], TGSI_WRITEMASK_Z), ureg_src(tex));
}
Beispiel #10
0
static void *
create_mismatch_vert_shader(struct vl_idct *idct)
{
    struct ureg_program *shader;
    struct ureg_src vpos;
    struct ureg_src scale;
    struct ureg_dst t_tex;
    struct ureg_dst o_vpos, o_addr[2];

    shader = ureg_create(TGSI_PROCESSOR_VERTEX);
    if (!shader)
        return NULL;

    vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);

    t_tex = ureg_DECL_temporary(shader);

    o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);

    o_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0);
    o_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1);

    /*
     * scale = (VL_BLOCK_WIDTH, VL_BLOCK_HEIGHT) / (dst.width, dst.height)
     *
     * t_vpos = vpos + 7 / VL_BLOCK_WIDTH
     * o_vpos.xy = t_vpos * scale
     *
     * o_addr = calc_addr(...)
     *
     */

    scale = ureg_imm2f(shader,
                       (float)VL_BLOCK_WIDTH / idct->buffer_width,
                       (float)VL_BLOCK_HEIGHT / idct->buffer_height);

    ureg_MAD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), vpos, scale, scale);
    ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));

    ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, scale);
    calc_addr(shader, o_addr, ureg_src(t_tex), ureg_src(t_tex), false, false, idct->buffer_width / 4);

    ureg_release_temporary(shader, t_tex);

    ureg_END(shader);

    return ureg_create_shader_and_destroy(shader, idct->pipe);
}
Beispiel #11
0
void *
st_pbo_create_vs(struct st_context *st)
{
   struct ureg_program *ureg;
   struct ureg_src in_pos;
   struct ureg_src in_instanceid;
   struct ureg_dst out_pos;
   struct ureg_dst out_layer;

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

   in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION);

   out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);

   if (st->pbo.layers) {
      in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);

      if (!st->pbo.use_gs)
         out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
   }

   /* out_pos = in_pos */
   ureg_MOV(ureg, out_pos, in_pos);

   if (st->pbo.layers) {
      if (st->pbo.use_gs) {
         /* out_pos.z = i2f(gl_InstanceID) */
         ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z),
                        ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
      } else {
         /* out_layer = gl_InstanceID */
         ureg_MOV(ureg, out_layer, in_instanceid);
      }
   }

   ureg_END(ureg);

   return ureg_create_shader_and_destroy(ureg, st->pipe);
}
static void *
create_vert_shader(struct vl_deint_filter *filter)
{
   struct ureg_program *shader;
   struct ureg_src i_vpos;
   struct ureg_dst o_vpos, o_vtex;

   shader = ureg_create(PIPE_SHADER_VERTEX);
   if (!shader)
      return NULL;

   i_vpos = ureg_DECL_vs_input(shader, 0);
   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
   o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);

   ureg_MOV(shader, o_vpos, i_vpos);
   ureg_MOV(shader, o_vtex, i_vpos);

   ureg_END(shader);

   return ureg_create_shader_and_destroy(shader, filter->pipe);
}
Beispiel #13
0
/**
 * Translate Mesa program to TGSI format.
 * \param program  the program to translate
 * \param numInputs  number of input registers used
 * \param inputMapping  maps Mesa fragment program inputs to TGSI generic
 *                      input indexes
 * \param inputSemanticName  the TGSI_SEMANTIC flag for each input
 * \param inputSemanticIndex  the semantic index (ex: which texcoord) for
 *                            each input
 * \param interpMode  the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
 * \param numOutputs  number of output registers used
 * \param outputMapping  maps Mesa fragment program outputs to TGSI
 *                       generic outputs
 * \param outputSemanticName  the TGSI_SEMANTIC flag for each output
 * \param outputSemanticIndex  the semantic index (ex: which texcoord) for
 *                             each output
 *
 * \return  PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY
 */
enum pipe_error
st_translate_mesa_program(
   struct gl_context *ctx,
   uint procType,
   struct ureg_program *ureg,
   const struct gl_program *program,
   GLuint numInputs,
   const GLuint inputMapping[],
   const ubyte inputSemanticName[],
   const ubyte inputSemanticIndex[],
   const GLuint interpMode[],
   GLuint numOutputs,
   const GLuint outputMapping[],
   const ubyte outputSemanticName[],
   const ubyte outputSemanticIndex[],
   boolean passthrough_edgeflags,
   boolean clamp_color)
{
   struct st_translate translate, *t;
   unsigned i;
   enum pipe_error ret = PIPE_OK;

   assert(numInputs <= ARRAY_SIZE(t->inputs));
   assert(numOutputs <= ARRAY_SIZE(t->outputs));

   t = &translate;
   memset(t, 0, sizeof *t);

   t->procType = procType;
   t->inputMapping = inputMapping;
   t->outputMapping = outputMapping;
   t->ureg = ureg;

   /*_mesa_print_program(program);*/

   /*
    * Declare input attributes.
    */
   if (procType == TGSI_PROCESSOR_FRAGMENT) {
      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_fs_input(ureg,
                                           inputSemanticName[i],
                                           inputSemanticIndex[i],
                                           interpMode[i]);
      }

      if (program->InputsRead & VARYING_BIT_POS) {
         /* Must do this after setting up t->inputs, and before
          * emitting constant references, below:
          */
         emit_wpos(st_context(ctx), t, program, ureg);
      }

      if (program->InputsRead & VARYING_BIT_FACE) {
         emit_face_var( t, program );
      }

      /*
       * Declare output attributes.
       */
      for (i = 0; i < numOutputs; i++) {
         switch (outputSemanticName[i]) {
         case TGSI_SEMANTIC_POSITION:
            t->outputs[i] = ureg_DECL_output( ureg,
                                              TGSI_SEMANTIC_POSITION, /* Z / Depth */
                                              outputSemanticIndex[i] );

            t->outputs[i] = ureg_writemask( t->outputs[i],
                                            TGSI_WRITEMASK_Z );
            break;
         case TGSI_SEMANTIC_STENCIL:
            t->outputs[i] = ureg_DECL_output( ureg,
                                              TGSI_SEMANTIC_STENCIL, /* Stencil */
                                              outputSemanticIndex[i] );
            t->outputs[i] = ureg_writemask( t->outputs[i],
                                            TGSI_WRITEMASK_Y );
            break;
         case TGSI_SEMANTIC_COLOR:
            t->outputs[i] = ureg_DECL_output( ureg,
                                              TGSI_SEMANTIC_COLOR,
                                              outputSemanticIndex[i] );
            break;
         default:
            debug_assert(0);
            return 0;
         }
      }
   }
   else if (procType == TGSI_PROCESSOR_GEOMETRY) {
      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_input(ureg,
                                        inputSemanticName[i],
                                        inputSemanticIndex[i], 0, 1);
      }

      for (i = 0; i < numOutputs; i++) {
         t->outputs[i] = ureg_DECL_output( ureg,
                                           outputSemanticName[i],
                                           outputSemanticIndex[i] );
      }
   }
   else {
      assert(procType == TGSI_PROCESSOR_VERTEX);

      for (i = 0; i < numInputs; i++) {
         t->inputs[i] = ureg_DECL_vs_input(ureg, i);
      }

      for (i = 0; i < numOutputs; i++) {
         t->outputs[i] = ureg_DECL_output( ureg,
                                           outputSemanticName[i],
                                           outputSemanticIndex[i] );
         if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) {
            /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */
            ureg_MOV(ureg,
                     ureg_writemask(t->outputs[i], TGSI_WRITEMASK_YZW),
                     ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f));
            t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
	 }
      }
      if (passthrough_edgeflags)
         emit_edgeflags( t, program );
   }

   /* Declare address register.
    */
   if (program->NumAddressRegs > 0) {
      debug_assert( program->NumAddressRegs == 1 );
      t->address[0] = ureg_DECL_address( ureg );
   }

   /* Declare misc input registers
    */
   {
      GLbitfield sysInputs = program->SystemValuesRead;
      unsigned numSys = 0;
      for (i = 0; sysInputs; i++) {
         if (sysInputs & (1 << i)) {
            unsigned semName = _mesa_sysval_to_semantic[i];
            t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0);
            if (semName == TGSI_SEMANTIC_INSTANCEID ||
                semName == TGSI_SEMANTIC_VERTEXID) {
               /* From Gallium perspective, these system values are always
                * integer, and require native integer support.  However, if
                * native integer is supported on the vertex stage but not the
                * pixel stage (e.g, i915g + draw), Mesa will generate IR that
                * assumes these system values are floats. To resolve the
                * inconsistency, we insert a U2F.
                */
               struct st_context *st = st_context(ctx);
               struct pipe_screen *pscreen = st->pipe->screen;
               assert(procType == TGSI_PROCESSOR_VERTEX);
               assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS));
               (void) pscreen;  /* silence non-debug build warnings */
               if (!ctx->Const.NativeIntegers) {
                  struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg);
                  ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]);
                  t->systemValues[i] = ureg_scalar(ureg_src(temp), 0);
               }
            }
            numSys++;
            sysInputs &= ~(1 << i);
         }
      }
   }

   if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) {
      /* If temps are accessed with indirect addressing, declare temporaries
       * in sequential order.  Else, we declare them on demand elsewhere.
       */
      for (i = 0; i < program->NumTemporaries; i++) {
         /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
         t->temps[i] = ureg_DECL_temporary( t->ureg );
      }
   }

   /* Emit constants and immediates.  Mesa uses a single index space
    * for these, so we put all the translated regs in t->constants.
    */
   if (program->Parameters) {
      t->constants = calloc( program->Parameters->NumParameters,
                             sizeof t->constants[0] );
      if (t->constants == NULL) {
         ret = PIPE_ERROR_OUT_OF_MEMORY;
         goto out;
      }

      for (i = 0; i < program->Parameters->NumParameters; i++) {
         switch (program->Parameters->Parameters[i].Type) {
         case PROGRAM_STATE_VAR:
         case PROGRAM_UNIFORM:
            t->constants[i] = ureg_DECL_constant( ureg, i );
            break;

            /* Emit immediates only when there's no indirect addressing of
             * the const buffer.
             * FIXME: Be smarter and recognize param arrays:
             * indirect addressing is only valid within the referenced
             * array.
             */
         case PROGRAM_CONSTANT:
            if (program->IndirectRegisterFiles & PROGRAM_ANY_CONST)
               t->constants[i] = ureg_DECL_constant( ureg, i );
            else
               t->constants[i] = 
                  ureg_DECL_immediate( ureg,
                                       (const float*) program->Parameters->ParameterValues[i],
                                       4 );
            break;
         default:
            break;
         }
      }
   }

   /* texture samplers */
   for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) {
      if (program->SamplersUsed & (1 << i)) {
         t->samplers[i] = ureg_DECL_sampler( ureg, i );
      }
   }

   /* Emit each instruction in turn:
    */
   for (i = 0; i < program->NumInstructions; i++) {
      set_insn_start( t, ureg_get_instruction_number( ureg ));
      compile_instruction( ctx, t, &program->Instructions[i], clamp_color );
   }

   /* Fix up all emitted labels:
    */
   for (i = 0; i < t->labels_count; i++) {
      ureg_fixup_label( ureg,
                        t->labels[i].token,
                        t->insn[t->labels[i].branch_target] );
   }

out:
   free(t->insn);
   free(t->labels);
   free(t->constants);

   if (t->error) {
      debug_printf("%s: translate error flag set\n", __func__);
   }

   return ret;
}
Beispiel #14
0
void *si_get_blitter_vs(struct si_context *sctx, enum blitter_attrib_type type,
			unsigned num_layers)
{
	unsigned vs_blit_property;
	void **vs;

	switch (type) {
	case UTIL_BLITTER_ATTRIB_NONE:
		vs = num_layers > 1 ? &sctx->vs_blit_pos_layered :
				      &sctx->vs_blit_pos;
		vs_blit_property = SI_VS_BLIT_SGPRS_POS;
		break;
	case UTIL_BLITTER_ATTRIB_COLOR:
		vs = num_layers > 1 ? &sctx->vs_blit_color_layered :
				      &sctx->vs_blit_color;
		vs_blit_property = SI_VS_BLIT_SGPRS_POS_COLOR;
		break;
	case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
	case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
		assert(num_layers == 1);
		vs = &sctx->vs_blit_texcoord;
		vs_blit_property = SI_VS_BLIT_SGPRS_POS_TEXCOORD;
		break;
	default:
		assert(0);
		return NULL;
	}
	if (*vs)
		return *vs;

	struct ureg_program *ureg = ureg_create(PIPE_SHADER_VERTEX);
	if (!ureg)
		return NULL;

	/* Tell the shader to load VS inputs from SGPRs: */
	ureg_property(ureg, TGSI_PROPERTY_VS_BLIT_SGPRS, vs_blit_property);
	ureg_property(ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, true);

	/* This is just a pass-through shader with 1-3 MOV instructions. */
	ureg_MOV(ureg,
		 ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0),
		 ureg_DECL_vs_input(ureg, 0));

	if (type != UTIL_BLITTER_ATTRIB_NONE) {
		ureg_MOV(ureg,
			 ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0),
			 ureg_DECL_vs_input(ureg, 1));
	}

	if (num_layers > 1) {
		struct ureg_src instance_id =
			ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);
		struct ureg_dst layer =
			ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);

		ureg_MOV(ureg, ureg_writemask(layer, TGSI_WRITEMASK_X),
			 ureg_scalar(instance_id, TGSI_SWIZZLE_X));
	}
	ureg_END(ureg);

	*vs = ureg_create_shader_and_destroy(ureg, &sctx->b);
	return *vs;
}
Beispiel #15
0
static void *
create_vert_shader(struct vl_compositor *c)
{
   struct ureg_program *shader;
   struct ureg_src vpos, vtex, color;
   struct ureg_dst tmp;
   struct ureg_dst o_vpos, o_vtex, o_color;
   struct ureg_dst o_vtop, o_vbottom;

   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
   if (!shader)
      return false;

   vpos = ureg_DECL_vs_input(shader, 0);
   vtex = ureg_DECL_vs_input(shader, 1);
   color = ureg_DECL_vs_input(shader, 2);
   tmp = ureg_DECL_temporary(shader);
   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
   o_color = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR);
   o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);
   o_vtop = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP);
   o_vbottom = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM);

   /*
    * o_vpos = vpos
    * o_vtex = vtex
    * o_color = color
    */
   ureg_MOV(shader, o_vpos, vpos);
   ureg_MOV(shader, o_vtex, vtex);
   ureg_MOV(shader, o_color, color);

   /*
    * tmp.x = vtex.w / 2
    * tmp.y = vtex.w / 4
    *
    * o_vtop.x = vtex.x
    * o_vtop.y = vtex.y * tmp.x + 0.25f
    * o_vtop.z = vtex.y * tmp.y + 0.25f
    * o_vtop.w = 1 / tmp.x
    *
    * o_vbottom.x = vtex.x
    * o_vbottom.y = vtex.y * tmp.x - 0.25f
    * o_vbottom.z = vtex.y * tmp.y - 0.25f
    * o_vbottom.w = 1 / tmp.y
    */
   ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X),
            ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.5f));
   ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y),
            ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.25f));

   ureg_MOV(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_X), vtex);
   ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, 0.25f));
   ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.25f));
   ureg_RCP(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_W),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));

   ureg_MOV(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_X), vtex);
   ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, -0.25f));
   ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, -0.25f));
   ureg_RCP(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_W),
            ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y));

   ureg_END(shader);

   return ureg_create_shader_and_destroy(shader, c->pipe);
}
Beispiel #16
0
static void *
create_vert_shader(struct vl_zscan *zscan)
{
   struct ureg_program *shader;
   struct ureg_src scale;
   struct ureg_src vrect, vpos, block_num;
   struct ureg_dst tmp;
   struct ureg_dst o_vpos;
   struct ureg_dst *o_vtex;
   unsigned i;

   shader = ureg_create(PIPE_SHADER_VERTEX);
   if (!shader)
      return NULL;

   o_vtex = MALLOC(zscan->num_channels * sizeof(struct ureg_dst));

   scale = ureg_imm2f(shader,
      (float)VL_BLOCK_WIDTH / zscan->buffer_width,
      (float)VL_BLOCK_HEIGHT / zscan->buffer_height);

   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
   block_num = ureg_DECL_vs_input(shader, VS_I_BLOCK_NUM);

   tmp = ureg_DECL_temporary(shader);

   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);

   for (i = 0; i < zscan->num_channels; ++i)
      o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX + i);

   /*
    * o_vpos.xy = (vpos + vrect) * scale
    * o_vpos.zw = 1.0f
    *
    * tmp.xy = InstanceID / blocks_per_line
    * tmp.x = frac(tmp.x)
    * tmp.y = floor(tmp.y)
    *
    * o_vtex.x = vrect.x / blocks_per_line + tmp.x
    * o_vtex.y = vrect.y
    * o_vtex.z = tmp.z * blocks_per_line / blocks_total
    */
   ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), vpos, vrect);
   ureg_MUL(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(tmp), scale);
   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));

   ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XW), ureg_scalar(block_num, TGSI_SWIZZLE_X),
            ureg_imm1f(shader, 1.0f / zscan->blocks_per_line));

   ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
   ureg_FLR(shader, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_src(tmp));

   for (i = 0; i < zscan->num_channels; ++i) {
      ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y),
               ureg_imm1f(shader, 1.0f / (zscan->blocks_per_line * VL_BLOCK_WIDTH)
                * (i - (signed)zscan->num_channels / 2)));

      ureg_MAD(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_X), vrect,
               ureg_imm1f(shader, 1.0f / zscan->blocks_per_line), ureg_src(tmp));
      ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Y), vrect);
      ureg_MOV(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_Z), vpos);
      ureg_MUL(shader, ureg_writemask(o_vtex[i], TGSI_WRITEMASK_W), ureg_src(tmp),
               ureg_imm1f(shader, (float)zscan->blocks_per_line / zscan->blocks_total));
   }

   ureg_release_temporary(shader, tmp);
   ureg_END(shader);

   FREE(o_vtex);

   return ureg_create_shader_and_destroy(shader, zscan->pipe);
}
Beispiel #17
0
/**
 * The current vertex shader is already executed by the 'draw'
 * module, so we just need to generate a simple vertex shader
 * to pass through all those VS outputs that will
 * be consumed by the fragment shader.
 * Used when we employ the 'draw' module.
 */
static enum pipe_error
compile_passthrough_vs(struct svga_context *svga,
                       struct svga_vertex_shader *vs,
                       struct svga_fragment_shader *fs,
                       struct svga_shader_variant **out_variant)
{
   struct svga_shader_variant *variant = NULL;
   unsigned num_inputs;
   unsigned i;
   unsigned num_elements;
   struct svga_vertex_shader new_vs;
   struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
   struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
   struct ureg_program *ureg;
   unsigned num_tokens;
   struct svga_compile_key key;
   enum pipe_error ret;

   assert(svga_have_vgpu10(svga));
   assert(fs);

   num_inputs = fs->base.info.num_inputs;

   ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
   if (!ureg)
      return PIPE_ERROR_OUT_OF_MEMORY;

   /* draw will always add position */
   dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
   src[0] = ureg_DECL_vs_input(ureg, 0);
   num_elements = 1;

   /**
    * swtnl backend redefines the input layout based on the
    * fragment shader's inputs. So we only need to passthrough
    * those inputs that will be consumed by the fragment shader.
    * Note: DX10 requires the number of vertex elements
    * specified in the input layout to be no less than the
    * number of inputs to the vertex shader.
    */
   for (i = 0; i < num_inputs; i++) {
      switch (fs->base.info.input_semantic_name[i]) {
      case TGSI_SEMANTIC_COLOR:
      case TGSI_SEMANTIC_GENERIC:
      case TGSI_SEMANTIC_FOG:
         dst[num_elements] = ureg_DECL_output(ureg,
                                fs->base.info.input_semantic_name[i],
                                fs->base.info.input_semantic_index[i]);
         src[num_elements] = ureg_DECL_vs_input(ureg, num_elements);
         num_elements++;
         break;
      default:
         break;
      }
   }

   for (i = 0; i < num_elements; i++) {
      ureg_MOV(ureg, dst[i], src[i]);
   }

   ureg_END(ureg);

   memset(&new_vs, 0, sizeof(new_vs));
   new_vs.base.tokens = ureg_get_tokens(ureg, &num_tokens);
   tgsi_scan_shader(new_vs.base.tokens, &new_vs.base.info);

   memset(&key, 0, sizeof(key));
   key.vs.undo_viewport = 1;

   ret = compile_vs(svga, &new_vs, &key, &variant);
   if (ret != PIPE_OK)
      return ret;

   ureg_free_tokens(new_vs.base.tokens);
   ureg_destroy(ureg);

   /* Overwrite the variant key to indicate it's a pass-through VS */
   memset(&variant->key, 0, sizeof(variant->key));
   variant->key.vs.passthrough = 1;
   variant->key.vs.undo_viewport = 1;

   *out_variant = variant;

   return PIPE_OK;
}
static void *
create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, void *callback_priv)
{
   struct ureg_program *shader;

   struct ureg_src vrect, vpos;
   struct ureg_dst t_vpos, t_vtex;
   struct ureg_dst o_vpos, o_flags;

   struct vertex2f scale = {
      (float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size,
      (float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size
   };

   unsigned label;

   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
   if (!shader)
      return NULL;

   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);

   t_vpos = calc_position(r, shader, ureg_imm2f(shader, scale.x, scale.y));
   t_vtex = ureg_DECL_temporary(shader);

   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
   o_flags = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS);

   /*
    * o_vtex.xy = t_vpos
    * o_flags.z = intra * 0.5
    *
    * if(interlaced) {
    *    t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 }
    *    t_vtex.z = vpos.y % 2
    *    t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y
    *    o_vpos.y = t_vtex.y + t_vpos.y
    *
    *    o_flags.w = t_vtex.z ? 0 : 1
    * }
    *
    */

   vs_callback(callback_priv, r, shader, VS_O_VTEX, t_vpos);

   ureg_MUL(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_Z),
            ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f));
   ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f));

   if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO
      ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label);

         ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY),
                  ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_Y)),
                  ureg_imm2f(shader, 0.0f, scale.y),
                  ureg_imm2f(shader, -scale.y, 0.0f));
         ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z),
                  ureg_scalar(vpos, TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.5f));

         ureg_FRC(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_src(t_vtex));

         ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y),
                  ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)),
                  ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_X),
                  ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Y));
         ureg_ADD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_Y),
                  ureg_src(t_vpos), ureg_src(t_vtex));

         ureg_CMP(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W),
                  ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)),
                  ureg_imm1f(shader, 0.0f), ureg_imm1f(shader, 1.0f));

      ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
      ureg_ENDIF(shader);
   }

   ureg_release_temporary(shader, t_vtex);
   ureg_release_temporary(shader, t_vpos);

   ureg_END(shader);

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