コード例 #1
0
ファイル: draw_context.c プロジェクト: Forzaferrarileo/mesa
/**
 * Allocate an extra vertex/geometry shader vertex attribute, if it doesn't
 * exist already.
 *
 * This is used by some of the optional draw module stages such
 * as wide_point which may need to allocate additional generic/texcoord
 * attributes.
 */
int
draw_alloc_extra_vertex_attrib(struct draw_context *draw,
                               uint semantic_name, uint semantic_index)
{
   int slot;
   uint num_outputs;
   uint n;

   slot = draw_find_shader_output(draw, semantic_name, semantic_index);
   if (slot > 0) {
      return slot;
   }

   num_outputs = draw_current_shader_outputs(draw);
   n = draw->extra_shader_outputs.num;

   assert(n < Elements(draw->extra_shader_outputs.semantic_name));

   draw->extra_shader_outputs.semantic_name[n] = semantic_name;
   draw->extra_shader_outputs.semantic_index[n] = semantic_index;
   draw->extra_shader_outputs.slot[n] = num_outputs + n;
   draw->extra_shader_outputs.num++;

   return draw->extra_shader_outputs.slot[n];
}
コード例 #2
0
static void
aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
{
   auto struct aapoint_stage *aapoint = aapoint_stage(stage);
   struct draw_context *draw = stage->draw;
   struct pipe_context *pipe = draw->pipe;
   const struct pipe_rasterizer_state *rast = draw->rasterizer;
   void *r;

   assert(draw->rasterizer->point_smooth);

   if (draw->rasterizer->point_size <= 2.0)
      aapoint->radius = 1.0;
   else
      aapoint->radius = 0.5f * draw->rasterizer->point_size;

   /*
    * Bind (generate) our fragprog.
    */
   bind_aapoint_fragment_shader(aapoint);

   /* update vertex attrib info */
   aapoint->tex_slot = draw_current_shader_outputs(draw);
   assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */

   aapoint->pos_slot = draw_current_shader_position_output(draw);

   draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
   draw->extra_shader_outputs.semantic_index = aapoint->fs->generic_attrib;
   draw->extra_shader_outputs.slot = aapoint->tex_slot;

   /* find psize slot in post-transform vertex */
   aapoint->psize_slot = -1;
   if (draw->rasterizer->point_size_per_vertex) {
      /* find PSIZ vertex output */
      const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
      uint i;
      for (i = 0; i < vs->info.num_outputs; i++) {
         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
            aapoint->psize_slot = i;
            break;
         }
      }
   }

   draw->suspend_flushing = TRUE;

   /* Disable triangle culling, stippling, unfilled mode etc. */
   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
   pipe->bind_rasterizer_state(pipe, r);

   draw->suspend_flushing = FALSE;

   /* now really draw first point */
   stage->point = aapoint_point;
   stage->point(stage, header);
}
コード例 #3
0
static void
aaline_first_line(struct draw_stage *stage, struct prim_header *header)
{
   auto struct aaline_stage *aaline = aaline_stage(stage);
   struct draw_context *draw = stage->draw;
   struct pipe_context *pipe = draw->pipe;
   const struct pipe_rasterizer_state *rast = draw->rasterizer;
   uint num_samplers;
   void *r;

   assert(draw->rasterizer->line_smooth);

   if (draw->rasterizer->line_width <= 2.2)
      aaline->half_line_width = 1.1f;
   else
      aaline->half_line_width = 0.5f * draw->rasterizer->line_width;

   /*
    * Bind (generate) our fragprog, sampler and texture
    */
   if (!bind_aaline_fragment_shader(aaline)) {
      stage->line = draw_pipe_passthrough_line;
      stage->line(stage, header);
      return;
   }

   /* update vertex attrib info */
   aaline->tex_slot = draw_current_shader_outputs(draw);
   aaline->pos_slot = draw_current_shader_position_output(draw);;

   /* allocate the extra post-transformed vertex attribute */
   (void) draw_alloc_extra_vertex_attrib(draw, TGSI_SEMANTIC_GENERIC,
                                         aaline->fs->generic_attrib);

   /* how many samplers? */
   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
   num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);
   num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);

   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
   pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
                               aaline->sampler_view);

   draw->suspend_flushing = TRUE;
   aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
   aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);

   /* Disable triangle culling, stippling, unfilled mode etc. */
   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
   pipe->bind_rasterizer_state(pipe, r);

   draw->suspend_flushing = FALSE;

   /* now really draw first line */
   stage->line = aaline_line;
   stage->line(stage, header);
}
コード例 #4
0
ファイル: draw_context.c プロジェクト: nikai3d/mesa
/**
 * Allocate an extra vertex/geometry shader vertex attribute.
 * This is used by some of the optional draw module stages such
 * as wide_point which may need to allocate additional generic/texcoord
 * attributes.
 */
int
draw_alloc_extra_vertex_attrib(struct draw_context *draw,
                               uint semantic_name, uint semantic_index)
{
   const int num_outputs = draw_current_shader_outputs(draw);
   const int n = draw->extra_shader_outputs.num;

   assert(n < Elements(draw->extra_shader_outputs.semantic_name));

   draw->extra_shader_outputs.semantic_name[n] = semantic_name;
   draw->extra_shader_outputs.semantic_index[n] = semantic_index;
   draw->extra_shader_outputs.slot[n] = num_outputs + n;
   draw->extra_shader_outputs.num++;

   return draw->extra_shader_outputs.slot[n];
}
コード例 #5
0
ファイル: draw_pipe_clip.c プロジェクト: mlankhorst/Mesa-3D
/* Interpolate between two vertices to produce a third.  
 */
static void interp( const struct clip_stage *clip,
		    struct vertex_header *dst,
		    float t,
		    const struct vertex_header *out, 
		    const struct vertex_header *in )
{
   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
   unsigned j;

   /* Vertex header.
    */
   dst->clipmask = 0;
   dst->edgeflag = 0;        /* will get overwritten later */
   dst->pad = 0;
   dst->vertex_id = UNDEFINED_VERTEX_ID;

   /* Interpolate the clip-space coords.
    */
   interp_attr(dst->clip, t, in->clip, out->clip);

   /* Do the projective divide and viewport transformation to get
    * new window coordinates:
    */
   {
      const float *pos = dst->clip;
      const float *scale = clip->stage.draw->viewport.scale;
      const float *trans = clip->stage.draw->viewport.translate;
      const float oow = 1.0f / pos[3];

      dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
      dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
      dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
      dst->data[pos_attr][3] = oow;
   }

   /* Other attributes
    */
   for (j = 0; j < nr_attrs; j++) {
      if (j != pos_attr)
         interp_attr(dst->data[j], t, in->data[j], out->data[j]);
   }
}
コード例 #6
0
/**
 * Compute interpolated vertex attributes for 'dst' at position 't' 
 * between 'v0' and 'v1'.
 * XXX using linear interpolation for all attribs at this time.
 */
static void
screen_interp( struct draw_context *draw,
               struct vertex_header *dst,
               float t,
               const struct vertex_header *v0, 
               const struct vertex_header *v1 )
{
   uint attr;
   uint num_outputs = draw_current_shader_outputs(draw);
   for (attr = 0; attr < num_outputs; attr++) {
      const float *val0 = v0->data[attr];
      const float *val1 = v1->data[attr];
      float *newv = dst->data[attr];
      uint i;
      for (i = 0; i < 4; i++) {
         newv[i] = val0[i] + t * (val1[i] - val0[i]);
      }
   }
}
コード例 #7
0
ファイル: draw_pipe_clip.c プロジェクト: Forzaferrarileo/mesa
/* Interpolate between two vertices to produce a third.  
 */
static void interp( const struct clip_stage *clip,
		    struct vertex_header *dst,
		    float t,
		    const struct vertex_header *out, 
		    const struct vertex_header *in )
{
   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
   const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
   unsigned j;
   float t_nopersp;

   /* Vertex header.
    */
   dst->clipmask = 0;
   dst->edgeflag = 0;        /* will get overwritten later */
   dst->have_clipdist = in->have_clipdist;
   dst->vertex_id = UNDEFINED_VERTEX_ID;

   /* Interpolate the clip-space coords.
    */
   interp_attr(dst->clip, t, in->clip, out->clip);
   /* interpolate the clip-space position */
   interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos);

   /* Do the projective divide and viewport transformation to get
    * new window coordinates:
    */
   {
      const float *pos = dst->pre_clip_pos;
      const float *scale = clip->stage.draw->viewport.scale;
      const float *trans = clip->stage.draw->viewport.translate;
      const float oow = 1.0f / pos[3];

      dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
      dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
      dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
      dst->data[pos_attr][3] = oow;
   }
   
   /**
    * Compute the t in screen-space instead of 3d space to use
    * for noperspective interpolation.
    *
    * The points can be aligned with the X axis, so in that case try
    * the Y.  When both points are at the same screen position, we can
    * pick whatever value (the interpolated point won't be in front
    * anyway), so just use the 3d t.
    */
   {
      int k;
      t_nopersp = t;
      /* find either in.x != out.x or in.y != out.y */
      for (k = 0; k < 2; k++) {
         if (in->clip[k] != out->clip[k]) {
            /* do divide by W, then compute linear interpolation factor */
            float in_coord = in->clip[k] / in->clip[3];
            float out_coord = out->clip[k] / out->clip[3];
            float dst_coord = dst->clip[k] / dst->clip[3];
            t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord);
            break;
         }
      }
   }

   /* Other attributes
    */
   for (j = 0; j < nr_attrs; j++) {
      if (j != pos_attr && j != clip_attr) {
         if (clip->noperspective_attribs[j])
            interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]);
         else
            interp_attr(dst->data[j], t, in->data[j], out->data[j]);
      }
   }
}