/** * 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] */ }
/** * 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] */ }
/** * 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 } }