Пример #1
0
/* If there are lots of sprite points (and why wouldn't there be?) it
 * would probably be more sensible to change hardware setup to
 * optimize this rather than doing the whole thing in software like
 * this.
 */
static void widepoint_point( struct draw_stage *stage,
                             struct prim_header *header )
{
   const struct widepoint_stage *wide = widepoint_stage(stage);
   const unsigned pos = draw_current_shader_position_output(stage->draw);
   const boolean sprite = (boolean) stage->draw->rasterizer->point_quad_rasterization;
   float half_size;
   float left_adj, right_adj, bot_adj, top_adj;

   struct prim_header tri;

   /* four dups of original vertex */
   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
   struct vertex_header *v2 = dup_vert(stage, header->v[0], 2);
   struct vertex_header *v3 = dup_vert(stage, header->v[0], 3);

   float *pos0 = v0->data[pos];
   float *pos1 = v1->data[pos];
   float *pos2 = v2->data[pos];
   float *pos3 = v3->data[pos];

   /* point size is either per-vertex or fixed size */
   if (wide->psize_slot >= 0) {
      half_size = header->v[0]->data[wide->psize_slot][0];
      half_size *= 0.5f; 
   }
   else {
      half_size = wide->half_point_size;
   }

   left_adj = -half_size + wide->xbias;
   right_adj = half_size + wide->xbias;
   bot_adj = half_size + wide->ybias;
   top_adj = -half_size + wide->ybias;

   pos0[0] += left_adj;
   pos0[1] += top_adj;

   pos1[0] += left_adj;
   pos1[1] += bot_adj;

   pos2[0] += right_adj;
   pos2[1] += top_adj;

   pos3[0] += right_adj;
   pos3[1] += bot_adj;

   if (sprite) {
      static const float tex00[4] = { 0, 0, 0, 1 };
      static const float tex01[4] = { 0, 1, 0, 1 };
      static const float tex11[4] = { 1, 1, 0, 1 };
      static const float tex10[4] = { 1, 0, 0, 1 };
      set_texcoords( wide, v0, tex00 );
      set_texcoords( wide, v1, tex01 );
      set_texcoords( wide, v2, tex10 );
      set_texcoords( wide, v3, tex11 );
   }

   tri.det = header->det;  /* only the sign matters */
   tri.v[0] = v0;
   tri.v[1] = v2;
   tri.v[2] = v3;
   stage->next->tri( stage->next, &tri );

   tri.v[0] = v0;
   tri.v[1] = v3;
   tri.v[2] = v1;
   stage->next->tri( stage->next, &tri );
}
Пример #2
0
static void
widepoint_first_point(struct draw_stage *stage, 
                      struct prim_header *header)
{
   struct widepoint_stage *wide = widepoint_stage(stage);
   struct draw_context *draw = stage->draw;
   struct pipe_context *pipe = draw->pipe;
   const struct pipe_rasterizer_state *rast = draw->rasterizer;
   void *r;

   wide->half_point_size = 0.5f * rast->point_size;
   wide->xbias = 0.0;
   wide->ybias = 0.0;

   if (rast->half_pixel_center) {
      wide->xbias = 0.125;
      wide->ybias = -0.125;
   }

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

   /* XXX we won't know the real size if it's computed by the vertex shader! */
   if ((rast->point_size > draw->pipeline.wide_point_threshold) ||
       (rast->point_quad_rasterization && draw->pipeline.point_sprite)) {
      stage->point = widepoint_point;
   }
   else {
      stage->point = draw_pipe_passthrough_point;
   }

   draw_remove_extra_vertex_attribs(draw);

   if (rast->point_quad_rasterization) {
      const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
      uint i;

      assert(fs);

      wide->num_texcoord_gen = 0;

      /* Loop over fragment shader inputs looking for the PCOORD input or inputs
       * for which bit 'k' in sprite_coord_enable is set.
       */
      for (i = 0; i < fs->info.num_inputs; i++) {
         int slot;
         const unsigned sn = fs->info.input_semantic_name[i];
         const unsigned si = fs->info.input_semantic_index[i];

         if (sn == wide->sprite_coord_semantic) {
            /* Note that sprite_coord_enable is a bitfield of 32 bits. */
            if (si >= 32 || !(rast->sprite_coord_enable & (1 << si)))
               continue;
         } else if (sn != TGSI_SEMANTIC_PCOORD) {
            continue;
         }

         /* OK, this generic attribute needs to be replaced with a
          * sprite coord (see above).
          */
         slot = draw_alloc_extra_vertex_attrib(draw, sn, si);

         /* add this slot to the texcoord-gen list */
         wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot;
      }
   }

   wide->psize_slot = -1;
   if (rast->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) {
            wide->psize_slot = i;
            break;
         }
      }
   }
   
   stage->point( stage, header );
}
Пример #3
0
static void widepoint_first_point( struct draw_stage *stage, 
			      struct prim_header *header )
{
   struct widepoint_stage *wide = widepoint_stage(stage);
   struct draw_context *draw = stage->draw;

   wide->half_point_size = 0.5f * draw->rasterizer->point_size;
   wide->point_size_min = draw->rasterizer->point_size_min;
   wide->point_size_max = draw->rasterizer->point_size_max;
   wide->xbias = 0.0;
   wide->ybias = 0.0;

   if (draw->rasterizer->gl_rasterization_rules) {
      wide->xbias = 0.125;
   }

   /* XXX we won't know the real size if it's computed by the vertex shader! */
   if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) ||
       (draw->rasterizer->point_sprite && draw->pipeline.point_sprite)) {
      stage->point = widepoint_point;
   }
   else {
      stage->point = draw_pipe_passthrough_point;
   }

   if (draw->rasterizer->point_sprite) {
      /* find vertex shader texcoord outputs */
      const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
      uint i, j = 0;
      for (i = 0; i < vs->info.num_outputs; i++) {
         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
            wide->texcoord_slot[j] = i;
            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
            j++;
         }
      }
      wide->num_texcoords = j;

      /* find fragment shader PointCoord/Fog input */
      wide->point_coord_fs_input = 0; /* XXX fix this! */

      /* setup extra vp output (point coord implemented as a texcoord) */
      draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
      draw->extra_vp_outputs.semantic_index = 0;
      draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs;
   }
   else {
      wide->point_coord_fs_input = -1;
      draw->extra_vp_outputs.slot = 0;
   }

   wide->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) {
            wide->psize_slot = i;
            break;
         }
      }
   }
   
   stage->point( stage, header );
}