mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-23 23:30:22 +01:00
llvmpipe: whip out the intra-tile code from lp_setup_tri.c
The "setup" module handles building per-tile display lists. Intra-tile rendering is handled by lp_rast*.c
This commit is contained in:
parent
e529170c11
commit
5e13dfe618
1 changed files with 33 additions and 293 deletions
|
|
@ -26,12 +26,10 @@
|
|||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Recursive rasterization for triangles
|
||||
* Binning code for triangles
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_setup.h"
|
||||
#include "lp_state.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
|
@ -42,43 +40,6 @@
|
|||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#define BLOCKSIZE 4
|
||||
|
||||
struct triangle {
|
||||
/* one-pixel sized trivial accept offsets for each plane */
|
||||
float ei1;
|
||||
float ei2;
|
||||
float ei3;
|
||||
|
||||
/* one-pixel sized trivial reject offsets for each plane */
|
||||
float eo1;
|
||||
float eo2;
|
||||
float eo3;
|
||||
|
||||
/* y deltas for vertex pairs */
|
||||
float dy12;
|
||||
float dy23;
|
||||
float dy31;
|
||||
|
||||
/* x deltas for vertex pairs */
|
||||
float dx12;
|
||||
float dx23;
|
||||
float dx31;
|
||||
|
||||
/* Attribute interpolation:
|
||||
*/
|
||||
float oneoverarea;
|
||||
float x1;
|
||||
float y1;
|
||||
struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS];
|
||||
struct tgsi_interp_coef position_coef;
|
||||
|
||||
/* A run of pre-initialized quads:
|
||||
*/
|
||||
struct llvmpipe_context *llvmpipe;
|
||||
struct quad_header quad[4];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compute a0 for a constant-valued coefficient (GL_FLAT shading).
|
||||
|
|
@ -267,163 +228,6 @@ static inline float subpixel_snap( float a )
|
|||
}
|
||||
|
||||
|
||||
/* Convert 8x8 block into four runs of quads and render each in turn.
|
||||
*/
|
||||
#if (BLOCKSIZE == 8)
|
||||
static void block_full( struct triangle *tri, int x, int y )
|
||||
{
|
||||
struct quad_header *ptrs[4];
|
||||
int i;
|
||||
|
||||
tri->quad[0].input.x0 = x + 0;
|
||||
tri->quad[1].input.x0 = x + 2;
|
||||
tri->quad[2].input.x0 = x + 4;
|
||||
tri->quad[3].input.x0 = x + 6;
|
||||
|
||||
for (i = 0; i < 4; i++, y += 2) {
|
||||
tri->quad[0].inout.mask = 0xf;
|
||||
tri->quad[1].inout.mask = 0xf;
|
||||
tri->quad[2].inout.mask = 0xf;
|
||||
tri->quad[3].inout.mask = 0xf;
|
||||
|
||||
tri->quad[0].input.y0 = y;
|
||||
tri->quad[1].input.y0 = y;
|
||||
tri->quad[2].input.y0 = y;
|
||||
tri->quad[3].input.y0 = y;
|
||||
|
||||
/* XXX: don't bother with this ptrs business */
|
||||
ptrs[0] = &tri->quad[0];
|
||||
ptrs[1] = &tri->quad[1];
|
||||
ptrs[2] = &tri->quad[2];
|
||||
ptrs[3] = &tri->quad[3];
|
||||
|
||||
tri->llvmpipe->quad.first->run( tri->llvmpipe->quad.first, ptrs, 4 );
|
||||
}
|
||||
}
|
||||
#elif (BLOCKSIZE == 4)
|
||||
static void block_full( struct triangle *tri, int x, int y )
|
||||
{
|
||||
struct quad_header *ptrs[4];
|
||||
int iy;
|
||||
|
||||
tri->quad[0].input.x0 = x + 0;
|
||||
tri->quad[1].input.x0 = x + 2;
|
||||
|
||||
for (iy = 0; iy < 4; iy += 2) {
|
||||
tri->quad[0].inout.mask = 0xf;
|
||||
tri->quad[1].inout.mask = 0xf;
|
||||
|
||||
tri->quad[0].input.y0 = y + iy;
|
||||
tri->quad[1].input.y0 = y + iy;
|
||||
|
||||
/* XXX: don't bother with this ptrs business */
|
||||
ptrs[0] = &tri->quad[0];
|
||||
ptrs[1] = &tri->quad[1];
|
||||
|
||||
tri->llvmpipe->quad.first->run( tri->llvmpipe->quad.first, ptrs, 2 );
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void block_full( struct triangle *tri, int x, int y )
|
||||
{
|
||||
struct quad_header *ptrs[4];
|
||||
int iy;
|
||||
|
||||
tri->quad[0].input.x0 = x;
|
||||
tri->quad[0].input.y0 = y;
|
||||
tri->quad[0].inout.mask = 0xf;
|
||||
|
||||
ptrs[0] = &tri->quad[0];
|
||||
tri->llvmpipe->quad.first->run( tri->llvmpipe->quad.first, ptrs, 1 );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
do_quad( struct triangle *tri,
|
||||
int x, int y,
|
||||
float c1, float c2, float c3 )
|
||||
{
|
||||
struct quad_header *quad = &tri->quad[0];
|
||||
|
||||
float xstep1 = -tri->dy12;
|
||||
float xstep2 = -tri->dy23;
|
||||
float xstep3 = -tri->dy31;
|
||||
|
||||
float ystep1 = tri->dx12;
|
||||
float ystep2 = tri->dx23;
|
||||
float ystep3 = tri->dx31;
|
||||
|
||||
quad->input.x0 = x;
|
||||
quad->input.y0 = y;
|
||||
quad->inout.mask = 0;
|
||||
|
||||
if (c1 > 0 &&
|
||||
c2 > 0 &&
|
||||
c3 > 0)
|
||||
quad->inout.mask |= 1;
|
||||
|
||||
if (c1 + xstep1 > 0 &&
|
||||
c2 + xstep2 > 0 &&
|
||||
c3 + xstep3 > 0)
|
||||
quad->inout.mask |= 2;
|
||||
|
||||
if (c1 + ystep1 > 0 &&
|
||||
c2 + ystep2 > 0 &&
|
||||
c3 + ystep3 > 0)
|
||||
quad->inout.mask |= 4;
|
||||
|
||||
if (c1 + ystep1 + xstep1 > 0 &&
|
||||
c2 + ystep2 + xstep2 > 0 &&
|
||||
c3 + ystep3 + xstep3 > 0)
|
||||
quad->inout.mask |= 8;
|
||||
|
||||
if (quad->inout.mask)
|
||||
tri->llvmpipe->quad.first->run( tri->llvmpipe->quad.first, &quad, 1 );
|
||||
}
|
||||
|
||||
/* Evaluate each pixel in a block, generate a mask and possibly render
|
||||
* the quad:
|
||||
*/
|
||||
static void
|
||||
do_block( struct triangle *tri,
|
||||
int x, int y,
|
||||
float c1,
|
||||
float c2,
|
||||
float c3 )
|
||||
{
|
||||
const int step = 2;
|
||||
|
||||
float xstep1 = -step * tri->dy12;
|
||||
float xstep2 = -step * tri->dy23;
|
||||
float xstep3 = -step * tri->dy31;
|
||||
|
||||
float ystep1 = step * tri->dx12;
|
||||
float ystep2 = step * tri->dx23;
|
||||
float ystep3 = step * tri->dx31;
|
||||
|
||||
int ix, iy;
|
||||
|
||||
for (iy = 0; iy < BLOCKSIZE; iy += 2) {
|
||||
float cx1 = c1;
|
||||
float cx2 = c2;
|
||||
float cx3 = c3;
|
||||
|
||||
for (ix = 0; ix < BLOCKSIZE; ix += 2) {
|
||||
|
||||
do_quad(tri, x+ix, y+iy, cx1, cx2, cx3);
|
||||
|
||||
cx1 += xstep1;
|
||||
cx2 += xstep2;
|
||||
cx3 += xstep3;
|
||||
}
|
||||
|
||||
c1 += ystep1;
|
||||
c2 += ystep2;
|
||||
c3 += ystep3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -441,14 +245,14 @@ do_block( struct triangle *tri,
|
|||
#define MAX3(a,b,c) MAX2(MAX2(a,b),c)
|
||||
|
||||
static void
|
||||
do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
||||
do_triangle_ccw(struct lp_setup *setup,
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4],
|
||||
const float (*v3)[4],
|
||||
boolean frontfacing )
|
||||
{
|
||||
const int rt_width = llvmpipe->framebuffer.cbufs[0]->width;
|
||||
const int rt_height = llvmpipe->framebuffer.cbufs[0]->height;
|
||||
const int rt_width = setup->framebuffer.cbufs[0]->width;
|
||||
const int rt_height = setup->framebuffer.cbufs[0]->height;
|
||||
|
||||
const float y1 = subpixel_snap(v1[0][1]);
|
||||
const float y2 = subpixel_snap(v2[0][1]);
|
||||
|
|
@ -458,15 +262,12 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
const float x2 = subpixel_snap(v2[0][0]);
|
||||
const float x3 = subpixel_snap(v3[0][0]);
|
||||
|
||||
struct triangle tri;
|
||||
struct triangle *tri = allocate_triangle;
|
||||
float area;
|
||||
float c1, c2, c3;
|
||||
int i;
|
||||
int minx, maxx, miny, maxy;
|
||||
|
||||
tri.llvmpipe = llvmpipe;
|
||||
|
||||
|
||||
tri.dx12 = x1 - x2;
|
||||
tri.dx23 = x2 - x3;
|
||||
tri.dx31 = x3 - x1;
|
||||
|
|
@ -505,12 +306,7 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
|
||||
/* Setup parameter interpolants:
|
||||
*/
|
||||
setup_tri_coefficients( llvmpipe, &tri, v1, v2, v3, frontfacing );
|
||||
|
||||
for (i = 0; i < Elements(tri.quad); i++) {
|
||||
tri.quad[i].coef = tri.coef;
|
||||
tri.quad[i].posCoef = &tri.position_coef;
|
||||
}
|
||||
setup_tri_coefficients( setup, &tri, v1, v2, v3, frontfacing );
|
||||
|
||||
/* half-edge constants, will be interated over the whole
|
||||
* rendertarget.
|
||||
|
|
@ -548,73 +344,22 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
tri.ei2 = tri.dx23 - tri.dy23 - tri.eo2;
|
||||
tri.ei3 = tri.dx31 - tri.dy31 - tri.eo3;
|
||||
|
||||
minx &= ~(BLOCKSIZE-1); /* aligned blocks */
|
||||
miny &= ~(BLOCKSIZE-1); /* aligned blocks */
|
||||
minx &= ~(TILESIZE-1); /* aligned blocks */
|
||||
miny &= ~(TILESIZE-1); /* aligned blocks */
|
||||
|
||||
c1 += tri.dx12 * miny - tri.dy12 * minx;
|
||||
c2 += tri.dx23 * miny - tri.dy23 * minx;
|
||||
c3 += tri.dx31 * miny - tri.dy31 * minx;
|
||||
|
||||
if ((miny & ~15) == (maxy & ~15) &&
|
||||
(minx & ~15) == (maxx & ~15))
|
||||
if (miny + TILESIZE > maxy &&
|
||||
minx + TILESIZE > maxx)
|
||||
{
|
||||
const int step = 2;
|
||||
|
||||
float xstep1 = -step * tri.dy12;
|
||||
float xstep2 = -step * tri.dy23;
|
||||
float xstep3 = -step * tri.dy31;
|
||||
|
||||
float ystep1 = step * tri.dx12;
|
||||
float ystep2 = step * tri.dx23;
|
||||
float ystep3 = step * tri.dx31;
|
||||
|
||||
float eo1 = tri.eo1 * step;
|
||||
float eo2 = tri.eo2 * step;
|
||||
float eo3 = tri.eo3 * step;
|
||||
|
||||
int x, y;
|
||||
|
||||
/* Subdivide space into NxM blocks, where each block is square and
|
||||
* power-of-four in dimension.
|
||||
*
|
||||
* Trivially accept or reject blocks, else jump to per-pixel
|
||||
* examination above.
|
||||
/* Triangle is contained in a single tile:
|
||||
*/
|
||||
for (y = miny; y < maxy; y += step)
|
||||
{
|
||||
float cx1 = c1;
|
||||
float cx2 = c2;
|
||||
float cx3 = c3;
|
||||
|
||||
for (x = minx; x < maxx; x += step)
|
||||
{
|
||||
if (cx1 + eo1 < 0 ||
|
||||
cx2 + eo2 < 0 ||
|
||||
cx3 + eo3 < 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
do_quad(&tri, x, y, cx1, cx2, cx3);
|
||||
}
|
||||
|
||||
/* Iterate cx values across the region:
|
||||
*/
|
||||
cx1 += xstep1;
|
||||
cx2 += xstep2;
|
||||
cx3 += xstep3;
|
||||
}
|
||||
|
||||
/* Iterate c values down the region:
|
||||
*/
|
||||
c1 += ystep1;
|
||||
c2 += ystep2;
|
||||
c3 += ystep3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int step = BLOCKSIZE;
|
||||
const int step = TILESIZE;
|
||||
|
||||
float ei1 = tri.ei1 * step;
|
||||
float ei2 = tri.ei2 * step;
|
||||
|
|
@ -645,7 +390,6 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
float cx1 = c1;
|
||||
float cx2 = c2;
|
||||
float cx3 = c3;
|
||||
boolean in = false;
|
||||
|
||||
for (x = minx; x < maxx; x += step)
|
||||
{
|
||||
|
|
@ -654,21 +398,18 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
cx3 + eo3 < 0)
|
||||
{
|
||||
/* do nothing */
|
||||
if (in)
|
||||
break;
|
||||
}
|
||||
else if (cx1 + ei1 > 0 &&
|
||||
cx2 + ei2 > 0 &&
|
||||
cx3 + ei3 > 0)
|
||||
{
|
||||
in = TRUE;
|
||||
block_full(&tri, x, y); /* trivial accept */
|
||||
/* shade whole tile */
|
||||
bin_command(tile[x][y], lp_rast_shade_tile, &tri->inputs );
|
||||
}
|
||||
else
|
||||
{
|
||||
in = TRUE;
|
||||
// block_full(&tri, x, y); /* trivial accept */
|
||||
do_block(&tri, x, y, cx1, cx2, cx3);
|
||||
/* shade partial tile */
|
||||
bin_command(tile[x][y], lp_rast_triangle, &tri );
|
||||
}
|
||||
|
||||
/* Iterate cx values across the region:
|
||||
|
|
@ -687,23 +428,23 @@ do_triangle_ccw(struct llvmpipe_context *llvmpipe,
|
|||
}
|
||||
}
|
||||
|
||||
static void triangle_cw( struct llvmpipe_context *llvmpipe,
|
||||
static void triangle_cw( struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4] )
|
||||
{
|
||||
do_triangle_ccw( llvmpipe, v1, v0, v2, !llvmpipe->ccw_is_frontface );
|
||||
do_triangle_ccw( setup, v1, v0, v2, !setup->ccw_is_frontface );
|
||||
}
|
||||
|
||||
static void triangle_ccw( struct llvmpipe_context *llvmpipe,
|
||||
static void triangle_ccw( struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4] )
|
||||
{
|
||||
do_triangle_ccw( llvmpipe, v0, v1, v2, llvmpipe->ccw_is_frontface );
|
||||
do_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface );
|
||||
}
|
||||
|
||||
static void triangle_both( struct llvmpipe_context *llvmpipe,
|
||||
static void triangle_both( struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4] )
|
||||
|
|
@ -716,38 +457,37 @@ static void triangle_both( struct llvmpipe_context *llvmpipe,
|
|||
|
||||
/* det = cross(e,f).z */
|
||||
if (ex * fy - ey * fx < 0)
|
||||
triangle_ccw( llvmpipe, v0, v1, v2 );
|
||||
triangle_ccw( setup, v0, v1, v2 );
|
||||
else
|
||||
triangle_cw( llvmpipe, v0, v1, v2 );
|
||||
triangle_cw( setup, v0, v1, v2 );
|
||||
}
|
||||
|
||||
static void triangle_nop( struct llvmpipe_context *llvmpipe,
|
||||
static void triangle_nop( struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4] )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setup_prepare_tri( struct llvmpipe_context *llvmpipe )
|
||||
void setup_prepare_tri( struct setup_context *setup )
|
||||
{
|
||||
llvmpipe->ccw_is_frontface = (llvmpipe->rasterizer->front_winding ==
|
||||
PIPE_WINDING_CW);
|
||||
struct llvmpipe_context *llvmpipe = setup->llvmpipe;
|
||||
|
||||
setup->ccw_is_frontface = (llvmpipe->rasterizer->front_winding ==
|
||||
PIPE_WINDING_CW);
|
||||
|
||||
switch (llvmpipe->rasterizer->cull_mode) {
|
||||
case PIPE_WINDING_NONE:
|
||||
llvmpipe->triangle = triangle_both;
|
||||
setup->triangle = triangle_both;
|
||||
break;
|
||||
case PIPE_WINDING_CCW:
|
||||
llvmpipe->triangle = triangle_cw;
|
||||
setup->triangle = triangle_cw;
|
||||
break;
|
||||
case PIPE_WINDING_CW:
|
||||
llvmpipe->triangle = triangle_ccw;
|
||||
setup->triangle = triangle_ccw;
|
||||
break;
|
||||
default:
|
||||
llvmpipe->triangle = triangle_nop;
|
||||
setup->triangle = triangle_nop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue