示例#1
0
/**
 * Render a horizontal span of quads
 */
static void flush_spans( struct setup_context *setup )
{
   const int step = 16;
   const int xleft0 = setup->span.left[0];
   const int xleft1 = setup->span.left[1];
   const int xright0 = setup->span.right[0];
   const int xright1 = setup->span.right[1];
   struct quad_stage *pipe = setup->softpipe->quad.first;


   int minleft = block_x(MIN2(xleft0, xleft1));
   int maxright = MAX2(xright0, xright1);
   int x;

   for (x = minleft; x < maxright; x += step) {
      unsigned skip_left0 = CLAMP(xleft0 - x, 0, step);
      unsigned skip_left1 = CLAMP(xleft1 - x, 0, step);
      unsigned skip_right0 = CLAMP(x + step - xright0, 0, step);
      unsigned skip_right1 = CLAMP(x + step - xright1, 0, step);
      unsigned lx = x;
      unsigned q = 0;

      unsigned skipmask_left0 = (1U << skip_left0) - 1U;
      unsigned skipmask_left1 = (1U << skip_left1) - 1U;

      /* These calculations fail when step == 32 and skip_right == 0.
       */
      unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0);
      unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1);

      unsigned mask0 = ~skipmask_left0 & ~skipmask_right0;
      unsigned mask1 = ~skipmask_left1 & ~skipmask_right1;

      if (mask0 | mask1) {
         do {
            unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2);
            if (quadmask) {
               setup->quad[q].input.x0 = lx;
               setup->quad[q].input.y0 = setup->span.y;
               setup->quad[q].input.facing = setup->facing;
               setup->quad[q].inout.mask = quadmask;
               setup->quad_ptrs[q] = &setup->quad[q];
               q++;
            }
            mask0 >>= 2;
            mask1 >>= 2;
            lx += 2;
         } while (mask0 | mask1);

         pipe->run( pipe, setup->quad_ptrs, q );
      }
   }


   setup->span.y = 0;
   setup->span.right[0] = 0;
   setup->span.right[1] = 0;
   setup->span.left[0] = 1000000;     /* greater than right[0] */
   setup->span.left[1] = 1000000;     /* greater than right[1] */
}
示例#2
0
/**
 * Render a horizontal span of quads
 */
static void flush_spans( struct setup_context *setup )
{
   const int step = TILE_VECTOR_WIDTH;
   const int xleft0 = setup->span.left[0];
   const int xleft1 = setup->span.left[1];
   const int xright0 = setup->span.right[0];
   const int xright1 = setup->span.right[1];


   int minleft = block_x(MIN2(xleft0, xleft1));
   int maxright = MAX2(xright0, xright1);
   int x;

   for (x = minleft; x < maxright; x += step) {
      unsigned skip_left0 = CLAMP(xleft0 - x, 0, step);
      unsigned skip_left1 = CLAMP(xleft1 - x, 0, step);
      unsigned skip_right0 = CLAMP(x + step - xright0, 0, step);
      unsigned skip_right1 = CLAMP(x + step - xright1, 0, step);
      unsigned lx = x;
      const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE;
      unsigned q = 0;

      unsigned skipmask_left0 = (1U << skip_left0) - 1U;
      unsigned skipmask_left1 = (1U << skip_left1) - 1U;

      /* These calculations fail when step == 32 and skip_right == 0.
       */
      unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0);
      unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1);

      unsigned mask0 = ~skipmask_left0 & ~skipmask_right0;
      unsigned mask1 = ~skipmask_left1 & ~skipmask_right1;

      if (mask0 | mask1) {
         for(q = 0; q < nr_quads; ++q) {
            unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2);
            setup->quad[q].input.x0 = lx;
            setup->quad[q].input.y0 = setup->span.y;
            setup->quad[q].inout.mask = quadmask;
            setup->quad_ptrs[q] = &setup->quad[q];
            mask0 >>= 2;
            mask1 >>= 2;
            lx += 2;
         }
         assert(!(mask0 | mask1));

         shade_quads(setup->llvmpipe, setup->quad_ptrs, nr_quads );
      }
   }


   setup->span.y = 0;
   setup->span.right[0] = 0;
   setup->span.right[1] = 0;
   setup->span.left[0] = 1000000;     /* greater than right[0] */
   setup->span.left[1] = 1000000;     /* greater than right[1] */
}
示例#3
0
/**
 * Emit a quad (pass to next stage) with clipping.
 */
static INLINE void
clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
{
   quad_clip( setup, quad );

   if (quad->inout.mask) {
      struct llvmpipe_context *lp = setup->llvmpipe;

#if 1
      /* XXX: The blender expects 4 quads. This is far from efficient, but
       * until we codegenerate single-quad variants of the fragment pipeline
       * we need this hack. */
      const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE;
      struct quad_header quads[4];
      struct quad_header *quad_ptrs[4];
      int x0 = block_x(quad->input.x0);
      unsigned i;

      assert(nr_quads == 4);

      for(i = 0; i < nr_quads; ++i) {
         int x = x0 + 2*i;
         if(x == quad->input.x0)
            memcpy(&quads[i], quad, sizeof quads[i]);
         else {
            memset(&quads[i], 0, sizeof quads[i]);
            quads[i].input.x0 = x;
            quads[i].input.y0 = quad->input.y0;
            quads[i].coef = quad->coef;
         }
         quad_ptrs[i] = &quads[i];
      }

      shade_quads( lp, quad_ptrs, nr_quads );
#else
      shade_quads( lp, &quad, 1 );
#endif
   }
}