From 89498d01531cd515c769e570bf799c39fbafc8fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 7 Oct 2009 22:36:43 +0100 Subject: llvmpipe: import experimental softpipe rasterizer code, wip binning code WIP, does't build or run. Rasterizer code is based on Nick Capen's devmaster posts and the larrabee articles, but currently doesn't share either the performance or correctness of either... --- src/gallium/drivers/llvmpipe/lp_setup.c | 1432 +------------------------------ 1 file changed, 38 insertions(+), 1394 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 60107214df..8c67524506 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -26,15 +26,15 @@ **************************************************************************/ /** - * \brief Primitive rasterization/rendering (points, lines, triangles) + * \brief Primitive rasterization/rendering (points, lines) * * \author Keith Whitwell * \author Brian Paul */ #include "lp_context.h" -#include "lp_prim_setup.h" #include "lp_quad.h" +#include "lp_quad_pipe.h" #include "lp_setup.h" #include "lp_state.h" #include "draw/draw_context.h" @@ -44,1397 +44,49 @@ #include "pipe/p_thread.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "lp_bld_debug.h" -#include "lp_tile_cache.h" -#include "lp_tile_soa.h" #define DEBUG_VERTS 0 -#define DEBUG_FRAGS 0 -/** - * Triangle edge info - */ -struct edge { - float dx; /**< X(v1) - X(v0), used only during setup */ - float dy; /**< Y(v1) - Y(v0), used only during setup */ - float dxdy; /**< dx/dy */ - float sx, sy; /**< first sample point coord */ - int lines; /**< number of lines on this edge */ -}; - - -#define MAX_QUADS 16 - - -/** - * Triangle setup info (derived from draw_stage). - * Also used for line drawing (taking some liberties). - */ -struct setup_context { - struct llvmpipe_context *llvmpipe; - - /* Vertices are just an array of floats making up each attribute in - * turn. Currently fixed at 4 floats, but should change in time. - * Codegen will help cope with this. - */ - const float (*vmax)[4]; - const float (*vmid)[4]; - const float (*vmin)[4]; - const float (*vprovoke)[4]; - - struct edge ebot; - struct edge etop; - struct edge emaj; - - float oneoverarea; - int facing; - - struct quad_header quad[MAX_QUADS]; - struct quad_header *quad_ptrs[MAX_QUADS]; - unsigned count; - - struct quad_interp_coef coef; - - struct { - int left[2]; /**< [0] = row0, [1] = row1 */ - int right[2]; - int y; - } span; - -#if DEBUG_FRAGS - uint numFragsEmitted; /**< per primitive */ - uint numFragsWritten; /**< per primitive */ -#endif - - unsigned winding; /* which winding to cull */ -}; - - - -/** - * Execute fragment shader for the four fragments in the quad. - */ -static void -shade_quads(struct llvmpipe_context *llvmpipe, - struct quad_header *quads[], - unsigned nr) -{ - struct lp_fragment_shader *fs = llvmpipe->fs; - struct quad_header *quad = quads[0]; - const unsigned x = quad->input.x0; - const unsigned y = quad->input.y0; - uint8_t *tile; - uint8_t *color; - void *depth; - uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; - unsigned chan_index; - unsigned q; - - assert(fs->current); - if(!fs->current) - return; - - /* Sanity checks */ - assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH); - assert(x % TILE_VECTOR_WIDTH == 0); - assert(y % TILE_VECTOR_HEIGHT == 0); - for (q = 0; q < nr; ++q) { - assert(quads[q]->input.x0 == x + q*2); - assert(quads[q]->input.y0 == y); - } - - /* mask */ - for (q = 0; q < 4; ++q) - for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) - mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0; - - /* color buffer */ - if(llvmpipe->framebuffer.nr_cbufs >= 1 && - llvmpipe->framebuffer.cbufs[0]) { - tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y); - color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0); - } - else - color = NULL; - - /* depth buffer */ - if(llvmpipe->zsbuf_map) { - assert((x % 2) == 0); - assert((y % 2) == 0); - depth = llvmpipe->zsbuf_map + - y*llvmpipe->zsbuf_transfer->stride + - 2*x*llvmpipe->zsbuf_transfer->block.size; - } - else - depth = NULL; - - /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ - assert(lp_check_alignment(mask, 16)); - - assert(lp_check_alignment(depth, 16)); - assert(lp_check_alignment(color, 16)); - assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16)); - - /* run shader */ - fs->current->jit_function( &llvmpipe->jit_context, - x, y, - quad->coef->a0, - quad->coef->dadx, - quad->coef->dady, - &mask[0][0], - color, - depth); -} - - - - -/** - * Do triangle cull test using tri determinant (sign indicates orientation) - * \return true if triangle is to be culled. - */ -static INLINE boolean -cull_tri(const struct setup_context *setup, float det) -{ - if (det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - - if ((winding & setup->winding) == 0) - return FALSE; - } - - /* Culled: - */ - return TRUE; -} - - - -/** - * Clip setup->quad against the scissor/surface bounds. - */ -static INLINE void -quad_clip( struct setup_context *setup, struct quad_header *quad ) -{ - const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - - if (quad->input.x0 >= maxx || - quad->input.y0 >= maxy || - quad->input.x0 + 1 < minx || - quad->input.y0 + 1 < miny) { - /* totally clipped */ - quad->inout.mask = 0x0; - return; - } - if (quad->input.x0 < minx) - quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - if (quad->input.y0 < miny) - quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - if (quad->input.x0 == maxx - 1) - quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - if (quad->input.y0 == maxy - 1) - quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); -} - - - -/** - * Given an X or Y coordinate, return the block/quad coordinate that it - * belongs to. - */ -static INLINE int block( int x ) -{ - return x & ~(2-1); -} - -static INLINE int block_x( int x ) -{ - return x & ~(TILE_VECTOR_WIDTH - 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[nr_quads]; - struct quad_header *quad_ptrs[nr_quads]; - int x0 = block_x(quad->input.x0); - unsigned i; - - 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 - } -} - - -/** - * 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] */ -} - - -#if DEBUG_VERTS -static void print_vertex(const struct setup_context *setup, - const float (*v)[4]) -{ - int i; - debug_printf(" Vertex: (%p)\n", v); - for (i = 0; i < setup->quad[0].nr_attrs; i++) { - debug_printf(" %d: %f %f %f %f\n", i, - v[i][0], v[i][1], v[i][2], v[i][3]); - if (util_is_inf_or_nan(v[i][0])) { - debug_printf(" NaN!\n"); - } - } -} -#endif - -/** - * Sort the vertices from top to bottom order, setting up the triangle - * edge fields (ebot, emaj, etop). - * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise - */ -static boolean setup_sort_vertices( struct setup_context *setup, - float det, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) -{ - setup->vprovoke = v2; - - /* determine bottom to top order of vertices */ - { - float y0 = v0[0][1]; - float y1 = v1[0][1]; - float y2 = v2[0][1]; - if (y0 <= y1) { - if (y1 <= y2) { - /* y0<=y1<=y2 */ - setup->vmin = v0; - setup->vmid = v1; - setup->vmax = v2; - } - else if (y2 <= y0) { - /* y2<=y0<=y1 */ - setup->vmin = v2; - setup->vmid = v0; - setup->vmax = v1; - } - else { - /* y0<=y2<=y1 */ - setup->vmin = v0; - setup->vmid = v2; - setup->vmax = v1; - } - } - else { - if (y0 <= y2) { - /* y1<=y0<=y2 */ - setup->vmin = v1; - setup->vmid = v0; - setup->vmax = v2; - } - else if (y2 <= y1) { - /* y2<=y1<=y0 */ - setup->vmin = v2; - setup->vmid = v1; - setup->vmax = v0; - } - else { - /* y1<=y2<=y0 */ - setup->vmin = v1; - setup->vmid = v2; - setup->vmax = v0; - } - } - } - - setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; - setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; - setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; - setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; - setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; - setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; - - /* - * Compute triangle's area. Use 1/area to compute partial - * derivatives of attributes later. - * - * The area will be the same as prim->det, but the sign may be - * different depending on how the vertices get sorted above. - * - * To determine whether the primitive is front or back facing we - * use the prim->det value because its sign is correct. - */ - { - const float area = (setup->emaj.dx * setup->ebot.dy - - setup->ebot.dx * setup->emaj.dy); - - setup->oneoverarea = 1.0f / area; - - /* - debug_printf("%s one-over-area %f area %f det %f\n", - __FUNCTION__, setup->oneoverarea, area, det ); - */ - if (util_is_inf_or_nan(setup->oneoverarea)) - return FALSE; - } - - /* We need to know if this is a front or back-facing triangle for: - * - the GLSL gl_FrontFacing fragment attribute (bool) - * - two-sided stencil test - */ - setup->facing = - ((det > 0.0) ^ - (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW)); - - return TRUE; -} - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a triangle. - */ -static void tri_pos_coeff( struct setup_context *setup, - uint vertSlot, unsigned i) -{ - float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; - float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - assert(i <= 3); - - setup->coef.dadx[0][i] = dadx; - setup->coef.dady[0][i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (0.5, 0.5). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ -} - - -/** - * Compute a0 for a constant-valued coefficient (GL_FLAT shading). - * The value value comes from vertex[slot][i]. - * The result will be put into setup->coef[slot].a0[i]. - * \param slot which attribute slot - * \param i which component of the slot (0..3) - */ -static void const_pos_coeff( struct setup_context *setup, - uint vertSlot, unsigned i) -{ - setup->coef.dadx[0][i] = 0; - setup->coef.dady[0][i] = 0; - - /* need provoking vertex info! - */ - setup->coef.a0[0][i] = setup->vprovoke[vertSlot][i]; -} - - -/** - * Compute a0 for a constant-valued coefficient (GL_FLAT shading). - * The value value comes from vertex[slot][i]. - * The result will be put into setup->coef[slot].a0[i]. - * \param slot which attribute slot - * \param i which component of the slot (0..3) - */ -static void const_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - setup->coef.dadx[1 + attrib][i] = 0; - setup->coef.dady[1 + attrib][i] = 0; - - /* need provoking vertex info! - */ - setup->coef.a0[1 + attrib][i] = setup->vprovoke[vertSlot][i]; - } -} - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a triangle. - */ -static void tri_linear_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; - float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - assert(i <= 3); - - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (0.5, 0.5). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ - } -} - - -/** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a triangle. - * We basically multiply the vertex value by 1/w before computing - * the plane coefficients (a0, dadx, dady). - * Later, when we compute the value at a particular fragment position we'll - * divide the interpolated value by the interpolated W at that fragment. - */ -static void tri_persp_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - /* premultiply by 1/w (v[0][3] is always W): - */ - float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; - float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; - float botda = mida - mina; - float majda = maxa - mina; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - /* - debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, - setup->vmin[vertSlot][i], - setup->vmid[vertSlot][i], - setup->vmax[vertSlot][i] - ); - */ - assert(i <= 3); - - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (mina - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); - } -} - - -/** - * Special coefficient setup for gl_FragCoord. - * X and Y are trivial, though Y has to be inverted for OpenGL. - * Z and W are copied from posCoef which should have already been computed. - * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. - */ -static void -setup_fragcoord_coeff(struct setup_context *setup, uint slot) -{ - /*X*/ - setup->coef.a0[1 + slot][0] = 0; - setup->coef.dadx[1 + slot][0] = 1.0; - setup->coef.dady[1 + slot][0] = 0.0; - /*Y*/ - setup->coef.a0[1 + slot][1] = 0.0; - setup->coef.dadx[1 + slot][1] = 0.0; - setup->coef.dady[1 + slot][1] = 1.0; - /*Z*/ - setup->coef.a0[1 + slot][2] = setup->coef.a0[0][2]; - setup->coef.dadx[1 + slot][2] = setup->coef.dadx[0][2]; - setup->coef.dady[1 + slot][2] = setup->coef.dady[0][2]; - /*W*/ - setup->coef.a0[1 + slot][3] = setup->coef.a0[0][3]; - setup->coef.dadx[1 + slot][3] = setup->coef.dadx[0][3]; - setup->coef.dady[1 + slot][3] = setup->coef.dady[0][3]; -} - - - -/** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. - */ -static void setup_tri_coefficients( struct setup_context *setup ) -{ - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; - - /* z and w are done by linear interpolation: - */ - tri_pos_coeff(setup, 0, 2); - tri_pos_coeff(setup, 0, 3); - - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; - - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_LINEAR: - tri_linear_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - tri_persp_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } - } -} - - - -static void setup_tri_edges( struct setup_context *setup ) -{ - float vmin_x = setup->vmin[0][0] + 0.5f; - float vmid_x = setup->vmid[0][0] + 0.5f; - - float vmin_y = setup->vmin[0][1] - 0.5f; - float vmid_y = setup->vmid[0][1] - 0.5f; - float vmax_y = setup->vmax[0][1] - 0.5f; - - setup->emaj.sy = ceilf(vmin_y); - setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); - setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; - setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; - - setup->etop.sy = ceilf(vmid_y); - setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); - setup->etop.dxdy = setup->etop.dx / setup->etop.dy; - setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; - - setup->ebot.sy = ceilf(vmin_y); - setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); - setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; - setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; -} - - -/** - * Render the upper or lower half of a triangle. - * Scissoring/cliprect is applied here too. - */ -static void subtriangle( struct setup_context *setup, - struct edge *eleft, - struct edge *eright, - unsigned lines ) -{ - const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - int y, start_y, finish_y; - int sy = (int)eleft->sy; - - assert((int)eleft->sy == (int) eright->sy); - - /* clip top/bottom */ - start_y = sy; - if (start_y < miny) - start_y = miny; - - finish_y = sy + lines; - if (finish_y > maxy) - finish_y = maxy; - - start_y -= sy; - finish_y -= sy; - - /* - debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); - */ - - for (y = start_y; y < finish_y; y++) { - - /* avoid accumulating adds as floats don't have the precision to - * accurately iterate large triangle edges that way. luckily we - * can just multiply these days. - * - * this is all drowned out by the attribute interpolation anyway. - */ - int left = (int)(eleft->sx + y * eleft->dxdy); - int right = (int)(eright->sx + y * eright->dxdy); - - /* clip left/right */ - if (left < minx) - left = minx; - if (right > maxx) - right = maxx; - - if (left < right) { - int _y = sy + y; - if (block(_y) != setup->span.y) { - flush_spans(setup); - setup->span.y = block(_y); - } - - setup->span.left[_y&1] = left; - setup->span.right[_y&1] = right; - } - } - - - /* save the values so that emaj can be restarted: - */ - eleft->sx += lines * eleft->dxdy; - eright->sx += lines * eright->dxdy; - eleft->sy += lines; - eright->sy += lines; -} - - -/** - * Recalculate prim's determinant. This is needed as we don't have - * get this information through the vbuf_render interface & we must - * calculate it here. - */ -static float -calc_det( const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) -{ - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0][0] - v2[0][0]; - const float ey = v0[0][1] - v2[0][1]; - const float fx = v1[0][0] - v2[0][0]; - const float fy = v1[0][1] - v2[0][1]; - - /* det = cross(e,f).z */ - return ex * fy - ey * fx; -} - - -/** - * Do setup for triangle rasterization, then render the triangle. - */ -void llvmpipe_setup_tri( struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) -{ - float det; - -#if DEBUG_VERTS - debug_printf("Setup triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif - - if (setup->llvmpipe->no_rast) - return; - - det = calc_det(v0, v1, v2); - /* - debug_printf("%s\n", __FUNCTION__ ); - */ - -#if DEBUG_FRAGS - setup->numFragsEmitted = 0; - setup->numFragsWritten = 0; -#endif - - if (cull_tri( setup, det )) - return; - - if (!setup_sort_vertices( setup, det, v0, v1, v2 )) - return; - setup_tri_coefficients( setup ); - setup_tri_edges( setup ); - - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_TRIANGLES); - - setup->span.y = 0; - setup->span.right[0] = 0; - setup->span.right[1] = 0; - /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ - - /* init_constant_attribs( setup ); */ - - if (setup->oneoverarea < 0.0) { - /* emaj on left: - */ - subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); - subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); - } - else { - /* emaj on right: - */ - subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); - subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); - } - - flush_spans( setup ); - -#if DEBUG_FRAGS - printf("Tri: %u frags emitted, %u written\n", - setup->numFragsEmitted, - setup->numFragsWritten); -#endif -} - - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a line. - */ -static void -linear_pos_coeff(struct setup_context *setup, - uint vertSlot, uint i) -{ - const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[0][i] = dadx; - setup->coef.dady[0][i] = dady; - setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); -} - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a line. - */ -static void -line_linear_coeff(struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); - } -} - - -/** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a line. - */ -static void -line_persp_coeff(struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - /* XXX double-check/verify this arithmetic */ - const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; - const float da = a1 - a0; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - 0.5f) + - dady * (setup->vmin[0][1] - 0.5f))); - } -} - - -/** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmax are initialized. - */ -static INLINE boolean -setup_line_coefficients(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) -{ - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; - float area; - - /* use setup->vmin, vmax to point to vertices */ - if (llvmpipe->rasterizer->flatshade_first) - setup->vprovoke = v0; - else - setup->vprovoke = v1; - setup->vmin = v0; - setup->vmax = v1; - - setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; - setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; - - /* NOTE: this is not really area but something proportional to it */ - area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; - if (area == 0.0f || util_is_inf_or_nan(area)) - return FALSE; - setup->oneoverarea = 1.0f / area; - - /* z and w are done by linear interpolation: - */ - linear_pos_coeff(setup, 0, 2); - linear_pos_coeff(setup, 0, 3); - - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; - - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_LINEAR: - line_linear_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - line_persp_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } - } - return TRUE; -} - - -/** - * Plot a pixel in a line segment. +/* Stubs for lines & points for now: */ -static INLINE void -plot(struct setup_context *setup, int x, int y) +void +llvmpipe_setup_point(struct setup_context *setup, + const float (*v0)[4]) { - const int iy = y & 1; - const int ix = x & 1; - const int quadX = x - ix; - const int quadY = y - iy; - const int mask = (1 << ix) << (2 * iy); - - if (quadX != setup->quad[0].input.x0 || - quadY != setup->quad[0].input.y0) - { - /* flush prev quad, start new quad */ - - if (setup->quad[0].input.x0 != -1) - clip_emit_quad( setup, &setup->quad[0] ); - - setup->quad[0].input.x0 = quadX; - setup->quad[0].input.y0 = quadY; - setup->quad[0].inout.mask = 0x0; - } - - setup->quad[0].inout.mask |= mask; } - -/** - * Do setup for line rasterization, then render the line. - * Single-pixel width, no stipple, etc. We rely on the 'draw' module - * to handle stippling and wide lines. - */ void llvmpipe_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) -{ - int x0 = (int) v0[0][0]; - int x1 = (int) v1[0][0]; - int y0 = (int) v0[0][1]; - int y1 = (int) v1[0][1]; - int dx = x1 - x0; - int dy = y1 - y0; - int xstep, ystep; - -#if DEBUG_VERTS - debug_printf("Setup line:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); -#endif - - if (setup->llvmpipe->no_rast) - return; - - if (dx == 0 && dy == 0) - return; - - if (!setup_line_coefficients(setup, v0, v1)) - return; - - assert(v0[0][0] < 1.0e9); - assert(v0[0][1] < 1.0e9); - assert(v1[0][0] < 1.0e9); - assert(v1[0][1] < 1.0e9); - - if (dx < 0) { - dx = -dx; /* make positive */ - xstep = -1; - } - else { - xstep = 1; - } - - if (dy < 0) { - dy = -dy; /* make positive */ - ystep = -1; - } - else { - ystep = 1; - } - - assert(dx >= 0); - assert(dy >= 0); - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_LINES); - - setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; - setup->quad[0].inout.mask = 0x0; - - /* XXX temporary: set coverage to 1.0 so the line appears - * if AA mode happens to be enabled. - */ - setup->quad[0].input.coverage[0] = - setup->quad[0].input.coverage[1] = - setup->quad[0].input.coverage[2] = - setup->quad[0].input.coverage[3] = 1.0; - - if (dx > dy) { - /*** X-major line ***/ - int i; - const int errorInc = dy + dy; - int error = errorInc - dx; - const int errorDec = error - dx; - - for (i = 0; i < dx; i++) { - plot(setup, x0, y0); - - x0 += xstep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - y0 += ystep; - } - } - } - else { - /*** Y-major line ***/ - int i; - const int errorInc = dx + dx; - int error = errorInc - dy; - const int errorDec = error - dy; - - for (i = 0; i < dy; i++) { - plot(setup, x0, y0); - - y0 += ystep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - x0 += xstep; - } - } - } - - /* draw final quad */ - if (setup->quad[0].inout.mask) { - clip_emit_quad( setup, &setup->quad[0] ); - } -} - - -static void -point_persp_coeff(struct setup_context *setup, - const float (*vert)[4], - unsigned attrib, - uint vertSlot) + const float (*v0)[4], + const float (*v1)[4]) { - unsigned i; - for(i = 0; i < NUM_CHANNELS; ++i) { - setup->coef.dadx[1 + attrib][i] = 0.0F; - setup->coef.dady[1 + attrib][i] = 0.0F; - setup->coef.a0[1 + attrib][i] = vert[vertSlot][i] * vert[0][3]; - } } -/** - * Do setup for point rasterization, then render the point. - * Round or square points... - * XXX could optimize a lot for 1-pixel points. +/* Called after statechange, before emitting primitives. If binning + * is active, this function should store relevant state in the binning + * context. + * + * That includes: + * - current fragment shader function + * - bound constant buffer contents + * - bound textures + * - blend color + * - etc. + * + * Basically everything needed at some point in the future to + * rasterize triangles for the current state. + * + * Additionally this will set up the state needed for the rasterizer + * to process and bin incoming triangles. That would include such + * things as: + * - cull mode + * - ??? + * - etc. + * */ -void -llvmpipe_setup_point( struct setup_context *setup, - const float (*v0)[4] ) -{ - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const int sizeAttr = setup->llvmpipe->psize_slot; - const float size - = sizeAttr > 0 ? v0[sizeAttr][0] - : setup->llvmpipe->rasterizer->point_size; - const float halfSize = 0.5F * size; - const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; - const float x = v0[0][0]; /* Note: data[0] is always position */ - const float y = v0[0][1]; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; - -#if DEBUG_VERTS - debug_printf("Setup point:\n"); - print_vertex(setup, v0); -#endif - - if (llvmpipe->no_rast) - return; - - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_POINTS); - - /* For points, all interpolants are constant-valued. - * However, for point sprites, we'll need to setup texcoords appropriately. - * XXX: which coefficients are the texcoords??? - * We may do point sprites as textured quads... - * - * KW: We don't know which coefficients are texcoords - ultimately - * the choice of what interpolation mode to use for each attribute - * should be determined by the fragment program, using - * per-attribute declaration statements that include interpolation - * mode as a parameter. So either the fragment program will have - * to be adjusted for pointsprite vs normal point behaviour, or - * otherwise a special interpolation mode will have to be defined - * which matches the required behaviour for point sprites. But - - * the latter is not a feature of normal hardware, and as such - * probably should be ruled out on that basis. - */ - setup->vprovoke = v0; - - /* setup Z, W */ - const_pos_coeff(setup, 0, 2); - const_pos_coeff(setup, 0, 3); - - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; - - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - /* fall-through */ - case INTERP_LINEAR: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - point_persp_coeff(setup, setup->vprovoke, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } - } - - - if (halfSize <= 0.5 && !round) { - /* special case for 1-pixel points */ - const int ix = ((int) x) & 1; - const int iy = ((int) y) & 1; - setup->quad[0].input.x0 = (int) x - ix; - setup->quad[0].input.y0 = (int) y - iy; - setup->quad[0].inout.mask = (1 << ix) << (2 * iy); - clip_emit_quad( setup, &setup->quad[0] ); - } - else { - if (round) { - /* rounded points */ - const int ixmin = block((int) (x - halfSize)); - const int ixmax = block((int) (x + halfSize)); - const int iymin = block((int) (y - halfSize)); - const int iymax = block((int) (y + halfSize)); - const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - const float rmax = halfSize + 0.7071F; - const float rmin2 = MAX2(0.0F, rmin * rmin); - const float rmax2 = rmax * rmax; - const float cscale = 1.0F / (rmax2 - rmin2); - int ix, iy; - - for (iy = iymin; iy <= iymax; iy += 2) { - for (ix = ixmin; ix <= ixmax; ix += 2) { - float dx, dy, dist2, cover; - - setup->quad[0].inout.mask = 0x0; - - dx = (ix + 0.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_TOP_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_TOP_RIGHT; - } - - dx = (ix + 0.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; - } - - if (setup->quad[0].inout.mask) { - setup->quad[0].input.x0 = ix; - setup->quad[0].input.y0 = iy; - clip_emit_quad( setup, &setup->quad[0] ); - } - } - } - } - else { - /* square points */ - const int xmin = (int) (x + 0.75 - halfSize); - const int ymin = (int) (y + 0.25 - halfSize); - const int xmax = xmin + (int) size; - const int ymax = ymin + (int) size; - /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ - const int ixmin = block(xmin); - const int ixmax = block(xmax - 1); - const int iymin = block(ymin); - const int iymax = block(ymax - 1); - int ix, iy; - - /* - debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); - */ - for (iy = iymin; iy <= iymax; iy += 2) { - uint rowMask = 0xf; - if (iy < ymin) { - /* above the top edge */ - rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - } - if (iy + 1 >= ymax) { - /* below the bottom edge */ - rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); - } - - for (ix = ixmin; ix <= ixmax; ix += 2) { - uint mask = rowMask; - - if (ix < xmin) { - /* fragment is past left edge of point, turn off left bits */ - mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - } - if (ix + 1 >= xmax) { - /* past the right edge */ - mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - } - - setup->quad[0].inout.mask = mask; - setup->quad[0].input.x0 = ix; - setup->quad[0].input.y0 = iy; - clip_emit_quad( setup, &setup->quad[0] ); - } - } - } - } -} - -void llvmpipe_setup_prepare( struct setup_context *setup ) +void setup_prepare( struct setup_context *setup ) { struct llvmpipe_context *lp = setup->llvmpipe; @@ -1442,6 +94,8 @@ void llvmpipe_setup_prepare( struct setup_context *setup ) llvmpipe_update_derived(lp); } + lp->quad.first->begin( lp->quad.first ); + if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { @@ -1452,38 +106,28 @@ void llvmpipe_setup_prepare( struct setup_context *setup ) /* 'draw' will do culling */ setup->winding = PIPE_WINDING_NONE; } + + setup_prepare_tri( setup->llvmpipe ); } -void llvmpipe_setup_destroy_context( struct setup_context *setup ) +void setup_destroy_context( struct setup_context *setup ) { - align_free( setup ); + FREE( setup ); } /** * Create a new primitive setup/render stage. */ -struct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe ) +struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ) { - struct setup_context *setup; + struct setup_context *setup = CALLOC_STRUCT(setup_context); unsigned i; - setup = align_malloc(sizeof(struct setup_context), 16); - if (!setup) - return NULL; - - memset(setup, 0, sizeof *setup); setup->llvmpipe = llvmpipe; - for (i = 0; i < MAX_QUADS; i++) { - setup->quad[i].coef = &setup->coef; - } - - setup->span.left[0] = 1000000; /* greater than right[0] */ - setup->span.left[1] = 1000000; /* greater than right[1] */ - return setup; } -- cgit v1.2.3 From e529170c11d3cb5812aabeff0a6ee2d7a2ea66f2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 11:47:33 +0100 Subject: llvmpipe: more wipping --- src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 2 +- src/gallium/drivers/llvmpipe/lp_rast.c | 119 ++++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 129 ++++++++ src/gallium/drivers/llvmpipe/lp_rast_priv.h | 31 ++ src/gallium/drivers/llvmpipe/lp_rast_tri.c | 348 ++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rasterizer.c | 157 ---------- src/gallium/drivers/llvmpipe/lp_rasterizer.h | 112 ------- src/gallium/drivers/llvmpipe/lp_setup.c | 17 ++ src/gallium/drivers/llvmpipe/lp_setup_rasterize.c | 19 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 6 +- src/gallium/drivers/llvmpipe/lp_state_derived.c | 27 ++ 11 files changed, 691 insertions(+), 276 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_rast.c create mode 100644 src/gallium/drivers/llvmpipe/lp_rast.h create mode 100644 src/gallium/drivers/llvmpipe/lp_rast_priv.h create mode 100644 src/gallium/drivers/llvmpipe/lp_rast_tri.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_rasterizer.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_rasterizer.h (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c index e244ac9087..8cccb2905b 100644 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c @@ -138,7 +138,7 @@ lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); struct setup_context *setup_ctx = cvbr->setup; - llvmpipe_setup_prepare( setup_ctx ); + llvmpipe_update_state( setup_ctx->llvmpipe ); cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim); cvbr->prim = prim; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c new file mode 100644 index 0000000000..4771f821b3 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -0,0 +1,119 @@ + +struct lp_rasterizer *lp_rast_create( void ) +{ + return CALLOC_STRUCT(lp_rasterizer); +} + +void lp_rast_bind_surfaces( struct lp_rasterizer *, + struct pipe_surface *color, + struct pipe_surface *zstencil, + const float *clear_color, + double clear_depth, + unsigned clear_stencil) +{ + pipe_surface_reference(&rast->state.color, color); + pipe_surface_reference(&rast->state.depth, depth); + rast->state.clear_color = util_pack_8888(clear_color); + rast->state.clear_depth = clear_depth * 0xffffffff; + rast->state.clear_stencil = clear_stencil; +} + +/* Begining of each tile: + */ +void lp_rast_start_tile( struct lp_rasterizer *, + unsigned x, + unsigned y ) +{ + rast->x = x; + rast->y = y; +} + +void lp_rast_clear_color( struct lp_rasterizer *rast ) +{ + const unsigned clear_color = rast->state.clear_color; + unsigned i, j; + + for (i = 0; i < TILESIZE; i++) + for (j = 0; j < TILESIZE; j++) + rast->tile[i][j] = clear_color; +} + +void lp_rast_clear_depth( struct lp_rasterizer *rast ) +{ + const unsigned clear_depth = rast->state.clear_depth; + unsigned i, j; + + for (i = 0; i < TILESIZE; i++) + for (j = 0; j < TILESIZE; j++) + rast->tile[i][j] = clear_depth; +} + +void lp_rast_clear_stencil( struct lp_rasterizer *rast ) +{ + const unsigned clear_stencil = rast->state.clear_stencil; + + memset(rast->tile.stencil, clear_stencil, sizeof rast->tile.stencil ); +} + +void lp_rast_load_color( struct lp_rasterizer *rast ) +{ + /* call u_tile func to load colors from surface */ +} + +void lp_rast_load_zstencil( struct lp_rasterizer *rast ) +{ + /* call u_tile func to load depth (and stencil?) from surface */ +} + +/* Within a tile: + */ +void lp_rast_set_state( struct lp_rasterizer *rast, + const struct lp_rast_state *state ) +{ + rast->shader_state = state; + lp->quad.first->begin( lp->quad.first ); + +} + + +void lp_rast_shade_tile( struct lp_rasterizer *rast, + const struct lp_rast_shader_inputs *inputs ) +{ + /* Set up the silly quad coef pointers + */ + for (i = 0; i < 4; i++) { + rast->quads[i].posCoef = &inputs->posCoef; + rast->quads[i].coef = inputs->coef; + } + + /* Use the existing preference for 8x2 (four quads) shading: + */ + for (i = 0; i < TILESIZE; i += 8) { + for (j = 0; j < TILESIZE; j += 2) { + rast->shader_state.shade( inputs->jc, + rast->x + i, + rast->y + j, + rast->quads, 4 ); + } + } +} + +/* End of tile: + */ +void lp_rast_store_color( struct lp_rasterizer *rast ) +{ + /* call u_tile func to store colors to surface */ +} + +void lp_rast_store_zstencil( struct lp_rasterizer *rast ) +{ + /* call u_tile func to store depth/stencil to surface */ +} + +/* Shutdown: + */ +void lp_rast_destroy( struct lp_rasterizer *rast ) +{ + FREE(rast); +} + diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h new file mode 100644 index 0000000000..8f4bd52c9e --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -0,0 +1,129 @@ + +#ifndef LP_RAST_H +#define LP_RAST_H + +/* Initially create and program a single rasterizer directly. Later + * will want multiple of these, one or two per core. At that stage + * will probably pass command buffers into the rasterizers rather than + * individual function calls like this. + */ +struct lp_rasterizer; + +struct lp_rast_state { + /* State for the shader: + */ + struct lp_jit_context jc; + + /* The shader itself. Probably we also need to pass a pointer to + * the tile color/z/stencil data somehow: + */ + void (*run)( struct lp_jit_context *jc, + struct quad_header **quads, + unsigned nr ); +}; + +/* Coefficients necessary to run the shader at a given location: + */ +struct lp_rast_shader_inputs { + + /* Current rasterizer state: + */ + const struct lp_rast_state *state; + + /* Attribute interpolation: + */ + struct tgsi_interp_coef position_coef; + struct tgsi_interp_coef *coef; +}; + + +/* Rasterization information for a triangle known to be in this bin, + * plus inputs to run the shader: + */ +struct lp_rast_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; + + /* State to run the shader: */ + struct lp_rast_shader_inputs inputs; +}; + + + +struct lp_rasterizer *lp_rast_create( void ); + +void lp_rast_bind_surfaces( struct lp_rasterizer *, + struct pipe_surface *color, + struct pipe_surface *zstencil, + const float *clear_color, + double clear_depth, + unsigned clear_stencil); + +/* Begining of each tile: + */ +void lp_rast_start_tile( struct lp_rasterizer *, + unsigned x, + unsigned y ); + + + +union lp_rast_cmd_arg { + const struct lp_rast_shader_inputs *shade_tile; + const struct lp_rast_triangle *triangle; + const struct lp_rast_state *set_state; +}; + + +/* Binnable Commands: + */ +void lp_rast_clear_color( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + +void lp_rast_clear_zstencil( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + +void lp_rast_load_color( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + +void lp_rast_load_zstencil( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + +void lp_rast_set_state( struct lp_rasterizer *, + const union lp_rast_cmd_arg * ); + +void lp_rast_triangle( struct lp_rasterizer *, + const union lp_rast_cmd_arg * ); + +void lp_rast_shade_tile( struct lp_rasterizer *, + const union lp_rast_cmd_arg * ); + +void lp_rast_store_color( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + +void lp_rast_store_zstencil( struct lp_rasterizer *, + const union lp_rast_cmd_arg *); + + +/* Shutdown: + */ +void lp_rast_destroy( struct lp_rasterizer * ); + + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h new file mode 100644 index 0000000000..538ec22551 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -0,0 +1,31 @@ +#ifndef LP_RAST_PRIV_H +#define LP_RAST_PRIV_H + +#include "lp_rast.h" + +struct lp_rasterizer { + + /* We can choose whatever layout for the internal tile storage we + * prefer: + */ + struct { + unsigned color[TILESIZE][TILESIZE]; + unsigned depth[TILESIZE][TILESIZE]; + char stencil[TILESIZE][TILESIZE]; + } tile; + + + unsigned x; + unsigned y; + + + struct { + struct pipe_surface *color; + struct pipe_surface *zstencil; + unsigned clear_color; + unsigned clear_depth; + char clear_stencil; + } state; +}; + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c new file mode 100644 index 0000000000..4b7b3719de --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -0,0 +1,348 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Rasterization for binned triangles within a tile + */ + +#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" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_thread.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#define BLOCKSIZE 4 + + +/* 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 ); + } +} +#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 + 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 ); + } +} +#endif + +static void +do_quad( struct lp_rasterizer *rast, + int x, int y, + float c1, float c2, float c3 ) +{ + struct triangle *tri = rast->tri; + struct quad_header *quad = &rast->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) + rast->state->run( rast->state->state, &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; + } +} + + + +/* Scan the tile in chunks and figure out which pixels to rasterize + * for this triangle: + */ +void lp_rast_triangle( struct lp_rasterizer *rast, + const struct lp_rast_triangle *tri ) +{ + int minx, maxx, miny, maxy; + + /* Clamp to tile dimensions: + */ + minx = MAX2(tri->maxx, rast->x); + miny = MAX2(tri->miny, rast->y); + maxx = MIN2(tri->maxx, rast->x + TILESIZE); + maxy = MIN2(tri->maxy, rast->y + TILESIZE); + + if (miny == maxy || + minx == maxx) { + debug_printf("%s: non-intersecting triangle in bin\n", __FUNCTION__); + //assert(0); + return; + } + + /* Bind parameter interpolants: + */ + for (i = 0; i < Elements(rast->quad); i++) { + rast->quad[i].coef = tri->coef; + rast->quad[i].posCoef = &tri->position_coef; + } + + /* Small area? + */ + if (miny + 16 > maxy && + minx + 16 > 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; + + minx &= ~(step-1); + maxx &= ~(step-1); + + /* 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. + */ + 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; + + float ei1 = tri->ei1 * step; + float ei2 = tri->ei2 * step; + float ei3 = tri->ei3 * step; + + float eo1 = tri->eo1 * step; + float eo2 = tri->eo2 * step; + float eo3 = tri->eo3 * step; + + 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 x, y; + + minx &= ~(step-1); + miny &= ~(step-1); + + 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 if (cx1 + ei1 > 0 && + cx2 + ei2 > 0 && + cx3 + ei3 > 0) + { + block_full(&tri, x, y); /* trivial accept */ + } + else + { + do_block(&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; + } + } +} + diff --git a/src/gallium/drivers/llvmpipe/lp_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_rasterizer.c deleted file mode 100644 index 089ea59729..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_rasterizer.c +++ /dev/null @@ -1,157 +0,0 @@ - -struct lp_rasterizer { - - /* We can choose whatever layout for the internal tile storage we - * prefer: - */ - struct { - unsigned color[TILESIZE][TILESIZE]; - unsigned depth[TILESIZE][TILESIZE]; - char stencil[TILESIZE][TILESIZE]; - } tile; - - - unsigned x; - unsigned y; - - - struct { - struct pipe_surface *color; - struct pipe_surface *zstencil; - unsigned clear_color; - unsigned clear_depth; - char clear_stencil; - } state; -}; - -struct lp_rasterizer *lp_rast_create( void ) -{ - return CALLOC_STRUCT(lp_rasterizer); -} - -void lp_rast_bind_surfaces( struct lp_rasterizer *, - struct pipe_surface *color, - struct pipe_surface *zstencil, - const float *clear_color, - double clear_depth, - unsigned clear_stencil) -{ - pipe_surface_reference(&rast->state.color, color); - pipe_surface_reference(&rast->state.depth, depth); - rast->state.clear_color = util_pack_8888(clear_color); - rast->state.clear_depth = clear_depth * 0xffffffff; - rast->state.clear_stencil = clear_stencil; -} - -/* Begining of each tile: - */ -void lp_rast_start_tile( struct lp_rasterizer *, - unsigned x, - unsigned y ) -{ - rast->x = x; - rast->y = y; -} - -void lp_rast_clear_color( struct lp_rasterizer *rast ) -{ - const unsigned clear_color = rast->state.clear_color; - unsigned i, j; - - for (i = 0; i < TILESIZE; i++) - for (j = 0; j < TILESIZE; j++) - rast->tile[i][j] = clear_color; -} - -void lp_rast_clear_depth( struct lp_rasterizer *rast ) -{ - const unsigned clear_depth = rast->state.clear_depth; - unsigned i, j; - - for (i = 0; i < TILESIZE; i++) - for (j = 0; j < TILESIZE; j++) - rast->tile[i][j] = clear_depth; -} - -void lp_rast_clear_stencil( struct lp_rasterizer *rast ) -{ - const unsigned clear_stencil = rast->state.clear_stencil; - - memset(rast->tile.stencil, clear_stencil, sizeof rast->tile.stencil ); -} - -void lp_rast_load_color( struct lp_rasterizer *rast ) -{ - /* call u_tile func to load colors from surface */ -} - -void lp_rast_load_zstencil( struct lp_rasterizer *rast ) -{ - /* call u_tile func to load depth (and stencil?) from surface */ -} - -/* Within a tile: - */ -void lp_rast_set_state( struct lp_rasterizer *rast, - const struct lp_rast_state *state ) -{ - rast->shader_state = state; -} - -void lp_rast_triangle( struct lp_rasterizer *rast, - const struct lp_rast_triangle *inputs ) -{ - /* Set up the silly quad coef pointers - */ - for (i = 0; i < 4; i++) { - rast->quads[i].posCoef = inputs->posCoef; - rast->quads[i].coef = inputs->coef; - } - - /* Scan the tile in 4x4 chunks (?) and figure out which bits to - * rasterize: - */ - -} - -void lp_rast_shade_tile( struct lp_rasterizer *rast, - const struct lp_rast_shader_inputs *inputs ) -{ - /* Set up the silly quad coef pointers - */ - for (i = 0; i < 4; i++) { - rast->quads[i].posCoef = inputs->posCoef; - rast->quads[i].coef = inputs->coef; - } - - /* Use the existing preference for 8x2 (four quads) shading: - */ - for (i = 0; i < TILESIZE; i += 8) { - for (j = 0; j < TILESIZE; j += 2) { - rast->shader_state.shade( inputs->jc, - rast->x + i, - rast->y + j, - rast->quads, 4 ); - } - } -} - -/* End of tile: - */ -void lp_rast_store_color( struct lp_rasterizer *rast ) -{ - /* call u_tile func to store colors to surface */ -} - -void lp_rast_store_zstencil( struct lp_rasterizer *rast ) -{ - /* call u_tile func to store depth/stencil to surface */ -} - -/* Shutdown: - */ -void lp_rast_destroy( struct lp_rasterizer *rast ) -{ - FREE(rast); -} - diff --git a/src/gallium/drivers/llvmpipe/lp_rasterizer.h b/src/gallium/drivers/llvmpipe/lp_rasterizer.h deleted file mode 100644 index b3ae06a116..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_rasterizer.h +++ /dev/null @@ -1,112 +0,0 @@ - -/* Initially create and program a single rasterizer directly. Later - * will want multiple of these, one or two per core. At that stage - * will probably pass command buffers into the rasterizers rather than - * individual function calls like this. - */ -struct lp_rasterizer; - -struct lp_rast_state { - /* State: - */ - struct lp_jit_context jc; - - /* Shader itself: - */ -}; - -/* Coefficients necessary to run the shader at a given location: - */ -struct lp_rast_shader_inputs { - - /* Current rasterizer state: - */ - const struct lp_rast_state *state; - - /* Attribute interpolation: - */ - float oneoverarea; - float x1; - float y1; - - struct tgsi_interp_coef position_coef; - struct tgsi_interp_coef *coef; -}; - - -/* Rasterization information for a triangle known to be in this bin, - * plus inputs to run the shader: - */ -struct lp_rast_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; - - /* State to run the shader: */ - struct lp_rast_shader_inputs inputs; -}; - - - -struct lp_rasterizer *lp_rast_create( void ); - -void lp_rast_bind_surfaces( struct lp_rasterizer *, - struct pipe_surface *color, - struct pipe_surface *zstencil, - const float *clear_color, - double clear_depth, - unsigned clear_stencil); - -/* Begining of each tile: - */ -void lp_rast_start_tile( struct lp_rasterizer *, - unsigned x, - unsigned y ); - -void lp_rast_clear_color( struct lp_rasterizer * ); - -void lp_rast_clear_zstencil( struct lp_rasterizer * ); - -void lp_rast_load_color( struct lp_rasterizer * ); - -void lp_rast_load_zstencil( struct lp_rasterizer * ); - - -/* Within a tile: - */ -void lp_rast_set_state( struct lp_rasterizer *, - const struct lp_rast_state * ); - -void lp_rast_triangle( struct lp_rasterizer *, - const struct lp_rast_triangle * ); - -void lp_rast_shade_tile( struct lp_rasterizer *, - const struct lp_rast_shader_inputs * ); - -/* End of tile: - */ -void lp_rast_store_color( struct lp_rasterizer * ); - -void lp_rast_store_zstencil( struct lp_rasterizer * ); - - -/* Shutdown: - */ -void lp_rast_destroy( struct lp_rasterizer * ); - diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 8c67524506..d6e51888b9 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -48,6 +48,23 @@ #define DEBUG_VERTS 0 + +void +llvmpipe_setup_flush() +{ +} + +void +llvmpipe_setup_bind_framebuffer() +{ +} + +void +llvmpipe_setup_clear() +{ +} + + /* Stubs for lines & points for now: */ void diff --git a/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c b/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c index 5b4faf489b..bb7a4feb39 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c @@ -1,7 +1,20 @@ void -rasterize( struct llvmpipe_context *llvmpipe, - struct binned_scene *scene ) +lp_setup_rasterize( struct llvmpipe_context *llvmpipe, + struct binned_scene *scene ) { - + lp_rast_bind_surfaces( rast, scene->framebuffer ); + + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + + lp_rast_start_tile( rast, i * TILESIZE, j * TILESIZE ); + + for (block = scene->tile[i][j].first; block; block = block->next) { + for (k = 0; k < block->nr_cmds; k++) { + block->cmd[k].func( rast, block->cmd[k].arg ); + } + } + } + } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index a09e0fa643..d43db7b123 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -728,9 +728,9 @@ static void triangle_nop( struct llvmpipe_context *llvmpipe, { } -/** - * Do setup for triangle rasterization, then render the triangle. - */ + + + void setup_prepare_tri( struct llvmpipe_context *llvmpipe ) { llvmpipe->ccw_is_frontface = (llvmpipe->rasterizer->front_winding == diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 31eaadda21..fcd31136b7 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -232,6 +232,22 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe ) llvmpipe->jit_context.samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list; } +static void +update_culling() +{ + if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && + lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && + lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { + /* we'll do culling */ + setup->winding = lp->rasterizer->cull_mode; + } + else { + /* 'draw' will do culling */ + setup->winding = PIPE_WINDING_NONE; + } +} + + /* Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ @@ -270,3 +286,14 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) llvmpipe->dirty = 0; } + + +void llvmpipe_prepare( ) +{ + struct llvmpipe_context *lp = setup->llvmpipe; + + if (lp->dirty) { + llvmpipe_update_derived(lp); + } + +} -- cgit v1.2.3 From d614ced756f2cca64ec83b122da4cd028c08c0eb Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 12:51:46 +0100 Subject: llvmpipe: Update includes and copyright headers. --- src/gallium/drivers/llvmpipe/lp_rast.c | 33 ++++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 26 +++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast_tri.c | 4 ++-- src/gallium/drivers/llvmpipe/lp_setup.c | 1 - 4 files changed, 61 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 58ef108123..df48ccce81 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -1,3 +1,36 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_memory.h" + +#include "lp_state.h" +#include "lp_quad.h" +#include "lp_rast.h" + struct lp_rasterizer *lp_rast_create( void ) { diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index e417be935b..dadde2e863 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -1,3 +1,29 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #ifndef LP_RAST_H #define LP_RAST_H diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 4b7b3719de..40965d5f65 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index d6e51888b9..ac9bfad3f2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -34,7 +34,6 @@ #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" -- cgit v1.2.3 From 931210424bc46b2c13919f0ac3e0ef781eff207e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 15:44:29 +0100 Subject: llvmpipe: wip me harder --- src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 84 +++--- src/gallium/drivers/llvmpipe/lp_rast.h | 11 + src/gallium/drivers/llvmpipe/lp_setup.c | 343 ++++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_setup.h | 44 ++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 187 ++++++------ src/gallium/drivers/llvmpipe/lp_setup_rasterize.c | 20 -- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 151 +++++----- 7 files changed, 536 insertions(+), 304 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_setup_rasterize.c (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c index 8cccb2905b..6c51d40a8f 100644 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c @@ -171,14 +171,14 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - llvmpipe_setup_point( setup_ctx, + lp_setup_point( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_LINES: for (i = 1; i < nr; i += 2) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } @@ -186,7 +186,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } @@ -194,12 +194,12 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_LINE_LOOP: for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); } if (nr) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, indices[nr-1], stride), get_vert(vertex_buffer, indices[0], stride) ); } @@ -208,7 +208,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_TRIANGLES: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-2], stride) ); @@ -216,7 +216,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) } else { for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -227,7 +227,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_TRIANGLE_STRIP: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i+(i&1)-1], stride), get_vert(vertex_buffer, indices[i-(i&1)], stride), get_vert(vertex_buffer, indices[i-2], stride) ); @@ -235,7 +235,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) } else { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -246,7 +246,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_TRIANGLE_FAN: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride) ); @@ -254,7 +254,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) } else { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -265,11 +265,11 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_QUADS: if (llvmpipe->rasterizer->flatshade_first) { for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-3], stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-3], stride) ); @@ -277,12 +277,12 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) } else { for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -293,11 +293,11 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_QUAD_STRIP: if (llvmpipe->rasterizer->flatshade_first) { for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-3], stride)); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-3], stride) ); @@ -305,11 +305,11 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) } else { for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-0], stride) ); @@ -324,7 +324,7 @@ lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) * flatshade_first state makes no difference. */ for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[0], stride) ); @@ -355,14 +355,14 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - llvmpipe_setup_point( setup_ctx, + lp_setup_point( setup_ctx, get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_LINES: for (i = 1; i < nr; i += 2) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } @@ -370,7 +370,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } @@ -378,12 +378,12 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_LINE_LOOP: for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); } if (nr) { - llvmpipe_setup_line( setup_ctx, + lp_setup_line( setup_ctx, get_vert(vertex_buffer, nr-1, stride), get_vert(vertex_buffer, 0, stride) ); } @@ -392,7 +392,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_TRIANGLES: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-2, stride) ); @@ -400,7 +400,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } else { for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -411,7 +411,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_TRIANGLE_STRIP: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i++) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i+(i&1)-1, stride), get_vert(vertex_buffer, i-(i&1), stride), get_vert(vertex_buffer, i-2, stride) ); @@ -419,7 +419,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } else { for (i = 2; i < nr; i++) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -430,7 +430,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_TRIANGLE_FAN: if (llvmpipe->rasterizer->flatshade_first) { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride) ); @@ -438,7 +438,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } else { for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -449,11 +449,11 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_QUADS: if (llvmpipe->rasterizer->flatshade_first) { for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride) ); @@ -461,11 +461,11 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } else { for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -476,11 +476,11 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_QUAD_STRIP: if (llvmpipe->rasterizer->flatshade_first) { for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride) ); @@ -488,11 +488,11 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } else { for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-0, stride) ); @@ -507,7 +507,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) * flatshade_first state makes no difference. */ for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, + lp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, 0, stride) ); @@ -525,7 +525,7 @@ static void lp_vbuf_destroy(struct vbuf_render *vbr) { struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - llvmpipe_setup_destroy_context(cvbr->setup); + lp_setup_destroy_context(cvbr->setup); FREE(cvbr); } @@ -556,7 +556,7 @@ lp_create_vbuf_backend(struct llvmpipe_context *lp) cvbr->llvmpipe = lp; - cvbr->setup = llvmpipe_setup_create_context(cvbr->llvmpipe); + cvbr->setup = lp_setup_create_context(cvbr->llvmpipe); return &cvbr->base; } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index dadde2e863..33a6065b89 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -90,6 +90,17 @@ struct lp_rast_triangle { struct lp_rast_shader_inputs inputs; }; +struct clear_tile { + boolean do_color; + boolean do_depth_stencil; + unsigned rgba; + unsigned depth_stencil; +}; + +struct load_tile { + boolean do_color; + boolean do_depth_stencil; +}; struct lp_rasterizer *lp_rast_create( void ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ac9bfad3f2..514366b71f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -26,124 +26,337 @@ **************************************************************************/ /** - * \brief Primitive rasterization/rendering (points, lines) + * Tiling engine. * - * \author Keith Whitwell - * \author Brian Paul + * Builds per-tile display lists and executes them on calls to + * lp_setup_flush(). */ -#include "lp_context.h" -#include "lp_quad.h" #include "lp_setup.h" -#include "lp_state.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_thread.h" #include "util/u_math.h" #include "util/u_memory.h" +void lp_setup_new_cmd_block( struct cmd_block_list *list ) +{ + struct cmd_block *block = MALLOC_STRUCT(cmd_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; +} -#define DEBUG_VERTS 0 +void lp_setup_new_data_block( struct data_block_list *list ) +{ + struct data_block *block = MALLOC_STRUCT(data_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; +} +static void reset_context( struct setup_context *setup ) +{ + for (i = 0; i < setup->tiles_x; i++) { + for (j = 0; j < setup->tiles_y; j++) { + struct cmd_block_list *list = scene->tile[i][j]; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->first; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + list->first = list->tail; + } + } -void -llvmpipe_setup_flush() + { + struct data_block_list *list = &scene->data; + struct data_block *block, *tmp; + + for (block = list->first; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + list->first = list->tail; + } +} + + + + +/* Add a command to all active bins. + */ +static void bin_everywhere( struct setup_context *setup, + bin_cmd cmd, + const union lp_rast_cmd_arg *arg ) { + unsigned i, j; + for (i = 0; i < setup->tiles_x; i++) + for (j = 0; j < setup->tiles_y; j++) + bin_cmd( setup, &setup->tile[i][j], cmd, arg ); } -void -llvmpipe_setup_bind_framebuffer() + +static void +rasterize_bins( struct setup_context *setup, + struct lp_rast *rast, + boolean write_depth ) { + lp_rast_bind_color( rast, + scene->fb.color, + TRUE ); /* WRITE */ + + lp_rast_bind_depth( rast, + scene->fb.depth, + write_depth ); /* WRITE */ + + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + + lp_rast_start_tile( rast, + i * TILESIZE, + j * TILESIZE ); + + for (block = scene->tile[i][j].first; block; block = block->next) { + for (k = 0; k < block->nr_cmds; k++) { + block->cmd[k].func( rast, block->cmd[k].arg ); + } + } + + lp_rast_finish_tile( rast ); + } + } + + lp_setup_free_data( setup ); } -void -llvmpipe_setup_clear() + + +static void +begin_binning( struct setup_context *setup ) { + if (setup->fb.color) { + if (setup->fb.clear_color) + bin_everywhere( setup, + lp_rast_clear_color, + &setup->clear_data ); + else + bin_everywhere( setup, + lp_rast_load_color, + NULL ); + } + + if (setup->fb.zstencil) { + if (setup->fb.clear_zstencil) + bin_everywhere( setup, + lp_rast_clear_zstencil, + &setup->clear_data ); + else + bin_everywhere( setup, + lp_rast_load_zstencil, + NULL ); + } } -/* Stubs for lines & points for now: +/* This basically bins and then flushes any outstanding full-screen + * clears. + * + * TODO: fast path for fullscreen clears and no triangles. */ -void -llvmpipe_setup_point(struct setup_context *setup, - const float (*v0)[4]) +static void +execute_clears( struct setup_context *setup ) { + begin_binning( setup ); + rasterize_bins( setup ); } + +static void +set_state( struct setup_context *setup, + unsigned new_state ) +{ + unsigned old_state = setup->state; + + if (old_state == new_state) + return; + + switch (new_state) { + case SETUP_ACTIVE: + if (old_state == SETUP_FLUSHED) + setup_begin_binning( setup ); + break; + + case SETUP_CLEARED: + if (old_state == SETUP_ACTIVE) { + assert(0); + return; + } + break; + + case SETUP_FLUSHED: + if (old_state == SETUP_CLEAR) + execute_clears( setup ); + else + rasterize_bins( setup ); + break; + } + + setup->state = new_state; +} + + void -llvmpipe_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) +lp_setup_flush( struct setup_context *setup, + unsigned flags ) { + set_state( setup, SETUP_FLUSHED ); } -/* Called after statechange, before emitting primitives. If binning - * is active, this function should store relevant state in the binning - * context. - * - * That includes: - * - current fragment shader function - * - bound constant buffer contents - * - bound textures - * - blend color - * - etc. - * - * Basically everything needed at some point in the future to - * rasterize triangles for the current state. - * - * Additionally this will set up the state needed for the rasterizer - * to process and bin incoming triangles. That would include such - * things as: - * - cull mode - * - ??? - * - etc. - * - */ -void setup_prepare( struct setup_context *setup ) +void +lp_setup_bind_framebuffer( struct setup_context *setup, + struct pipe_surface *color, + struct pipe_surface *zstencil ) { - struct llvmpipe_context *lp = setup->llvmpipe; + unsigned width, height; - if (lp->dirty) { - llvmpipe_update_derived(lp); - } + set_state( setup, SETUP_FLUSHED ); + + pipe_surface_reference( &setup->fb.color, color ); + pipe_surface_reference( &setup->fb.zstencil, zstencil ); + + width = MAX2( color->width, zstencil->width ); + height = MAX2( color->height, zstencil->height ); + + setup->tiles_x = align( width, TILESIZE ) / TILESIZE; + setup->tiles_y = align( height, TILESIZE ) / TILESIZE; +} + +void +lp_setup_clear( struct setup_context *setup, + const float *clear_color, + double clear_depth, + unsigned clear_stencil, + unsigned flags ) +{ + if (setup->state == SETUP_ACTIVE) { + struct lp_rast_clear_info *clear_info; + unsigned i, j; + + clear_info = alloc_clear_info( setup ); - lp->quad.first->begin( lp->quad.first ); + if (flags & PIPE_CLEAR_COLOR) { + pack_color( setup, + clear_info->color, + clear_color ); + bin_everywhere(setup, lp_rast_clear_color, clear_info ); + } - if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && - lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && - lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { - /* we'll do culling */ - setup->winding = lp->rasterizer->cull_mode; + if (flags & PIPE_CLEAR_DEPTH_STENCIL) { + pack_depth_stencil( setup, + clear_info->depth, + clear_depth, + clear_stencil ); + + bin_everywhere(setup, lp_rast_clear_zstencil, clear_info ); + } } else { - /* 'draw' will do culling */ - setup->winding = PIPE_WINDING_NONE; + set_state( setup, SETUP_CLEARED ); + setup->clear.flags |= flags; + + if (flags & PIPE_CLEAR_COLOR) { + memcpy(setup->clear.color, color, sizeof setup->clear.color); + } + + if (flags & PIPE_CLEAR_DEPTH_STENCIL) { + setup->clear.depth = clear_depth; + setup->clear.stencil = clear_stencil; + } } +} + + +void +lp_setup_set_fs_inputs( struct setup_context *setup, + const enum lp_interp *interp, + unsigned nr ) +{ + memcpy( setup->interp, interp, nr * sizeof interp[0] ); +} - setup_prepare_tri( setup->llvmpipe ); + +static void +first_triangle( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) +{ + set_state( setup, STATE_ACTIVE ); + setup_choose_triangle( setup, v0, v1, v2 ); +} + + + +/* Stubs for lines & points for now: + */ +void +lp_setup_point(struct setup_context *setup, + const float (*v0)[4]) +{ + setup->point( setup, v0 ); } +void +lp_setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + setup->line( setup, v0, v1 ); +} + +void +lp_setup_triangle(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) +{ + setup->triangle( setup, v0, v1, v2 ); +} void setup_destroy_context( struct setup_context *setup ) { + lp_rast_destroy( setup->rast ); FREE( setup ); } /** - * Create a new primitive setup/render stage. + * Create a new primitive tiling engine. Currently also creates a + * rasterizer to use with it. */ -struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ) +struct setup_context *setup_create_context( void ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); - unsigned i; - setup->llvmpipe = llvmpipe; + setup->rast = lp_rast_create( void ); + if (!setup->rast) + goto fail; + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) + setup->tile[i][j].first = + setup->tile[i][j].next = CALLOC_STRUCT(cmd_block); return setup; + +fail: + FREE(setup); + return NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 05aaaf83b8..2542faad36 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -27,28 +27,46 @@ #ifndef LP_SETUP_H #define LP_SETUP_H + +enum lp_interp { + LP_INTERP_CONSTANT, + LP_INTERP_LINEAR, + LP_INTERP_PERSPECTIVE, + LP_INTERP_POSITION, + LP_INTERP_FACING +}; + struct setup_context; -struct llvmpipe_context; -/* Note, not using setup_context currently - */ +struct setup_context * +lp_setup_create( void ); void -llvmpipe_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]); +lp_setup_triangle(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v1)[4]); void -llvmpipe_setup_point( struct setup_context *setup, - const float (*v0)[4] ); - +lp_setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]); -struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ); +void +lp_setup_point( struct setup_context *setup, + const float (*v0)[4] ); -void setup_prepare( struct setup_context *setup ); +void +lp_setup_set_triangle_state( struct setup_context *setup, + unsigned cullmode, + boolean front_is_ccw ); -void setup_destroy_context( struct setup_context *setup ); +void +lp_setup_set_fs_inputs( struct setup_context *setup, + const enum lp_interp *interp, + unsigned nr ); -void setup_prepare_tri( struct llvmpipe_context *llvmpipe ); +void +lp_setup_destroy( struct setup_context *setup ); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 848705e099..91540d6751 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -27,114 +27,125 @@ #ifndef LP_SETUP_CONTEXT_H #define LP_SETUP_CONTEXT_H -struct clear_tile { - boolean do_color; - boolean do_depth_stencil; - unsigned rgba; - unsigned depth_stencil; -}; - -struct load_tile { - boolean do_color; - boolean do_depth_stencil; -}; -/* Shade tile points directly at this: - */ -struct shader_inputs { - /* Some way of updating rasterizer state: - */ - /* ??? */ - - /* Attribute interpolation: - */ - float oneoverarea; - float x1; - float y1; - - struct tgsi_interp_coef position_coef; - struct tgsi_interp_coef *coef; -}; +#define CMD_BLOCK_MAX 128 +#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) -/* Shade triangle points at this: +/* switch to a non-pointer value for this: */ -struct shade_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; - - struct shader_inputs inputs; -}; - -struct bin_cmd { - enum { - CMD_END = 0, - CMD_CLEAR, - CMD_LOAD_TILE, - CMD_SHADE_TILE, - CMD_SHADE_TRIANGLE, - } cmd; - - union { - struct triangle *tri; - struct clear *clear; - } ptr; -}; +typedef void (*lp_rast_cmd)( struct lp_rast *, const union lp_rast_cmd_arg * ); struct cmd_block { - struct bin_cmd cmds[128]; + union lp_rast_arg *arg[CMD_BLOCK_MAX]; + lp_rast_cmd cmd[CMD_BLOCK_MAX]; unsigned count; struct cmd_block *next; }; -/* Triangles - */ struct data_block { - ubyte data[4096 - sizeof(unsigned) - sizeof(struct cmd_block *)]; - unsigned count; + ubyte data[DATA_BLOCK_SZ]; + unsigned used; struct data_block *next; }; -/* Need to store the state at the time the triangle was drawn, at - * least as it is needed during rasterization. That would include at - * minimum the constant values referred to by the fragment shader, - * blend state, etc. Much of this is code-generated into the shader - * in llvmpipe -- may be easier to do this work there. - */ -struct state_block { +struct cmd_block_list { + struct cmd_block *head; + struct cmd_block *tail; }; +struct data_block_list { + struct data_block *head; + struct data_block *tail; +}; + -/** - * Basically all the data from a binner scene: +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. */ -struct binned_scene { - struct llvmpipe_context *llvmpipe; +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 + +struct setup_context { + + /* When there are multiple threads, will want to double-buffer the + * bin arrays: + */ + struct cmd_block_list bin[MAXHEIGHT / TILESIZE][MAXWIDTH / TILESIZE]; + struct data_block_list data; + + unsigned tiles_x; + unsigned tiles_y; - struct cmd_block *bin[MAX_HEIGHT / BIN_SIZE][MAX_WIDTH / BIN_SIZE]; - struct data_block *data; + struct { + struct pipe_surface *color; + struct pipe_surface *zstencil; + } fb; + + struct { + unsigned flags; + float clear_color[4]; + double clear_depth; + unsigned clear_stencil; + } clear; + + enum { + SETUP_FLUSHED, + SETUP_CLEARED, + SETUP_ACTIVE + } state; + + struct { + enum lp_interp inputs[PIPE_MAX_ATTRIBS]; + unsigned nr_inputs; + } fs; + + void (*point)( struct setup_context *, + const float (*v0)[4]); + + void (*line)( struct setup_context *, + const float (*v0)[4], + const float (*v1)[4]); + + void (*triangle)( struct setup_context *, + const float (*v0)[4], + const float (*v1)[4], + const float (*v1)[4]); }; -static INLINE struct triangle *get_triangle( struct setup_context *setup ) +static INLINE void *get_data( struct data_block_list *list, + unsigned size) { - if (setup->triangles->count == TRIANGLE_BLOCK_COUNT) - return setup_triangle_from_new_block( setup ); - return &setup->triangles[setup->triangles->count++]; + if (list->tail->used + size > DATA_BLOCK_SIZE) { + lp_setup_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + char *data = tail->data + tail->used; + tail->used += size; + return data; + } +} + +/* Add a command to a given bin. + */ +static INLINE void bin_cmd( struct cmd_block_list *list, + bin_cmd cmd, + const union lp_rast_cmd_arg *arg ) +{ + if (list->tail.count == CMD_BLOCK_MAX) { + lp_setup_new_cmd_block( list ) + } + + { + struct cmd_block *tail = list->tail; + unsigned i = tail->count; + tail->cmd[i] = cmd; + tail->arg[i] = arg; + tail->count++; + } } + + + diff --git a/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c b/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c deleted file mode 100644 index bb7a4feb39..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_setup_rasterize.c +++ /dev/null @@ -1,20 +0,0 @@ - -void -lp_setup_rasterize( struct llvmpipe_context *llvmpipe, - struct binned_scene *scene ) -{ - lp_rast_bind_surfaces( rast, scene->framebuffer ); - - for (i = 0; i < scene->tiles_x; i++) { - for (j = 0; j < scene->tiles_y; j++) { - - lp_rast_start_tile( rast, i * TILESIZE, j * TILESIZE ); - - for (block = scene->tile[i][j].first; block; block = block->next) { - for (k = 0; k < block->nr_cmds; k++) { - block->cmd[k].func( rast, block->cmd[k].arg ); - } - } - } - } -} diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 98c87d551f..75a0ea8888 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -29,14 +29,8 @@ * Binning code for triangles */ -#include "lp_context.h" #include "lp_setup.h" #include "lp_state.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_thread.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -163,56 +157,55 @@ setup_fragcoord_coef(struct triangle *tri, unsigned slot) /** * Compute the tri->coef[] array dadx, dady, a0 values. */ -static void setup_tri_coefficients( struct llvmpipe_context *llvmpipe, +static void setup_tri_coefficients( struct setup_context *setup, struct triangle *tri, const float (*v1)[4], const float (*v2)[4], const float (*v3)[4], boolean frontface ) { - const struct lp_fragment_shader *fs = llvmpipe->fs; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); + const struct vertex_info *vinfo = setup->vinfo; unsigned input; /* z and w are done by linear interpolation: */ - linear_coef(tri, &tri->position_coef, v1, v2, v3, 0, 2); - linear_coef(tri, &tri->position_coef, v1, v2, v3, 0, 3); + linear_coef(tri, tri->position_coef, v1, v2, v3, 0, 2); + linear_coef(tri, tri->position_coef, v1, v2, v3, 0, 3); /* setup interpolation for all the remaining attributes: */ - for (input = 0; input < fs->info.num_inputs; input++) { + for (input = 0; input < vinfo->num_fs_inputs; input++) { unsigned vert_attr = vinfo->attrib[input].src_index; unsigned i; switch (vinfo->attrib[input].interp_mode) { case INTERP_CONSTANT: for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(&tri->coef[input], v3, vert_attr, i); + constant_coef(tri->coef[input], v3, vert_attr, i); break; case INTERP_LINEAR: for (i = 0; i < NUM_CHANNELS; i++) - linear_coef(tri, &tri->coef[input], v1, v2, v3, vert_attr, i); + linear_coef(tri, tri->coef[input], v1, v2, v3, vert_attr, i); break; case INTERP_PERSPECTIVE: for (i = 0; i < NUM_CHANNELS; i++) - perspective_coef(tri, &tri->coef[input], v1, v2, v3, vert_attr, i); + perspective_coef(tri, tri->coef[input], v1, v2, v3, vert_attr, i); break; case INTERP_POS: setup_fragcoord_coef(tri, input); break; - default: - assert(0); - } - - if (fs->info.input_semantic_name[input] == TGSI_SEMANTIC_FACE) { + case INTERP_FACING: tri->coef[input].a0[0] = 1.0f - frontface; tri->coef[input].dadx[0] = 0.0; tri->coef[input].dady[0] = 0.0; + break; + + default: + assert(0); } } } @@ -262,22 +255,22 @@ do_triangle_ccw(struct lp_setup *setup, const float x2 = subpixel_snap(v2[0][0]); const float x3 = subpixel_snap(v3[0][0]); - struct triangle *tri = allocate_triangle; + struct triangle *tri = allocate_triangle( setup ); float area; float c1, c2, c3; int i; int minx, maxx, miny, maxy; - tri.dx12 = x1 - x2; - tri.dx23 = x2 - x3; - tri.dx31 = x3 - x1; + tri->dx12 = x1 - x2; + tri->dx23 = x2 - x3; + tri->dx31 = x3 - x1; - tri.dy12 = y1 - y2; - tri.dy23 = y2 - y3; - tri.dy31 = y3 - y1; + tri->dy12 = y1 - y2; + tri->dy23 = y2 - y3; + tri->dy31 = y3 - y1; - area = (tri.dx12 * tri.dy31 - - tri.dx31 * tri.dy12); + area = (tri->dx12 * tri->dy31 - + tri->dx31 * tri->dy12); /* Cull non-ccw and zero-sized triangles. */ @@ -302,80 +295,87 @@ do_triangle_ccw(struct lp_setup *setup, /* The only divide in this code. Is it really needed? */ - tri.oneoverarea = 1.0f / area; + tri->oneoverarea = 1.0f / area; /* Setup parameter interpolants: */ - setup_tri_coefficients( setup, &tri, v1, v2, v3, frontfacing ); + setup_tri_coefficients( setup, tri, v1, v2, v3, frontfacing ); /* half-edge constants, will be interated over the whole * rendertarget. */ - c1 = tri.dy12 * x1 - tri.dx12 * y1; - c2 = tri.dy23 * x2 - tri.dx23 * y2; - c3 = tri.dy31 * x3 - tri.dx31 * y3; + c1 = tri->dy12 * x1 - tri->dx12 * y1; + c2 = tri->dy23 * x2 - tri->dx23 * y2; + c3 = tri->dy31 * x3 - tri->dx31 * y3; /* correct for top-left fill convention: */ - if (tri.dy12 < 0 || (tri.dy12 == 0 && tri.dx12 > 0)) c1++; - if (tri.dy23 < 0 || (tri.dy23 == 0 && tri.dx23 > 0)) c2++; - if (tri.dy31 < 0 || (tri.dy31 == 0 && tri.dx31 > 0)) c3++; + if (tri->dy12 < 0 || (tri->dy12 == 0 && tri->dx12 > 0)) c1++; + if (tri->dy23 < 0 || (tri->dy23 == 0 && tri->dx23 > 0)) c2++; + if (tri->dy31 < 0 || (tri->dy31 == 0 && tri->dx31 > 0)) c3++; /* find trivial reject offsets for each edge for a single-pixel * sized block. These will be scaled up at each recursive level to * match the active blocksize. Scaling in this way works best if * the blocks are square. */ - tri.eo1 = 0; - if (tri.dy12 < 0) tri.eo1 -= tri.dy12; - if (tri.dx12 > 0) tri.eo1 += tri.dx12; + tri->eo1 = 0; + if (tri->dy12 < 0) tri->eo1 -= tri->dy12; + if (tri->dx12 > 0) tri->eo1 += tri->dx12; - tri.eo2 = 0; - if (tri.dy23 < 0) tri.eo2 -= tri.dy23; - if (tri.dx23 > 0) tri.eo2 += tri.dx23; + tri->eo2 = 0; + if (tri->dy23 < 0) tri->eo2 -= tri->dy23; + if (tri->dx23 > 0) tri->eo2 += tri->dx23; - tri.eo3 = 0; - if (tri.dy31 < 0) tri.eo3 -= tri.dy31; - if (tri.dx31 > 0) tri.eo3 += tri.dx31; + tri->eo3 = 0; + if (tri->dy31 < 0) tri->eo3 -= tri->dy31; + if (tri->dx31 > 0) tri->eo3 += tri->dx31; /* Calculate trivial accept offsets from the above. */ - tri.ei1 = tri.dx12 - tri.dy12 - tri.eo1; - tri.ei2 = tri.dx23 - tri.dy23 - tri.eo2; - tri.ei3 = tri.dx31 - tri.dy31 - tri.eo3; + tri->ei1 = tri->dx12 - tri->dy12 - tri->eo1; + tri->ei2 = tri->dx23 - tri->dy23 - tri->eo2; + tri->ei3 = tri->dx31 - tri->dy31 - tri->eo3; 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; + c1 += tri->dx12 * miny - tri->dy12 * minx; + c2 += tri->dx23 * miny - tri->dy23 * minx; + c3 += tri->dx31 * miny - tri->dy31 * minx; - if (miny + TILESIZE > maxy && - minx + TILESIZE > maxx) + /* Convert to tile coordinates: + */ + minx /= TILESIZE; + maxx /= TILESIZE; + miny /= TILESIZE; + maxy /= TILESIZE; + + if (miny == maxy && minx == maxx) { /* Triangle is contained in a single tile: */ + bin_command(setup->tile[minx][miny], lp_rast_triangle, tri ); } else { const int step = TILESIZE; - float ei1 = tri.ei1 * step; - float ei2 = tri.ei2 * step; - float ei3 = tri.ei3 * step; + float ei1 = tri->ei1 * step; + float ei2 = tri->ei2 * step; + float ei3 = tri->ei3 * step; - float eo1 = tri.eo1 * step; - float eo2 = tri.eo2 * step; - float eo3 = tri.eo3 * step; + float eo1 = tri->eo1 * step; + float eo2 = tri->eo2 * step; + float eo3 = tri->eo3 * step; - float xstep1 = -step * tri.dy12; - float xstep2 = -step * tri.dy23; - float xstep3 = -step * tri.dy31; + 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 ystep1 = step * tri->dx12; + float ystep2 = step * tri->dx23; + float ystep3 = step * tri->dx31; int x, y; @@ -385,13 +385,13 @@ do_triangle_ccw(struct lp_setup *setup, * Trivially accept or reject blocks, else jump to per-pixel * examination above. */ - for (y = miny; y < maxy; y += step) + for (y = miny; y < maxy; y++) { float cx1 = c1; float cx2 = c2; float cx3 = c3; - for (x = minx; x < maxx; x += step) + for (x = minx; x < maxx; x++) { if (cx1 + eo1 < 0 || cx2 + eo2 < 0 || @@ -404,12 +404,12 @@ do_triangle_ccw(struct lp_setup *setup, cx3 + ei3 > 0) { /* shade whole tile */ - bin_command(tile[x][y], lp_rast_shade_tile, &tri->inputs ); + bin_command(setup->tile[x][y], lp_rast_shade_tile, &tri->inputs ); } else { /* shade partial tile */ - bin_command(tile[x][y], lp_rast_triangle, &tri ); + bin_command(setup->tile[x][y], lp_rast_triangle, tri ); } /* Iterate cx values across the region: @@ -469,14 +469,13 @@ static void triangle_nop( struct setup_context *setup, { } -void setup_prepare_tri( struct setup_context *setup ) +void setup_set_tri_state( struct setup_context *setup, + unsigned cull_mode, + boolean ccw_is_frontface) { - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - - setup->ccw_is_frontface = (llvmpipe->rasterizer->front_winding == - PIPE_WINDING_CW); + setup->ccw_is_frontface = ccw_is_frontface; - switch (llvmpipe->rasterizer->cull_mode) { + switch (cull_mode) { case PIPE_WINDING_NONE: setup->triangle = triangle_both; break; -- cgit v1.2.3 From 1caa26202c3bcc41ea5829b646128088e14d5dfd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 17:52:35 +0100 Subject: llvmpipe: start cleaning up --- src/gallium/drivers/llvmpipe/SConscript | 4 +-- src/gallium/drivers/llvmpipe/lp_rast.h | 12 ++++++-- src/gallium/drivers/llvmpipe/lp_setup.c | 41 ++++++++++++++----------- src/gallium/drivers/llvmpipe/lp_setup.h | 1 + src/gallium/drivers/llvmpipe/lp_setup_context.h | 26 ++++++++++------ 5 files changed, 52 insertions(+), 32 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index b39bc76da0..f6945535ca 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -47,8 +47,6 @@ llvmpipe = env.ConvenienceLibrary( 'lp_jit.c', 'lp_prim_vbuf.c', 'lp_query.c', - 'lp_rast.c', - 'lp_rast_tri.c', 'lp_setup.c', 'lp_screen.c', 'lp_state_blend.c', @@ -61,6 +59,8 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_vertex.c', 'lp_state_vs.c', 'lp_surface.c', + 'lp_rast.c', + 'lp_rast_tri.c', 'lp_tex_sample_llvm.c', 'lp_texture.c', 'lp_tile_soa.c', diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 33a6065b89..f40208bbda 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -28,6 +28,8 @@ #ifndef LP_RAST_H #define LP_RAST_H +#include "lp_jit.h" + /* Initially create and program a single rasterizer directly. Later * will want multiple of these, one or two per core. At that stage * will probably pass command buffers into the rasterizers rather than @@ -35,6 +37,9 @@ */ struct lp_rasterizer; +#define TILESIZE 64 + + struct lp_rast_state { /* State for the shader: */ @@ -55,10 +60,11 @@ struct lp_rast_shader_inputs { */ const struct lp_rast_state *state; - /* Attribute interpolation: + /* Attribute interpolation: FIXME: reduce memory waste! */ - struct tgsi_interp_coef position_coef; - struct tgsi_interp_coef *coef; + float a0[PIPE_MAX_ATTRIBS][4]; + float dadx[PIPE_MAX_ATTRIBS][4]; + float dady[PIPE_MAX_ATTRIBS][4]; }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 514366b71f..43a4f5f029 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -32,7 +32,7 @@ * lp_setup_flush(). */ -#include "lp_setup.h" +#include "lp_setup_context.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -56,31 +56,33 @@ void lp_setup_new_data_block( struct data_block_list *list ) static void reset_context( struct setup_context *setup ) { + unsigned i, j; + for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { - struct cmd_block_list *list = scene->tile[i][j]; + struct cmd_block_list *list = &setup->tile[i][j]; struct cmd_block *block; struct cmd_block *tmp; - for (block = list->first; block != list->tail; block = tmp) { + for (block = list->head; block != list->tail; block = tmp) { tmp = block->next; FREE(block); } - list->first = list->tail; + list->head = list->tail; } } { - struct data_block_list *list = &scene->data; + struct data_block_list *list = &setup->data; struct data_block *block, *tmp; - for (block = list->first; block != list->tail; block = tmp) { + for (block = list->head; block != list->tail; block = tmp) { tmp = block->next; FREE(block); } - list->first = list->tail; + list->head = list->tail; } } @@ -90,39 +92,42 @@ static void reset_context( struct setup_context *setup ) /* Add a command to all active bins. */ static void bin_everywhere( struct setup_context *setup, - bin_cmd cmd, + lp_rast_cmd cmd, const union lp_rast_cmd_arg *arg ) { unsigned i, j; for (i = 0; i < setup->tiles_x; i++) for (j = 0; j < setup->tiles_y; j++) - bin_cmd( setup, &setup->tile[i][j], cmd, arg ); + bin_cmd( &setup->tile[i][j], cmd, arg ); } static void rasterize_bins( struct setup_context *setup, - struct lp_rast *rast, boolean write_depth ) { + struct lp_rasterizer *rast = setup->rast; + struct cmd_block *block; + unsigned i,j,k; + lp_rast_bind_color( rast, - scene->fb.color, + setup->fb.color, TRUE ); /* WRITE */ lp_rast_bind_depth( rast, - scene->fb.depth, + setup->fb.zstencil, write_depth ); /* WRITE */ - for (i = 0; i < scene->tiles_x; i++) { - for (j = 0; j < scene->tiles_y; j++) { + for (i = 0; i < setup->tiles_x; i++) { + for (j = 0; j < setup->tiles_y; j++) { lp_rast_start_tile( rast, i * TILESIZE, j * TILESIZE ); - for (block = scene->tile[i][j].first; block; block = block->next) { - for (k = 0; k < block->nr_cmds; k++) { - block->cmd[k].func( rast, block->cmd[k].arg ); + for (block = setup->tile[i][j].head; block; block = block->next) { + for (k = 0; k < block->count; k++) { + block->cmd[k]( rast, block->arg[k] ); } } @@ -130,7 +135,7 @@ rasterize_bins( struct setup_context *setup, } } - lp_setup_free_data( setup ); + reset_context( setup ); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 5151a174f2..6f560f5f93 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -37,6 +37,7 @@ enum lp_interp { LP_INTERP_FACING }; +struct pipe_texture; struct setup_context; struct setup_context * diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index eeee7159d9..19d163df8e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -28,23 +28,25 @@ #ifndef LP_SETUP_CONTEXT_H #define LP_SETUP_CONTEXT_H +#include "lp_setup.h" +#include "lp_rast.h" #define CMD_BLOCK_MAX 128 #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) /* switch to a non-pointer value for this: */ -typedef void (*lp_rast_cmd)( struct lp_rast *, const union lp_rast_cmd_arg * ); +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg * ); struct cmd_block { - union lp_rast_arg *arg[CMD_BLOCK_MAX]; lp_rast_cmd cmd[CMD_BLOCK_MAX]; + const union lp_rast_cmd_arg *arg[CMD_BLOCK_MAX]; unsigned count; struct cmd_block *next; }; struct data_block { - ubyte data[DATA_BLOCK_SZ]; + ubyte data[DATA_BLOCK_SIZE]; unsigned used; struct data_block *next; }; @@ -68,10 +70,12 @@ struct data_block_list { struct setup_context { + struct lp_rasterizer *rast; + /* When there are multiple threads, will want to double-buffer the * bin arrays: */ - struct cmd_block_list bin[MAXHEIGHT / TILESIZE][MAXWIDTH / TILESIZE]; + struct cmd_block_list tile[MAXHEIGHT / TILESIZE][MAXWIDTH / TILESIZE]; struct data_block_list data; unsigned tiles_x; @@ -110,9 +114,12 @@ struct setup_context { void (*triangle)( struct setup_context *, const float (*v0)[4], const float (*v1)[4], - const float (*v1)[4]); + const float (*v2)[4]); }; +void lp_setup_new_data_block( struct data_block_list *list ); +void lp_setup_new_cmd_block( struct cmd_block_list *list ); + static INLINE void *get_data( struct data_block_list *list, unsigned size) { @@ -123,7 +130,7 @@ static INLINE void *get_data( struct data_block_list *list, { struct data_block *tail = list->tail; - char *data = tail->data + tail->used; + ubyte *data = tail->data + tail->used; tail->used += size; return data; } @@ -132,11 +139,11 @@ static INLINE void *get_data( struct data_block_list *list, /* Add a command to a given bin. */ static INLINE void bin_cmd( struct cmd_block_list *list, - bin_cmd cmd, + lp_rast_cmd cmd, const union lp_rast_cmd_arg *arg ) { - if (list->tail.count == CMD_BLOCK_MAX) { - lp_setup_new_cmd_block( list ) + if (list->tail->count == CMD_BLOCK_MAX) { + lp_setup_new_cmd_block( list ); } { @@ -150,3 +157,4 @@ static INLINE void bin_cmd( struct cmd_block_list *list, +#endif -- cgit v1.2.3 From f92787679d668bd1f48929da49d4df55be635fa9 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 19:03:35 +0100 Subject: llvmpipe: More assorted build fixes. --- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 4 ++-- src/gallium/drivers/llvmpipe/lp_setup.c | 1 - src/gallium/drivers/llvmpipe/lp_state_derived.c | 30 ++++--------------------- 3 files changed, 6 insertions(+), 29 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 40965d5f65..63e956fb20 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -203,8 +203,8 @@ void lp_rast_triangle( struct lp_rasterizer *rast, */ minx = MAX2(tri->maxx, rast->x); miny = MAX2(tri->miny, rast->y); - maxx = MIN2(tri->maxx, rast->x + TILESIZE); - maxy = MIN2(tri->maxy, rast->y + TILESIZE); + maxx = MIN2(tri->maxx, rast->x + TILE_SIZE); + maxy = MIN2(tri->maxy, rast->y + TILE_SIZE); if (miny == maxy || minx == maxx) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 43a4f5f029..9016c4b364 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -250,7 +250,6 @@ lp_setup_clear( struct setup_context *setup, { if (setup->state == SETUP_ACTIVE) { struct lp_rast_clear_info *clear_info; - unsigned i, j; clear_info = alloc_clear_info( setup ); diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 4015b0439a..b801f054a2 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -205,28 +205,7 @@ compute_cliprect(struct llvmpipe_context *lp) } -static void -update_tgsi_samplers( struct llvmpipe_context *llvmpipe ) -{ - unsigned i; - - /* vertex shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->sampler[i]; - llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->texture[i]; - llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples; - } - - /* fragment shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - llvmpipe->tgsi.frag_samplers[i].sampler = llvmpipe->sampler[i]; - llvmpipe->tgsi.frag_samplers[i].texture = llvmpipe->texture[i]; - llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples; - } - - llvmpipe->jit_context.samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list; -} - +#if 0 static void update_culling(struct llvmpipe_context *lp) { @@ -243,6 +222,7 @@ update_culling(struct llvmpipe_context *lp) setup->winding = PIPE_WINDING_NONE; } } +#endif /* Hopefully this will remain quite simple, otherwise need to pull in @@ -259,10 +239,6 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) llvmpipe->dirty |= LP_NEW_TEXTURE; } - if (llvmpipe->dirty & (LP_NEW_SAMPLER | - LP_NEW_TEXTURE)) - update_tgsi_samplers( llvmpipe ); - if (llvmpipe->dirty & (LP_NEW_RASTERIZER | LP_NEW_FS | LP_NEW_VS)) @@ -285,6 +261,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) } +#if 0 void llvmpipe_prepare(struct lp_setup_context *setup) { struct llvmpipe_context *lp = setup->llvmpipe; @@ -294,3 +271,4 @@ void llvmpipe_prepare(struct lp_setup_context *setup) } } +#endif -- cgit v1.2.3 From 0718c7700533a965d7cd06b4f67b82bbae6e66a1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 19:58:28 +0100 Subject: llvmpipe: work on clears and coefficients --- src/gallium/drivers/llvmpipe/lp_rast.c | 15 +- src/gallium/drivers/llvmpipe/lp_rast.h | 27 +--- src/gallium/drivers/llvmpipe/lp_setup.c | 51 +++++-- src/gallium/drivers/llvmpipe/lp_setup.h | 15 ++ src/gallium/drivers/llvmpipe/lp_setup_context.h | 5 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 186 ++++++++++++------------ 6 files changed, 166 insertions(+), 133 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 110caafffb..695ddc089a 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -48,14 +48,17 @@ struct lp_rasterizer *lp_rast_create( void ) return rast; } -void lp_rast_bind_surfaces( struct lp_rasterizer *rast, - struct pipe_surface *cbuf, - struct pipe_surface *zsbuf, - const float *clear_color, - double clear_depth, - unsigned clear_stencil) +void lp_rast_bind_color( struct lp_rasterizer *rast, + struct pipe_surface *cbuf, + boolean write_color ) { pipe_surface_reference(&rast->state.cbuf, cbuf); +} + +void lp_rast_bind_zstencil( struct lp_rasterizer *rast, + struct pipe_surface *zsbuf, + boolean write_zstencil ) +{ pipe_surface_reference(&rast->state.zsbuf, zsbuf); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 492e4b06ad..28bb0a60eb 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -101,27 +101,17 @@ struct lp_rast_triangle { struct lp_rast_shader_inputs *inputs; }; -struct clear_tile { - boolean do_color; - boolean do_depth_stencil; - unsigned rgba; - unsigned depth_stencil; -}; - -struct load_tile { - boolean do_color; - boolean do_depth_stencil; -}; struct lp_rasterizer *lp_rast_create( void ); -void lp_rast_bind_surfaces( struct lp_rasterizer *, - struct pipe_surface *cbuf, - struct pipe_surface *zsbuf, - const float *clear_color, - double clear_depth, - unsigned clear_stencil); +void lp_rast_bind_color( struct lp_rasterizer *, + struct pipe_surface *cbuf, + boolean write_when_done ); + +void lp_rast_bind_depth( struct lp_rasterizer *, + struct pipe_surface *zsbuf, + boolean write_when_done ); /* Begining of each tile: */ @@ -174,8 +164,7 @@ void lp_rast_store_zstencil( struct lp_rasterizer *, /* End of tile: */ -void lp_rast_end_tile( struct lp_rasterizer *rast, - boolean write_depth ); +void lp_rast_end_tile( struct lp_rasterizer *rast ); /* Shutdown: */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 9016c4b364..57ac85468d 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -58,6 +58,8 @@ static void reset_context( struct setup_context *setup ) { unsigned i, j; + /* Free binner command lists: + */ for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { struct cmd_block_list *list = &setup->tile[i][j]; @@ -73,6 +75,8 @@ static void reset_context( struct setup_context *setup ) } } + /* Free binned data: + */ { struct data_block_list *list = &setup->data; struct data_block *block, *tmp; @@ -84,6 +88,10 @@ static void reset_context( struct setup_context *setup ) list->head = list->tail; } + + /* Reset some state: + */ + setup->clear.flags = 0; } @@ -131,7 +139,7 @@ rasterize_bins( struct setup_context *setup, } } - lp_rast_finish_tile( rast ); + lp_rast_end_tile( rast ); } } @@ -144,10 +152,10 @@ static void begin_binning( struct setup_context *setup ) { if (setup->fb.color) { - if (setup->fb.clear_color) + if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, lp_rast_clear_color, - &setup->clear_data ); + &setup->clear.color ); else bin_everywhere( setup, lp_rast_load_color, @@ -155,10 +163,10 @@ begin_binning( struct setup_context *setup ) } if (setup->fb.zstencil) { - if (setup->fb.clear_zstencil) + if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) bin_everywhere( setup, lp_rast_clear_zstencil, - &setup->clear_data ); + &setup->clear.zstencil ); else bin_everywhere( setup, lp_rast_load_zstencil, @@ -176,7 +184,7 @@ static void execute_clears( struct setup_context *setup ) { begin_binning( setup ); - rasterize_bins( setup ); + rasterize_bins( setup, TRUE ); } @@ -192,7 +200,7 @@ set_state( struct setup_context *setup, switch (new_state) { case SETUP_ACTIVE: if (old_state == SETUP_FLUSHED) - setup_begin_binning( setup ); + begin_binning( setup ); break; case SETUP_CLEARED: @@ -203,10 +211,10 @@ set_state( struct setup_context *setup, break; case SETUP_FLUSHED: - if (old_state == SETUP_CLEAR) + if (old_state == SETUP_CLEARED) execute_clears( setup ); else - rasterize_bins( setup ); + rasterize_bins( setup, TRUE ); break; } @@ -271,15 +279,20 @@ lp_setup_clear( struct setup_context *setup, } else { set_state( setup, SETUP_CLEARED ); + setup->clear.flags |= flags; if (flags & PIPE_CLEAR_COLOR) { - memcpy(setup->clear.color, color, sizeof setup->clear.color); + util_pack_color(rgba, + setup->fb.cbuf->format, + &setup->clear.color.clear_color ); } if (flags & PIPE_CLEAR_DEPTH_STENCIL) { - setup->clear.depth = clear_depth; - setup->clear.stencil = clear_stencil; + setup->clear.zstencil.clear_zstencil = + util_pack_z_stencil(setup->fb.zsbuf->format, + depth, + stencil); } } } @@ -293,6 +306,12 @@ lp_setup_set_fs_inputs( struct setup_context *setup, memcpy( setup->interp, interp, nr * sizeof interp[0] ); } +void +lp_setup_set_shader_state( struct setup_context *setup, + const struct jit_context *jc ) +{ +} + static void first_triangle( struct setup_context *setup, @@ -324,10 +343,10 @@ lp_setup_line(struct setup_context *setup, } void -lp_setup_triangle(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4]) +lp_setup_tri(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) { setup->triangle( setup, v0, v1, v2 ); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 6f560f5f93..7c813070b9 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -65,6 +65,17 @@ void lp_setup_point( struct setup_context *setup, const float (*v0)[4] ); + +void +lp_setup_flush( struct setup_context *setup, + unsigned flags ); + + +void +lp_setup_bind_framebuffer( struct setup_context *setup, + struct pipe_surface *color, + struct pipe_surface *zstencil ); + void lp_setup_set_triangle_state( struct setup_context *setup, unsigned cullmode, @@ -75,6 +86,10 @@ lp_setup_set_fs_inputs( struct setup_context *setup, const enum lp_interp *interp, unsigned nr ); +void +lp_setup_set_shader_state( struct setup_context *setup, + const struct jit_context *jc ); + boolean lp_setup_is_texture_referenced( struct setup_context *setup, const struct pipe_texture *texture ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 19d163df8e..5722e3e9de 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -88,9 +88,8 @@ struct setup_context { struct { unsigned flags; - float clear_color[4]; - double clear_depth; - unsigned clear_stencil; + union lp_rast_cmd_arg color; + union lp_rast_cmd_arg zstencil; } clear; enum { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 75a0ea8888..efd91124a0 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -38,55 +38,60 @@ /** * Compute a0 for a constant-valued coefficient (GL_FLAT shading). */ -static void constant_coef( struct tgsi_interp_coef *coef, +static void constant_coef( struct lp_rast_triangle *tri, const float (*v3)[4], unsigned vert_attr, unsigned i ) { - coef->a0[i] = v3[vert_attr][i]; - coef->dadx[i] = 0; - coef->dady[i] = 0; + tri->inputs.a0[i] = v3[vert_attr][i]; + tri->inputs.dadx[i] = 0; + tri->inputs.dady[i] = 0; } /** * Compute a0, dadx and dady for a linearly interpolated coefficient, * for a triangle. */ -static void linear_coef( struct triangle *tri, - struct tgsi_interp_coef *coef, +static void linear_coef( struct lp_rast_triangle *tri, + unsigned input, const float (*v1)[4], const float (*v2)[4], const float (*v3)[4], - unsigned vert_attr, - unsigned i) + unsigned vert_attr) { - float a1 = v1[vert_attr][i]; - float a2 = v2[vert_attr][i]; - float a3 = v3[vert_attr][i]; - - float da12 = a1 - a2; - float da31 = a3 - a1; - float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea; - float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea; - - coef->dadx[i] = dadx; - coef->dady[i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (0.5, 0.5). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - coef->a0[i] = (v1[vert_attr][i] - - (dadx * (v1[0][0] - 0.5f) + - dady * (v1[0][1] - 0.5f))); + unsigned i; + + input *= 4; + + for (i = 0; i < NUM_CHANNELS; i++) { + float a1 = v1[vert_attr][i]; + float a2 = v2[vert_attr][i]; + float a3 = v3[vert_attr][i]; + + float da12 = a1 - a2; + float da31 = a3 - a1; + float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea; + float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea; + + tri->inputs.dadx[input+i] = dadx; + tri->inputs.dady[input+i] = dady; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + tri->inputs.a0[input+i] = (v1[vert_attr][i] - + (dadx * (v1[0][0] - 0.5f) + + dady * (v1[0][1] - 0.5f))); + } } @@ -98,30 +103,35 @@ static void linear_coef( struct triangle *tri, * Later, when we compute the value at a particular fragment position we'll * divide the interpolated value by the interpolated W at that fragment. */ -static void perspective_coef( struct triangle *tri, - struct tgsi_interp_coef *coef, +static void perspective_coef( struct lp_rast_triangle *tri, const float (*v1)[4], const float (*v2)[4], const float (*v3)[4], unsigned vert_attr, unsigned i) { - /* premultiply by 1/w (v[0][3] is always 1/w): - */ - float a1 = v1[vert_attr][i] * v1[0][3]; - float a2 = v2[vert_attr][i] * v2[0][3]; - float a3 = v3[vert_attr][i] * v3[0][3]; - float da12 = a1 - a2; - float da31 = a3 - a1; - float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea; - float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea; - - - coef->dadx[i] = dadx; - coef->dady[i] = dady; - coef->a0[i] = (a1 - - (dadx * (v1[0][0] - 0.5f) + - dady * (v1[0][1] - 0.5f))); + unsigned i; + + input *= 4; + + for (i = 0; i < NUM_CHANNELS; i++) { + /* premultiply by 1/w (v[0][3] is always 1/w): + */ + float a1 = v1[vert_attr][i] * v1[0][3]; + float a2 = v2[vert_attr][i] * v2[0][3]; + float a3 = v3[vert_attr][i] * v3[0][3]; + float da12 = a1 - a2; + float da31 = a3 - a1; + float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * tri->oneoverarea; + float dady = (da31 * tri->dx12 - tri->dx31 * da12) * tri->oneoverarea; + + + tri->inputs.dadx[input+i] = dadx; + tri->inputs.dady[input+i] = dady; + tri->inputs.a0[input+i] = (a1 - + (dadx * (v1[0][0] - 0.5f) + + dady * (v1[0][1] - 0.5f))); + } } @@ -132,24 +142,26 @@ static void perspective_coef( struct triangle *tri, * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void -setup_fragcoord_coef(struct triangle *tri, unsigned slot) +setup_fragcoord_coef(struct lp_rast_triangle *tri, unsigned slot) { + slot *= 4; + /*X*/ - tri->coef[slot].a0[0] = 0.0; - tri->coef[slot].dadx[0] = 1.0; - tri->coef[slot].dady[0] = 0.0; + tri->inputs.a0[slot+0] = 0.0; + tri->inputs.dadx[slot+0] = 1.0; + tri->inputs.dady[slot+0] = 0.0; /*Y*/ - tri->coef[slot].a0[1] = 0.0; - tri->coef[slot].dadx[1] = 0.0; - tri->coef[slot].dady[1] = 1.0; + tri->inputs.a0[slot+1] = 0.0; + tri->inputs.dadx[slot+1] = 0.0; + tri->inputs.dady[slot+1] = 1.0; /*Z*/ - tri->coef[slot].a0[2] = tri->position_coef.a0[2]; - tri->coef[slot].dadx[2] = tri->position_coef.dadx[2]; - tri->coef[slot].dady[2] = tri->position_coef.dady[2]; + tri->inputs.a0[slot+2] = tri->inputs.a0[2]; + tri->inputs.dadx[slot+2] = tri->inputs.dadx[2]; + tri->inputs.dady[slot+2] = tri->inputs.dady[2]; /*W*/ - tri->coef[slot].a0[3] = tri->position_coef.a0[3]; - tri->coef[slot].dadx[3] = tri->position_coef.dadx[3]; - tri->coef[slot].dady[3] = tri->position_coef.dady[3]; + tri->inputs.a0[slot+3] = tri->inputs.a0[3]; + tri->inputs.dadx[slot+3] = tri->inputs.dadx[3]; + tri->inputs.dady[slot+3] = tri->inputs.dady[3]; } @@ -158,50 +170,46 @@ setup_fragcoord_coef(struct triangle *tri, unsigned slot) * Compute the tri->coef[] array dadx, dady, a0 values. */ static void setup_tri_coefficients( struct setup_context *setup, - struct triangle *tri, + struct lp_rast_triangle *tri, const float (*v1)[4], const float (*v2)[4], const float (*v3)[4], boolean frontface ) { - const struct vertex_info *vinfo = setup->vinfo; unsigned input; /* z and w are done by linear interpolation: */ - linear_coef(tri, tri->position_coef, v1, v2, v3, 0, 2); - linear_coef(tri, tri->position_coef, v1, v2, v3, 0, 3); + setup_fragcoord_coef(tri, 0); + linear_coef(tri, input, v1, v2, v3, vert_attr, i); - /* setup interpolation for all the remaining attributes: + /* setup interpolation for all the remaining attrbutes: */ - for (input = 0; input < vinfo->num_fs_inputs; input++) { - unsigned vert_attr = vinfo->attrib[input].src_index; + for (input = 0; input < setup->fs.nr_inputs; input++) { + unsigned vert_attr = setup->fs.input[input].src_index; unsigned i; - switch (vinfo->attrib[input].interp_mode) { - case INTERP_CONSTANT: - for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(tri->coef[input], v3, vert_attr, i); + switch (setup->fs.input[input].interp_mode) { + case LP_INTERP_CONSTANT: + constant_coef(tri, input, v3, vert_attr, i); break; - case INTERP_LINEAR: - for (i = 0; i < NUM_CHANNELS; i++) - linear_coef(tri, tri->coef[input], v1, v2, v3, vert_attr, i); + case LP_INTERP_LINEAR: + linear_coef(tri, input, v1, v2, v3, vert_attr, i); break; - case INTERP_PERSPECTIVE: - for (i = 0; i < NUM_CHANNELS; i++) - perspective_coef(tri, tri->coef[input], v1, v2, v3, vert_attr, i); + case LP_INTERP_PERSPECTIVE: + perspective_coef(tri, input, v1, v2, v3, vert_attr, i); break; - case INTERP_POS: + case LP_INTERP_POS: setup_fragcoord_coef(tri, input); break; - case INTERP_FACING: - tri->coef[input].a0[0] = 1.0f - frontface; - tri->coef[input].dadx[0] = 0.0; - tri->coef[input].dady[0] = 0.0; + case LP_INTERP_FACING: + tri->inputs.a0[input*4+0] = 1.0f - frontface; + tri->inputs.dadx[input*4+0] = 0.0; + tri->da[input].dady[0] = 0.0; break; default: @@ -255,7 +263,7 @@ do_triangle_ccw(struct lp_setup *setup, const float x2 = subpixel_snap(v2[0][0]); const float x3 = subpixel_snap(v3[0][0]); - struct triangle *tri = allocate_triangle( setup ); + struct lp_setup_triangle *tri = lp_setup_alloc_data( setup, sizeof *tri ); float area; float c1, c2, c3; int i; -- cgit v1.2.3 From 253dfed93918bd87c4a55047a9d569ede545f8be Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 23:08:41 +0100 Subject: llvmpipe: get lp_setup compiling --- src/gallium/drivers/llvmpipe/lp_setup.c | 131 ++++++++++++++++-------- src/gallium/drivers/llvmpipe/lp_setup.h | 11 +- src/gallium/drivers/llvmpipe/lp_setup_context.h | 28 +++-- 3 files changed, 117 insertions(+), 53 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 57ac85468d..9f1b3d21f0 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -35,6 +35,10 @@ #include "lp_setup_context.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_pack_color.h" +#include "pipe/p_defines.h" + +static void set_state( struct setup_context *, unsigned ); void lp_setup_new_cmd_block( struct cmd_block_list *list ) { @@ -54,6 +58,37 @@ void lp_setup_new_data_block( struct data_block_list *list ) block->used = 0; } + +static void +first_triangle( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) +{ + set_state( setup, SETUP_ACTIVE ); + lp_setup_choose_triangle( setup ); + setup->triangle( setup, v0, v1, v2 ); +} + +static void +first_line( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + set_state( setup, SETUP_ACTIVE ); + lp_setup_choose_line( setup ); + setup->line( setup, v0, v1 ); +} + +static void +first_point( struct setup_context *setup, + const float (*v0)[4]) +{ + set_state( setup, SETUP_ACTIVE ); + lp_setup_choose_point( setup ); + setup->point( setup, v0 ); +} + static void reset_context( struct setup_context *setup ) { unsigned i, j; @@ -92,6 +127,13 @@ static void reset_context( struct setup_context *setup ) /* Reset some state: */ setup->clear.flags = 0; + + /* Have an explicit "start-binning" call and get rid of this + * pointer twiddling? + */ + setup->line = first_line; + setup->point = first_point; + setup->triangle = first_triangle; } @@ -119,11 +161,11 @@ rasterize_bins( struct setup_context *setup, unsigned i,j,k; lp_rast_bind_color( rast, - setup->fb.color, + setup->fb.cbuf, TRUE ); /* WRITE */ lp_rast_bind_depth( rast, - setup->fb.zstencil, + setup->fb.zsbuf, write_depth ); /* WRITE */ for (i = 0; i < setup->tiles_x; i++) { @@ -151,7 +193,7 @@ rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { - if (setup->fb.color) { + if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, lp_rast_clear_color, @@ -162,7 +204,7 @@ begin_binning( struct setup_context *setup ) NULL ); } - if (setup->fb.zstencil) { + if (setup->fb.zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) bin_everywhere( setup, lp_rast_clear_zstencil, @@ -239,8 +281,8 @@ lp_setup_bind_framebuffer( struct setup_context *setup, set_state( setup, SETUP_FLUSHED ); - pipe_surface_reference( &setup->fb.color, color ); - pipe_surface_reference( &setup->fb.zstencil, zstencil ); + pipe_surface_reference( &setup->fb.cbuf, color ); + pipe_surface_reference( &setup->fb.zsbuf, zstencil ); width = MAX2( color->width, zstencil->width ); height = MAX2( color->height, zstencil->height ); @@ -251,44 +293,55 @@ lp_setup_bind_framebuffer( struct setup_context *setup, void lp_setup_clear( struct setup_context *setup, - const float *clear_color, - double clear_depth, - unsigned clear_stencil, + const float *color, + double depth, + unsigned stencil, unsigned flags ) { if (setup->state == SETUP_ACTIVE) { - struct lp_rast_clear_info *clear_info; + /* Add the clear to existing bins. In the unusual case where + * both color and depth-stencilare being cleared, we could + * discard the currently binned scene and start again, but I + * don't see that as being a common usage. + */ + if (flags & PIPE_CLEAR_COLOR) { + union lp_rast_cmd_arg *arg = get_data( &setup->data, sizeof *arg ); - clear_info = alloc_clear_info( setup ); + util_pack_color(color, + setup->fb.cbuf->format, + &arg->clear_color ); - if (flags & PIPE_CLEAR_COLOR) { - pack_color( setup, - clear_info->color, - clear_color ); - bin_everywhere(setup, lp_rast_clear_color, clear_info ); + bin_everywhere(setup, lp_rast_clear_color, arg ); } - if (flags & PIPE_CLEAR_DEPTH_STENCIL) { - pack_depth_stencil( setup, - clear_info->depth, - clear_depth, - clear_stencil ); + if (flags & PIPE_CLEAR_DEPTHSTENCIL) { + union lp_rast_cmd_arg *arg = get_data( &setup->data, sizeof *arg ); + + arg->clear_zstencil = + util_pack_z_stencil(setup->fb.zsbuf->format, + depth, + stencil); - bin_everywhere(setup, lp_rast_clear_zstencil, clear_info ); + bin_everywhere(setup, lp_rast_clear_zstencil, arg ); } } else { + /* Put ourselves into the 'pre-clear' state, specifically to try + * and accumulate multiple clears to color and depth_stencil + * buffers which the app or state-tracker might issue + * separately. + */ set_state( setup, SETUP_CLEARED ); setup->clear.flags |= flags; if (flags & PIPE_CLEAR_COLOR) { - util_pack_color(rgba, + util_pack_color(color, setup->fb.cbuf->format, &setup->clear.color.clear_color ); } - if (flags & PIPE_CLEAR_DEPTH_STENCIL) { + if (flags & PIPE_CLEAR_DEPTHSTENCIL) { setup->clear.zstencil.clear_zstencil = util_pack_z_stencil(setup->fb.zsbuf->format, depth, @@ -300,28 +353,21 @@ lp_setup_clear( struct setup_context *setup, void lp_setup_set_fs_inputs( struct setup_context *setup, - const enum lp_interp *interp, + const struct lp_shader_input *input, unsigned nr ) { - memcpy( setup->interp, interp, nr * sizeof interp[0] ); + memcpy( setup->fs.input, input, nr * sizeof input[0] ); + setup->fs.nr_inputs = nr; } void lp_setup_set_shader_state( struct setup_context *setup, - const struct jit_context *jc ) + const struct lp_jit_context *jc ) { + } -static void -first_triangle( struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4]) -{ - set_state( setup, STATE_ACTIVE ); - setup_choose_triangle( setup, v0, v1, v2 ); -} @@ -352,7 +398,8 @@ lp_setup_tri(struct setup_context *setup, } -void setup_destroy_context( struct setup_context *setup ) +void +lp_setup_destroy( struct setup_context *setup ) { lp_rast_destroy( setup->rast ); FREE( setup ); @@ -363,18 +410,20 @@ void setup_destroy_context( struct setup_context *setup ) * Create a new primitive tiling engine. Currently also creates a * rasterizer to use with it. */ -struct setup_context *setup_create_context( void ) +struct setup_context * +lp_setup_create( void ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); + unsigned i, j; - setup->rast = lp_rast_create( void ); + setup->rast = lp_rast_create(); if (!setup->rast) goto fail; for (i = 0; i < TILES_X; i++) for (j = 0; j < TILES_Y; j++) - setup->tile[i][j].first = - setup->tile[i][j].next = CALLOC_STRUCT(cmd_block); + setup->tile[i][j].head = + setup->tile[i][j].tail = CALLOC_STRUCT(cmd_block); return setup; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 7c813070b9..04f9f87892 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -37,8 +37,15 @@ enum lp_interp { LP_INTERP_FACING }; +struct lp_shader_input { + enum lp_interp interp; + unsigned vs_output; +}; + struct pipe_texture; +struct pipe_surface; struct setup_context; +struct lp_jit_context; struct setup_context * lp_setup_create( void ); @@ -83,12 +90,12 @@ lp_setup_set_triangle_state( struct setup_context *setup, void lp_setup_set_fs_inputs( struct setup_context *setup, - const enum lp_interp *interp, + const struct lp_shader_input *interp, unsigned nr ); void lp_setup_set_shader_state( struct setup_context *setup, - const struct jit_context *jc ); + const struct lp_jit_context *jc ); boolean lp_setup_is_texture_referenced( struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 5722e3e9de..37caeed85f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -31,8 +31,17 @@ #include "lp_setup.h" #include "lp_rast.h" +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. + */ +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 +#define TILES_X (MAXWIDTH / TILESIZE) +#define TILES_Y (MAXHEIGHT / TILESIZE) + #define CMD_BLOCK_MAX 128 #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) + /* switch to a non-pointer value for this: */ @@ -62,12 +71,6 @@ struct data_block_list { }; -/* We're limited to 2K by 2K for 32bit fixed point rasterization. - * Will need a 64-bit version for larger framebuffers. - */ -#define MAXHEIGHT 2048 -#define MAXWIDTH 2048 - struct setup_context { struct lp_rasterizer *rast; @@ -75,15 +78,15 @@ struct setup_context { /* When there are multiple threads, will want to double-buffer the * bin arrays: */ - struct cmd_block_list tile[MAXHEIGHT / TILESIZE][MAXWIDTH / TILESIZE]; + struct cmd_block_list tile[TILES_X][TILES_Y]; struct data_block_list data; unsigned tiles_x; unsigned tiles_y; struct { - struct pipe_surface *color; - struct pipe_surface *zstencil; + struct pipe_surface *cbuf; + struct pipe_surface *zsbuf; } fb; struct { @@ -99,7 +102,7 @@ struct setup_context { } state; struct { - enum lp_interp inputs[PIPE_MAX_ATTRIBS]; + struct lp_shader_input input[PIPE_MAX_ATTRIBS]; unsigned nr_inputs; } fs; @@ -116,6 +119,11 @@ struct setup_context { const float (*v2)[4]); }; +void lp_setup_choose_triangle( struct setup_context *setup ); +void lp_setup_choose_line( struct setup_context *setup ); +void lp_setup_choose_point( struct setup_context *setup ); + + void lp_setup_new_data_block( struct data_block_list *list ); void lp_setup_new_cmd_block( struct cmd_block_list *list ); -- cgit v1.2.3 From 84ab7dcf48e87350c0622c533e51aa495f7256c2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 10:24:19 +0100 Subject: llvmpipe: calculate overall width and height, pass to rasterizer --- src/gallium/drivers/llvmpipe/lp_rast.c | 24 ++++++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 15 ++++++-- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 4 ++ src/gallium/drivers/llvmpipe/lp_setup.c | 51 ++++++++++++++++++++----- src/gallium/drivers/llvmpipe/lp_setup.h | 10 ++++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 2 + 6 files changed, 84 insertions(+), 22 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 695ddc089a..6ac44feb4c 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -48,6 +48,17 @@ struct lp_rasterizer *lp_rast_create( void ) return rast; } + +void lp_rast_begin( struct lp_rasterizer *rast, + unsigned width, + unsigned height ) +{ + rast->width = width; + rast->height = height; + rast->check_for_clipped_tiles = (width % TILESIZE != 0 || + height % TILESIZE != 0); +} + void lp_rast_bind_color( struct lp_rasterizer *rast, struct pipe_surface *cbuf, boolean write_color ) @@ -195,8 +206,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, */ -void lp_rast_end_tile( struct lp_rasterizer *rast, - boolean write_depth ) +void lp_rast_end_tile( struct lp_rasterizer *rast ) { struct pipe_surface *surface; struct pipe_screen *screen; @@ -213,10 +223,10 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, screen = surface->texture->screen; - if(x + w > surface->width) - w = surface->width - x; - if(y + h > surface->height) - h = surface->height - y; + if(x + w > rast->width) + w = rast->width - x; + if(y + h > rast->height) + h = rast->height - y; transfer = screen->get_tex_transfer(screen, surface->texture, @@ -240,7 +250,7 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, screen->tex_transfer_destroy(transfer); - if (write_depth) { + if (0) { /* FIXME: call u_tile func to store depth/stencil to surface */ } } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 64d668f998..26d057beb2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -97,6 +97,11 @@ struct lp_rast_triangle { float dx23; float dx31; + /* XXX: these are only used inside lp_setup_tri.c, don't really + * need to bin them: + */ + float oneoverarea; + /* inputs for the shader */ struct lp_rast_shader_inputs inputs; }; @@ -105,13 +110,17 @@ struct lp_rast_triangle { struct lp_rasterizer *lp_rast_create( void ); +void lp_rast_begin( struct lp_rasterizer *, + unsigned width, + unsigned height); + void lp_rast_bind_color( struct lp_rasterizer *, struct pipe_surface *cbuf, boolean write_when_done ); -void lp_rast_bind_depth( struct lp_rasterizer *, - struct pipe_surface *zsbuf, - boolean write_when_done ); +void lp_rast_bind_zstencil( struct lp_rasterizer *, + struct pipe_surface *zsbuf, + boolean write_when_done ); /* Begining of each tile: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 29e4c8fd80..d7a8b9c257 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -52,7 +52,11 @@ struct lp_rasterizer { unsigned x; unsigned y; + boolean clipped_tile; + boolean check_for_clipped_tiles; + unsigned width; + unsigned height; struct { struct pipe_surface *cbuf; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 9f1b3d21f0..4f10080816 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -160,13 +160,23 @@ rasterize_bins( struct setup_context *setup, struct cmd_block *block; unsigned i,j,k; + if (setup->state != SETUP_ACTIVE) { + /* this can happen, not a big deal */ + debug_printf("%s called when not binning\n", __FUNCTION__); + return; + } + + lp_rast_begin( rast, + setup->fb.width, + setup->fb.height ); + lp_rast_bind_color( rast, setup->fb.cbuf, - TRUE ); /* WRITE */ + setup->fb.cbuf != NULL ); - lp_rast_bind_depth( rast, - setup->fb.zsbuf, - write_depth ); /* WRITE */ + lp_rast_bind_zstencil( rast, + setup->fb.zsbuf, + setup->fb.zsbuf != NULL && write_depth ); for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { @@ -193,15 +203,38 @@ rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { + if (!setup->fb.cbuf && !setup->fb.zsbuf) { + setup->fb.width = 0; + setup->fb.height = 0; + } + else if (!setup->fb.zsbuf) { + setup->fb.width = setup->fb.cbuf->width; + setup->fb.height = setup->fb.cbuf->height; + } + else if (!setup->fb.cbuf) { + setup->fb.width = setup->fb.zsbuf->width; + setup->fb.height = setup->fb.zsbuf->height; + } + else { + /* XXX: not sure what we're really supposed to do for + * mis-matched color & depth buffer sizes. + */ + setup->fb.width = MIN2(setup->fb.cbuf->width, + setup->fb.zsbuf->width); + setup->fb.height = MIN2(setup->fb.cbuf->height, + setup->fb.zsbuf->height); + } + + setup->tiles_x = align(setup->fb.width, TILESIZE); + setup->tiles_y = align(setup->fb.height, TILESIZE); + if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, lp_rast_clear_color, &setup->clear.color ); else - bin_everywhere( setup, - lp_rast_load_color, - NULL ); + bin_everywhere( setup, lp_rast_load_color, NULL ); } if (setup->fb.zsbuf) { @@ -210,9 +243,7 @@ begin_binning( struct setup_context *setup ) lp_rast_clear_zstencil, &setup->clear.zstencil ); else - bin_everywhere( setup, - lp_rast_load_zstencil, - NULL ); + bin_everywhere( setup, lp_rast_load_zstencil, NULL ); } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 04f9f87892..bd439fa857 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -37,9 +37,15 @@ enum lp_interp { LP_INTERP_FACING }; +/* Describes how to generate all the fragment shader inputs from the + * the vertices passed into our triangle/line/point functions. + * + * Vertices are treated as an array of float[4] values, indexed by + * src_index. + */ struct lp_shader_input { - enum lp_interp interp; - unsigned vs_output; + enum lp_interp interp; /* how to interpolate values */ + unsigned src_index; /* where to find values in incoming vertices */ }; struct pipe_texture; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 37caeed85f..7410ac70b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -87,6 +87,8 @@ struct setup_context { struct { struct pipe_surface *cbuf; struct pipe_surface *zsbuf; + unsigned width; + unsigned height; } fb; struct { -- cgit v1.2.3 From 415b271b5100d64579690111bc8eb549866865a7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 10:44:07 +0100 Subject: llvmpipe: hook up some state, add stub line and point functions --- src/gallium/drivers/llvmpipe/SConscript | 3 ++ src/gallium/drivers/llvmpipe/lp_setup.c | 23 +++++++++++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 9 +++-- src/gallium/drivers/llvmpipe/lp_setup_line.c | 47 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup_point.c | 46 ++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup_tri.c | 20 +++++------ 6 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_setup_line.c create mode 100644 src/gallium/drivers/llvmpipe/lp_setup_point.c (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index f6945535ca..3530e739cc 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -48,6 +48,9 @@ llvmpipe = env.ConvenienceLibrary( 'lp_prim_vbuf.c', 'lp_query.c', 'lp_setup.c', + 'lp_setup_tri.c', + 'lp_setup_line.c', + 'lp_setup_point.c', 'lp_screen.c', 'lp_state_blend.c', 'lp_state_clip.c', diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 4f10080816..13b40f1494 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -148,7 +148,7 @@ static void bin_everywhere( struct setup_context *setup, unsigned i, j; for (i = 0; i < setup->tiles_x; i++) for (j = 0; j < setup->tiles_y; j++) - bin_cmd( &setup->tile[i][j], cmd, arg ); + bin_command( &setup->tile[i][j], cmd, arg ); } @@ -382,6 +382,19 @@ lp_setup_clear( struct setup_context *setup, } + +void +lp_setup_set_tri_state( struct setup_context *setup, + unsigned cull_mode, + boolean ccw_is_frontface) +{ + setup->ccw_is_frontface = ccw_is_frontface; + setup->cullmode = cull_mode; + setup->triangle = first_triangle; +} + + + void lp_setup_set_fs_inputs( struct setup_context *setup, const struct lp_shader_input *input, @@ -432,6 +445,14 @@ lp_setup_tri(struct setup_context *setup, void lp_setup_destroy( struct setup_context *setup ) { + unsigned i, j; + + reset_context( setup ); + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) + FREE(setup->tile[i][j].head); + lp_rast_destroy( setup->rast ); FREE( setup ); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 7410ac70b8..9411f14cfb 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -83,6 +83,9 @@ struct setup_context { unsigned tiles_x; unsigned tiles_y; + + boolean ccw_is_frontface; + unsigned cullmode; struct { struct pipe_surface *cbuf; @@ -147,9 +150,9 @@ static INLINE void *get_data( struct data_block_list *list, /* Add a command to a given bin. */ -static INLINE void bin_cmd( struct cmd_block_list *list, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg *arg ) +static INLINE void bin_command( struct cmd_block_list *list, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg *arg ) { if (list->tail->count == CMD_BLOCK_MAX) { lp_setup_new_cmd_block( list ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c new file mode 100644 index 0000000000..feea79d394 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Binning code for lines + */ + +#include "lp_setup_context.h" + +static void line_nop( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4] ) +{ +} + + +void +lp_setup_choose_line( struct setup_context *setup ) +{ + setup->line = line_nop; +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c new file mode 100644 index 0000000000..f03ca729b2 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -0,0 +1,46 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Binning code for points + */ + +#include "lp_setup_context.h" + +static void point_nop( struct setup_context *setup, + const float (*v0)[4] ) +{ +} + + +void +lp_setup_choose_point( struct setup_context *setup ) +{ + setup->point = point_nop; +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 382a52e951..d3b8ce9434 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -30,6 +30,7 @@ */ #include "lp_setup_context.h" +#include "lp_rast.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -263,10 +264,9 @@ do_triangle_ccw(struct setup_context *setup, const float x2 = subpixel_snap(v2[0][0]); const float x3 = subpixel_snap(v3[0][0]); - struct lp_setup_triangle *tri = get_data( setup, sizeof *tri ); + struct lp_rast_triangle *tri = get_data( &setup->data, sizeof *tri ); float area; float c1, c2, c3; - int i; int minx, maxx, miny, maxy; tri->dx12 = x1 - x2; @@ -363,7 +363,7 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - bin_command(setup->tile[minx][miny], lp_rast_triangle, tri ); + bin_command( &setup->tile[minx][miny], lp_rast_triangle, tri ); } else { @@ -412,12 +412,12 @@ do_triangle_ccw(struct setup_context *setup, cx3 + ei3 > 0) { /* shade whole tile */ - bin_command(setup->tile[x][y], lp_rast_shade_tile, &tri->inputs ); + bin_command( &setup->tile[x][y], lp_rast_shade_tile, &tri->inputs ); } else { /* shade partial tile */ - bin_command(setup->tile[x][y], lp_rast_triangle, tri ); + bin_command( &setup->tile[x][y], lp_rast_triangle, tri ); } /* Iterate cx values across the region: @@ -477,13 +477,11 @@ static void triangle_nop( struct setup_context *setup, { } -void setup_set_tri_state( struct setup_context *setup, - unsigned cull_mode, - boolean ccw_is_frontface) -{ - setup->ccw_is_frontface = ccw_is_frontface; - switch (cull_mode) { +void +lp_setup_choose_triangle( struct setup_context *setup ) +{ + switch (setup->cull_mode) { case PIPE_WINDING_NONE: setup->triangle = triangle_both; break; -- cgit v1.2.3 From 4cdd10cb4b60d85f6c231a26739f7d5e264a05e5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 11:29:01 +0100 Subject: llvmpipe: use union lp_cmd_rast_arg directly, rather than through a pointer The union itself consists of pointers. We don't need to be passing pointer to pointers. --- src/gallium/drivers/llvmpipe/lp_rast.c | 21 ++++----- src/gallium/drivers/llvmpipe/lp_rast.h | 54 +++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 4 +- src/gallium/drivers/llvmpipe/lp_setup.c | 63 ++++++++++--------------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 6 +-- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 17 +++++-- 6 files changed, 98 insertions(+), 67 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 9825099c94..de15ddbb2e 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -87,9 +87,9 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, } void lp_rast_clear_color( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg arg ) { - const uint8_t *clear_color = arg->clear_color; + const uint8_t *clear_color = arg.clear_color; if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && @@ -106,25 +106,24 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, } void lp_rast_clear_zstencil( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg) + const union lp_rast_cmd_arg arg) { - const unsigned clear_zstencil = arg->clear_zstencil; unsigned i, j; for (i = 0; i < TILE_SIZE; i++) for (j = 0; j < TILE_SIZE; j++) - rast->tile.depth[i*TILE_SIZE + j] = clear_zstencil; + rast->tile.depth[i*TILE_SIZE + j] = arg.clear_zstencil; } void lp_rast_load_color( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg) + const union lp_rast_cmd_arg arg) { /* call u_tile func to load colors from surface */ } void lp_rast_load_zstencil( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg arg ) { /* call u_tile func to load depth (and stencil?) from surface */ } @@ -132,17 +131,17 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, /* Within a tile: */ void lp_rast_set_state( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg arg ) { - rast->shader_state = arg->set_state; + rast->shader_state = arg.set_state; } void lp_rast_shade_tile( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg, - const struct lp_rast_shader_inputs *inputs ) + const union lp_rast_cmd_arg arg ) { + const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const unsigned masks[4] = {~0, ~0, ~0, ~0}; unsigned x, y; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index aa50fba5a6..44cb4032da 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -134,34 +134,70 @@ union lp_rast_cmd_arg { const struct lp_rast_shader_inputs *shade_tile; const struct lp_rast_triangle *triangle; const struct lp_rast_state *set_state; - const uint8_t clear_color[4]; + uint8_t clear_color[4]; unsigned clear_zstencil; }; +/* Cast wrappers. Hopefully these compile to noops! + */ +static INLINE const union lp_rast_cmd_arg +lp_rast_arg_inputs( const struct lp_rast_shader_inputs *shade_tile ) +{ + union lp_rast_cmd_arg arg; + arg.shade_tile = shade_tile; + return arg; +} + +static INLINE const union lp_rast_cmd_arg +lp_rast_arg_triangle( const struct lp_rast_triangle *triangle ) +{ + union lp_rast_cmd_arg arg; + arg.triangle = triangle; + return arg; +} + +static INLINE const union lp_rast_cmd_arg +lp_rast_arg_state( const struct lp_rast_state *state ) +{ + union lp_rast_cmd_arg arg; + arg.set_state = state; + return arg; +} + +static INLINE const union lp_rast_cmd_arg +lp_rast_arg_null( void ) +{ + union lp_rast_cmd_arg arg; + arg.set_state = NULL; + return arg; +} + + + + /* Binnable Commands: */ void lp_rast_clear_color( struct lp_rasterizer *, - const union lp_rast_cmd_arg *); + const union lp_rast_cmd_arg ); void lp_rast_clear_zstencil( struct lp_rasterizer *, - const union lp_rast_cmd_arg *); + const union lp_rast_cmd_arg ); void lp_rast_load_color( struct lp_rasterizer *, - const union lp_rast_cmd_arg *); + const union lp_rast_cmd_arg ); void lp_rast_load_zstencil( struct lp_rasterizer *, - const union lp_rast_cmd_arg *); + const union lp_rast_cmd_arg ); void lp_rast_set_state( struct lp_rasterizer *, - const union lp_rast_cmd_arg * ); + const union lp_rast_cmd_arg ); void lp_rast_triangle( struct lp_rasterizer *, - const union lp_rast_cmd_arg * ); + const union lp_rast_cmd_arg ); void lp_rast_shade_tile( struct lp_rasterizer *, - const union lp_rast_cmd_arg *, - const struct lp_rast_shader_inputs *); + const union lp_rast_cmd_arg ); /* End of tile: diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 8cd3fcc360..efc635bffe 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -155,9 +155,9 @@ do_block( struct lp_rasterizer *rast, * for this triangle: */ void lp_rast_triangle( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg arg ) { - const struct lp_rast_triangle *tri = arg->triangle; + const struct lp_rast_triangle *tri = arg.triangle; int minx, maxx, miny, maxy; /* Clamp to tile dimensions: diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 13b40f1494..c0c294fbe3 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -143,7 +143,7 @@ static void reset_context( struct setup_context *setup ) */ static void bin_everywhere( struct setup_context *setup, lp_rast_cmd cmd, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg arg ) { unsigned i, j; for (i = 0; i < setup->tiles_x; i++) @@ -232,18 +232,18 @@ begin_binning( struct setup_context *setup ) if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, lp_rast_clear_color, - &setup->clear.color ); + setup->clear.color ); else - bin_everywhere( setup, lp_rast_load_color, NULL ); + bin_everywhere( setup, lp_rast_load_color, lp_rast_arg_null() ); } if (setup->fb.zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) bin_everywhere( setup, lp_rast_clear_zstencil, - &setup->clear.zstencil ); + setup->clear.zstencil ); else - bin_everywhere( setup, lp_rast_load_zstencil, NULL ); + bin_everywhere( setup, lp_rast_load_zstencil, lp_rast_arg_null() ); } } @@ -329,32 +329,34 @@ lp_setup_clear( struct setup_context *setup, unsigned stencil, unsigned flags ) { + if (flags & PIPE_CLEAR_COLOR) { + util_pack_color(color, + setup->fb.cbuf->format, + &setup->clear.color.clear_color ); + } + + if (flags & PIPE_CLEAR_DEPTHSTENCIL) { + setup->clear.zstencil.clear_zstencil = + util_pack_z_stencil(setup->fb.zsbuf->format, + depth, + stencil); + } + if (setup->state == SETUP_ACTIVE) { /* Add the clear to existing bins. In the unusual case where * both color and depth-stencilare being cleared, we could * discard the currently binned scene and start again, but I * don't see that as being a common usage. */ - if (flags & PIPE_CLEAR_COLOR) { - union lp_rast_cmd_arg *arg = get_data( &setup->data, sizeof *arg ); - - util_pack_color(color, - setup->fb.cbuf->format, - &arg->clear_color ); - - bin_everywhere(setup, lp_rast_clear_color, arg ); - } - - if (flags & PIPE_CLEAR_DEPTHSTENCIL) { - union lp_rast_cmd_arg *arg = get_data( &setup->data, sizeof *arg ); + if (flags & PIPE_CLEAR_COLOR) + bin_everywhere( setup, + lp_rast_clear_color, + setup->clear.color ); - arg->clear_zstencil = - util_pack_z_stencil(setup->fb.zsbuf->format, - depth, - stencil); - - bin_everywhere(setup, lp_rast_clear_zstencil, arg ); - } + if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) + bin_everywhere( setup, + lp_rast_clear_zstencil, + setup->clear.zstencil ); } else { /* Put ourselves into the 'pre-clear' state, specifically to try @@ -365,19 +367,6 @@ lp_setup_clear( struct setup_context *setup, set_state( setup, SETUP_CLEARED ); setup->clear.flags |= flags; - - if (flags & PIPE_CLEAR_COLOR) { - util_pack_color(color, - setup->fb.cbuf->format, - &setup->clear.color.clear_color ); - } - - if (flags & PIPE_CLEAR_DEPTHSTENCIL) { - setup->clear.zstencil.clear_zstencil = - util_pack_z_stencil(setup->fb.zsbuf->format, - depth, - stencil); - } } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 9411f14cfb..b29fec8ef0 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -45,11 +45,11 @@ /* switch to a non-pointer value for this: */ -typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg * ); +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg ); struct cmd_block { lp_rast_cmd cmd[CMD_BLOCK_MAX]; - const union lp_rast_cmd_arg *arg[CMD_BLOCK_MAX]; + union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; unsigned count; struct cmd_block *next; }; @@ -152,7 +152,7 @@ static INLINE void *get_data( struct data_block_list *list, */ static INLINE void bin_command( struct cmd_block_list *list, lp_rast_cmd cmd, - const union lp_rast_cmd_arg *arg ) + union lp_rast_cmd_arg arg ) { if (list->tail->count == CMD_BLOCK_MAX) { lp_setup_new_cmd_block( list ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index d3b8ce9434..f927f9df91 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -230,7 +230,10 @@ static inline float subpixel_snap( float a ) } - +static INLINE void bin_triangle( struct cmd_block_list *list, + const struct lp_rast_triangle arg ) +{ +} /* to avoid having to allocate power-of-four, square render targets, @@ -363,7 +366,8 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - bin_command( &setup->tile[minx][miny], lp_rast_triangle, tri ); + bin_command( &setup->tile[minx][miny], lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } else { @@ -412,12 +416,15 @@ do_triangle_ccw(struct setup_context *setup, cx3 + ei3 > 0) { /* shade whole tile */ - bin_command( &setup->tile[x][y], lp_rast_shade_tile, &tri->inputs ); + bin_command( &setup->tile[x][y], lp_rast_shade_tile, + lp_rast_arg_inputs(&tri->inputs) ); } else { /* shade partial tile */ - bin_command( &setup->tile[x][y], lp_rast_triangle, tri ); + bin_command( &setup->tile[x][y], + lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } /* Iterate cx values across the region: @@ -481,7 +488,7 @@ static void triangle_nop( struct setup_context *setup, void lp_setup_choose_triangle( struct setup_context *setup ) { - switch (setup->cull_mode) { + switch (setup->cullmode) { case PIPE_WINDING_NONE: setup->triangle = triangle_both; break; -- cgit v1.2.3 From e215f94f15fd20919cc0ed500dc2efde4f076516 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 12:19:49 +0100 Subject: llvmpipe: get lp_setup_tri building --- src/gallium/drivers/llvmpipe/lp_rast.h | 14 +++++++++-- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 37 +++++++++++++++++------------ src/gallium/drivers/llvmpipe/lp_setup.c | 6 ++--- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 12 +++++----- 4 files changed, 43 insertions(+), 26 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 44cb4032da..72f897503d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -77,6 +77,11 @@ struct lp_rast_shader_inputs { * plus inputs to run the shader: */ struct lp_rast_triangle { + int minx; + int maxx; + int miny; + int maxy; + /* one-pixel sized trivial accept offsets for each plane */ float ei1; float ei2; @@ -97,8 +102,13 @@ struct lp_rast_triangle { float dx23; float dx31; - /* XXX: these are only used inside lp_setup_tri.c, don't really - * need to bin them: + /* edge function values at minx,miny ?? */ + float c1; + float c2; + float c3; + + /* XXX: this is only used inside lp_setup_tri.c, don't really + * need it here: */ float oneoverarea; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index efc635bffe..7110afb9d5 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -158,21 +158,6 @@ void lp_rast_triangle( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { const struct lp_rast_triangle *tri = arg.triangle; - int minx, maxx, miny, maxy; - - /* Clamp to tile dimensions: - */ - minx = MAX2(tri->maxx, rast->x); - miny = MAX2(tri->miny, rast->y); - maxx = MIN2(tri->maxx, rast->x + TILE_SIZE); - maxy = MIN2(tri->maxy, rast->y + TILE_SIZE); - - if (miny == maxy || - minx == maxx) { - debug_printf("%s: non-intersecting triangle in bin\n", __FUNCTION__); - //assert(0); - return; - } const int step = BLOCKSIZE; @@ -191,11 +176,33 @@ void lp_rast_triangle( struct lp_rasterizer *rast, float ystep1 = step * tri->dx12; float ystep2 = step * tri->dx23; float ystep3 = step * tri->dx31; + + /* Clamp to tile dimensions: + */ + int minx = MAX2(tri->maxx, rast->x); + int miny = MAX2(tri->miny, rast->y); + int maxx = MIN2(tri->maxx, rast->x + TILE_SIZE); + int maxy = MIN2(tri->maxy, rast->y + TILE_SIZE); + int x, y; + float x0, y0; + float c1, c2, c3; + + if (miny == maxy || minx == maxx) { + debug_printf("%s: non-intersecting triangle in bin\n", __FUNCTION__); + return; + } minx &= ~(step-1); miny &= ~(step-1); + x0 = (float)minx; + y0 = (float)miny; + + c1 = tri->c1 + tri->dx12 * y0 - tri->dy12 * x0; + c2 = tri->c2 + tri->dx23 * y0 - tri->dy23 * x0; + c3 = tri->c3 + tri->dx31 * y0 - tri->dy31 * x0; + for (y = miny; y < maxy; y += step) { float cx1 = c1; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c0c294fbe3..56bbee1f7c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -373,9 +373,9 @@ lp_setup_clear( struct setup_context *setup, void -lp_setup_set_tri_state( struct setup_context *setup, - unsigned cull_mode, - boolean ccw_is_frontface) +lp_setup_set_triangle_state( struct setup_context *setup, + unsigned cull_mode, + boolean ccw_is_frontface) { setup->ccw_is_frontface = ccw_is_frontface; setup->cullmode = cull_mode; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index f927f9df91..5c402259df 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -315,9 +315,9 @@ do_triangle_ccw(struct setup_context *setup, /* half-edge constants, will be interated over the whole * rendertarget. */ - c1 = tri->dy12 * x1 - tri->dx12 * y1; - c2 = tri->dy23 * x2 - tri->dx23 * y2; - c3 = tri->dy31 * x3 - tri->dx31 * y3; + tri->c1 = tri->dy12 * x1 - tri->dx12 * y1; + tri->c2 = tri->dy23 * x2 - tri->dx23 * y2; + tri->c3 = tri->dy31 * x3 - tri->dx31 * y3; /* correct for top-left fill convention: */ @@ -351,9 +351,9 @@ do_triangle_ccw(struct setup_context *setup, 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; + c1 = tri->c1 + tri->dx12 * miny - tri->dy12 * minx; + c2 = tri->c2 + tri->dx23 * miny - tri->dy23 * minx; + c3 = tri->c3 + tri->dx31 * miny - tri->dy31 * minx; /* Convert to tile coordinates: */ -- cgit v1.2.3 From d904ed88c1d957f662497343de7dc3e9fa743e47 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 13:41:33 +0100 Subject: llvmpipe: Pass state to setup. --- src/gallium/drivers/llvmpipe/lp_context.h | 3 +- src/gallium/drivers/llvmpipe/lp_setup.c | 99 +++++++++++++++++++++++-- src/gallium/drivers/llvmpipe/lp_setup.h | 23 +++++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 5 ++ src/gallium/drivers/llvmpipe/lp_state.h | 1 + src/gallium/drivers/llvmpipe/lp_state_blend.c | 18 ++--- src/gallium/drivers/llvmpipe/lp_state_derived.c | 18 +++++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 7 +- src/gallium/drivers/llvmpipe/lp_state_sampler.c | 10 --- 9 files changed, 150 insertions(+), 34 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index e34385bbae..17c6939ff5 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -59,7 +59,7 @@ struct llvmpipe_context { const struct lp_vertex_shader *vs; /** Other rendering state */ - struct pipe_blend_color blend_color[4][16]; + struct pipe_blend_color blend_color; struct pipe_clip_state clip; struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; @@ -120,7 +120,6 @@ struct llvmpipe_context { unsigned tex_timestamp; boolean no_rast; - struct lp_jit_context jit_context; }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 56bbee1f7c..f999004a66 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -32,11 +32,15 @@ * lp_setup_flush(). */ -#include "lp_setup_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_pack_color.h" -#include "pipe/p_defines.h" +#include "lp_state.h" +#include "lp_buffer.h" +#include "lp_texture.h" +#include "lp_setup_context.h" static void set_state( struct setup_context *, unsigned ); @@ -394,14 +398,99 @@ lp_setup_set_fs_inputs( struct setup_context *setup, } void -lp_setup_set_shader_state( struct setup_context *setup, - const struct lp_jit_context *jc ) +lp_setup_set_fs( struct setup_context *setup, + struct lp_fragment_shader *fs ) { - + /* FIXME: reference count */ + + setup->fs.jit_function = fs->current->jit_function; } +void +lp_setup_set_fs_constants(struct setup_context *setup, + struct pipe_buffer *buffer) +{ + const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; + struct pipe_buffer *dummy; + /* FIXME: hold on to the reference */ + dummy = NULL; + pipe_buffer_reference(&dummy, buffer); + setup->fs.jit_context.constants = data; + + setup->fs.jit_context_dirty = TRUE; +} + + +void +lp_setup_set_alpha_ref_value( struct setup_context *setup, + float alpha_ref_value ) +{ + if(setup->fs.jit_context.alpha_ref_value != alpha_ref_value) { + setup->fs.jit_context.alpha_ref_value = alpha_ref_value; + setup->fs.jit_context_dirty = TRUE; + } +} + +void +lp_setup_set_blend_color( struct setup_context *setup, + const struct pipe_blend_color *blend_color ) +{ + unsigned i, j; + + if(!setup->fs.jit_context.blend_color) + setup->fs.jit_context.blend_color = align_malloc(4 * 16, 16); + + for (i = 0; i < 4; ++i) { + uint8_t c = float_to_ubyte(blend_color->color[i]); + for (j = 0; j < 16; ++j) + setup->fs.jit_context.blend_color[i*4 + j] = c; + } + + setup->fs.jit_context_dirty = TRUE; +} + +void +lp_setup_set_sampler_textures( struct setup_context *setup, + unsigned num, struct pipe_texture **texture) +{ + struct pipe_texture *dummy; + unsigned i; + + assert(num <= PIPE_MAX_SAMPLERS); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + /* FIXME: hold on to the reference */ + dummy = NULL; + pipe_texture_reference(&dummy, tex); + + if(tex) { + struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); + struct lp_jit_texture *jit_tex = &setup->fs.jit_context.textures[i]; + jit_tex->width = tex->width[0]; + jit_tex->height = tex->height[0]; + jit_tex->stride = lp_tex->stride[0]; + if(!lp_tex->dt) + jit_tex->data = lp_tex->data; + else + /* FIXME: map the rendertarget */ + assert(0); + } + } + + setup->fs.jit_context_dirty = TRUE; +} + +static void +lp_setup_set_shader_state( struct setup_context *setup, + const struct lp_jit_context *jc ) +{ + + +} /* Stubs for lines & points for now: diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index bd439fa857..ac9c3cc0ee 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -50,7 +50,9 @@ struct lp_shader_input { struct pipe_texture; struct pipe_surface; +struct pipe_blend_color; struct setup_context; +struct lp_fragment_shader; struct lp_jit_context; struct setup_context * @@ -100,8 +102,25 @@ lp_setup_set_fs_inputs( struct setup_context *setup, unsigned nr ); void -lp_setup_set_shader_state( struct setup_context *setup, - const struct lp_jit_context *jc ); +lp_setup_set_fs( struct setup_context *setup, + struct lp_fragment_shader *fs ); + +void +lp_setup_set_fs_constants(struct setup_context *setup, + struct pipe_buffer *buffer); + + +void +lp_setup_set_alpha_ref_value( struct setup_context *setup, + float alpha_ref_value ); + +void +lp_setup_set_blend_color( struct setup_context *setup, + const struct pipe_blend_color *blend_color ); + +void +lp_setup_set_sampler_textures( struct setup_context *setup, + unsigned num, struct pipe_texture **texture); boolean lp_setup_is_texture_referenced( struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index b29fec8ef0..2e2380dd80 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -109,6 +109,11 @@ struct setup_context { struct { struct lp_shader_input input[PIPE_MAX_ATTRIBS]; unsigned nr_inputs; + + struct lp_jit_context jit_context; + lp_jit_frag_func jit_function; + + boolean jit_context_dirty; } fs; void (*point)( struct setup_context *, diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index a9980d6f14..64fe3600f5 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -54,6 +54,7 @@ #define LP_NEW_VERTEX 0x1000 #define LP_NEW_VS 0x2000 #define LP_NEW_QUERY 0x4000 +#define LP_NEW_BLEND_COLOR 0x8000 struct tgsi_sampler; diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c index 3f03bd0057..48afe5f524 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c @@ -67,17 +67,16 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - unsigned i, j; + + if(!blend_color) + return; + + if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0) + return; memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color); - if(!llvmpipe->jit_context.blend_color) - llvmpipe->jit_context.blend_color = align_malloc(4 * 16, 16); - for (i = 0; i < 4; ++i) { - uint8_t c = float_to_ubyte(blend_color->color[i]); - for (j = 0; j < 16; ++j) - llvmpipe->jit_context.blend_color[i*4 + j] = c; - } + llvmpipe->dirty |= LP_NEW_BLEND_COLOR; } @@ -101,9 +100,6 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe, llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; - if(llvmpipe->depth_stencil) - llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value; - llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index b801f054a2..00903c8ef4 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -33,6 +33,7 @@ #include "draw/draw_private.h" #include "lp_context.h" #include "lp_screen.h" +#include "lp_setup.h" #include "lp_state.h" @@ -256,6 +257,23 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) LP_NEW_TEXTURE)) llvmpipe_update_fs( llvmpipe ); + if (llvmpipe->dirty & (LP_NEW_BLEND | + LP_NEW_DEPTH_STENCIL_ALPHA | + LP_NEW_SAMPLER | + LP_NEW_TEXTURE)) + llvmpipe_update_fs( llvmpipe ); + + if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) + lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); + + if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) + lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); + + if (llvmpipe->dirty & LP_NEW_CONSTANTS) + lp_setup_set_fs_constants(llvmpipe->setup, llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer); + + if (llvmpipe->dirty & LP_NEW_TEXTURE) + lp_setup_set_sampler_textures(llvmpipe->setup, llvmpipe->num_textures, llvmpipe->texture); llvmpipe->dirty = 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 59c7afc6f7..63e675e584 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -681,16 +681,15 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, assert(shader < PIPE_SHADER_TYPES); assert(index == 0); + if(llvmpipe->constants[shader].buffer == buffer) + return; + if(shader == PIPE_SHADER_VERTEX) draw_flush(llvmpipe->draw); /* note: reference counting */ pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer); - if(shader == PIPE_SHADER_FRAGMENT) { - llvmpipe->jit_context.constants = data; - } - if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, data, size); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index ae787801eb..e19394a4c9 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -96,16 +96,6 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&llvmpipe->texture[i], tex); - - if(tex) { - struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); - struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i]; - jit_tex->width = tex->width[0]; - jit_tex->height = tex->height[0]; - jit_tex->stride = lp_tex->stride[0]; - if(!lp_tex->dt) - jit_tex->data = lp_tex->data; - } } llvmpipe->num_textures = num; -- cgit v1.2.3 From c0e3e35b03e6cbed3768cb56e298b6119eafe1ef Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 13:44:24 +0100 Subject: llvmpipe: Add stub lp_setup_is_texture_referenced. --- src/gallium/drivers/llvmpipe/lp_setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index f999004a66..0a12d93c38 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -484,6 +484,15 @@ lp_setup_set_sampler_textures( struct setup_context *setup, setup->fs.jit_context_dirty = TRUE; } +boolean +lp_setup_is_texture_referenced( struct setup_context *setup, + const struct pipe_texture *texture ) +{ + /* FIXME */ + return PIPE_UNREFERENCED; +} + + static void lp_setup_set_shader_state( struct setup_context *setup, const struct lp_jit_context *jc ) -- cgit v1.2.3 From 1928c965b1fb76987cbc834111bd1d1e1f2cda51 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 13:53:14 +0100 Subject: llvmpipe: fix a couple of warnings --- src/gallium/drivers/llvmpipe/lp_setup.c | 9 --------- src/gallium/drivers/llvmpipe/lp_setup.h | 1 + 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 0a12d93c38..030a19ef30 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -493,15 +493,6 @@ lp_setup_is_texture_referenced( struct setup_context *setup, } -static void -lp_setup_set_shader_state( struct setup_context *setup, - const struct lp_jit_context *jc ) -{ - - -} - - /* Stubs for lines & points for now: */ void diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index ac9c3cc0ee..0dedc9e9fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -50,6 +50,7 @@ struct lp_shader_input { struct pipe_texture; struct pipe_surface; +struct pipe_buffer; struct pipe_blend_color; struct setup_context; struct lp_fragment_shader; -- cgit v1.2.3 From b0475a4b0d1eaa1179bc399301ed46b0b8e63497 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 13:55:04 +0100 Subject: llvmpipe: fix crash on init --- src/gallium/drivers/llvmpipe/lp_setup.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 030a19ef30..2eef63badc 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -229,8 +229,8 @@ begin_binning( struct setup_context *setup ) setup->fb.zsbuf->height); } - setup->tiles_x = align(setup->fb.width, TILESIZE); - setup->tiles_y = align(setup->fb.height, TILESIZE); + setup->tiles_x = align(setup->fb.width, TILESIZE) / TILESIZE; + setup->tiles_y = align(setup->fb.height, TILESIZE) / TILESIZE; if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) @@ -312,18 +312,10 @@ lp_setup_bind_framebuffer( struct setup_context *setup, struct pipe_surface *color, struct pipe_surface *zstencil ) { - unsigned width, height; - set_state( setup, SETUP_FLUSHED ); pipe_surface_reference( &setup->fb.cbuf, color ); pipe_surface_reference( &setup->fb.zsbuf, zstencil ); - - width = MAX2( color->width, zstencil->width ); - height = MAX2( color->height, zstencil->height ); - - setup->tiles_x = align( width, TILESIZE ) / TILESIZE; - setup->tiles_y = align( height, TILESIZE ) / TILESIZE; } void -- cgit v1.2.3 From 4e1334ced68dd25b151250a44af25e8e0d5a33fe Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 14:02:39 +0100 Subject: llvmpipe: debug, crash fixes --- src/gallium/drivers/llvmpipe/lp_rast.c | 28 +++++++++++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_setup.c | 6 ------ 2 files changed, 27 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index de15ddbb2e..fff292e294 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -33,6 +33,7 @@ #include "lp_tile_soa.h" #include "lp_bld_debug.h" +#define RAST_DEBUG debug_printf struct lp_rasterizer *lp_rast_create( void ) { @@ -53,6 +54,8 @@ void lp_rast_begin( struct lp_rasterizer *rast, unsigned width, unsigned height ) { + RAST_DEBUG("%s %dx%d\n", __FUNCTION__, width, height); + rast->width = width; rast->height = height; rast->check_for_clipped_tiles = (width % TILESIZE != 0 || @@ -63,6 +66,8 @@ void lp_rast_bind_color( struct lp_rasterizer *rast, struct pipe_surface *cbuf, boolean write_color ) { + RAST_DEBUG("%s\n", __FUNCTION__); + pipe_surface_reference(&rast->state.cbuf, cbuf); rast->state.write_color = write_color; } @@ -71,6 +76,8 @@ void lp_rast_bind_zstencil( struct lp_rasterizer *rast, struct pipe_surface *zsbuf, boolean write_zstencil ) { + RAST_DEBUG("%s\n", __FUNCTION__); + pipe_surface_reference(&rast->state.zsbuf, zsbuf); rast->state.write_zstencil = write_zstencil; } @@ -82,6 +89,8 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, unsigned x, unsigned y ) { + RAST_DEBUG("%s\n", __FUNCTION__); + rast->x = x; rast->y = y; } @@ -91,6 +100,8 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, { const uint8_t *clear_color = arg.clear_color; + RAST_DEBUG("%s\n", __FUNCTION__); + if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && clear_color[2] == clear_color[3]) { @@ -110,6 +121,8 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, { unsigned i, j; + RAST_DEBUG("%s\n", __FUNCTION__); + for (i = 0; i < TILE_SIZE; i++) for (j = 0; j < TILE_SIZE; j++) rast->tile.depth[i*TILE_SIZE + j] = arg.clear_zstencil; @@ -119,12 +132,16 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, void lp_rast_load_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg) { + RAST_DEBUG("%s\n", __FUNCTION__); + /* call u_tile func to load colors from surface */ } void lp_rast_load_zstencil( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { + RAST_DEBUG("%s\n", __FUNCTION__); + /* call u_tile func to load depth (and stencil?) from surface */ } @@ -133,8 +150,9 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, void lp_rast_set_state( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { - rast->shader_state = arg.set_state; + RAST_DEBUG("%s\n", __FUNCTION__); + rast->shader_state = arg.set_state; } @@ -145,6 +163,8 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, const unsigned masks[4] = {~0, ~0, ~0, ~0}; unsigned x, y; + RAST_DEBUG("%s\n", __FUNCTION__); + /* Use the existing preference for 8x2 (four quads) shading: */ for (y = 0; y < TILE_SIZE; y += 2) @@ -218,6 +238,8 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) unsigned h = TILE_SIZE; void *map; + RAST_DEBUG("%s\n", __FUNCTION__); + surface = rast->state.cbuf; if(!surface) return; @@ -256,12 +278,16 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) { + RAST_DEBUG("%s\n", __FUNCTION__); + /* FIXME: call u_tile func to store depth/stencil to surface */ } void lp_rast_end_tile( struct lp_rasterizer *rast ) { + RAST_DEBUG("%s\n", __FUNCTION__); + if (rast->state.write_color) lp_rast_store_color(rast); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 2eef63badc..009c641976 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -164,12 +164,6 @@ rasterize_bins( struct setup_context *setup, struct cmd_block *block; unsigned i,j,k; - if (setup->state != SETUP_ACTIVE) { - /* this can happen, not a big deal */ - debug_printf("%s called when not binning\n", __FUNCTION__); - return; - } - lp_rast_begin( rast, setup->fb.width, setup->fb.height ); -- cgit v1.2.3 From 659609e0ae27071a601794935c85547e315dedeb Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 14:03:11 +0100 Subject: llvmpipe: Replace util_pack_color with straight float_to_ubyte. --- src/gallium/drivers/llvmpipe/lp_setup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 009c641976..ec1027bb40 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -319,10 +319,11 @@ lp_setup_clear( struct setup_context *setup, unsigned stencil, unsigned flags ) { + unsigned i; + if (flags & PIPE_CLEAR_COLOR) { - util_pack_color(color, - setup->fb.cbuf->format, - &setup->clear.color.clear_color ); + for (i = 0; i < 4; ++i) + setup->clear.color.clear_color[i] = float_to_ubyte(color[i]); } if (flags & PIPE_CLEAR_DEPTHSTENCIL) { -- cgit v1.2.3 From e0e2008f1dcd73a59a184e0ef4c1dd77ac2a1cbf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 14:29:25 +0100 Subject: llvmpipe: trivial/clear works --- src/gallium/drivers/llvmpipe/lp_context.c | 2 +- src/gallium/drivers/llvmpipe/lp_rast.c | 120 ++++++++++++++-------------- src/gallium/drivers/llvmpipe/lp_rast.h | 21 +++-- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 11 ++- src/gallium/drivers/llvmpipe/lp_setup.c | 16 ++-- src/gallium/drivers/llvmpipe/lp_setup.h | 3 +- 6 files changed, 92 insertions(+), 81 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 7f7b04412c..06aa032540 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -179,7 +179,7 @@ llvmpipe_create( struct pipe_screen *screen ) if (debug_get_bool_option( "LP_NO_RAST", FALSE )) llvmpipe->no_rast = TRUE; - llvmpipe->setup = lp_setup_create(); + llvmpipe->setup = lp_setup_create( screen ); if (!llvmpipe->setup) goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index beb149ef18..977f35c46c 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -35,7 +35,7 @@ #define RAST_DEBUG debug_printf -struct lp_rasterizer *lp_rast_create( void ) +struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) { struct lp_rasterizer *rast; @@ -43,6 +43,7 @@ struct lp_rasterizer *lp_rast_create( void ) if(!rast) return NULL; + rast->screen = screen; rast->tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); rast->tile.depth = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); @@ -50,39 +51,75 @@ struct lp_rasterizer *lp_rast_create( void ) } -void lp_rast_begin( struct lp_rasterizer *rast, - unsigned width, - unsigned height ) +boolean lp_rast_begin( struct lp_rasterizer *rast, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf, + boolean write_color, + boolean write_zstencil, + unsigned width, + unsigned height ) { + struct pipe_screen *screen = rast->screen; + RAST_DEBUG("%s %dx%d\n", __FUNCTION__, width, height); + pipe_surface_reference(&rast->state.cbuf, cbuf); + pipe_surface_reference(&rast->state.zsbuf, zsbuf); + rast->width = width; rast->height = height; + rast->state.write_zstencil = write_zstencil; + rast->state.write_color = write_color; + rast->check_for_clipped_tiles = (width % TILESIZE != 0 || height % TILESIZE != 0); -} -void lp_rast_bind_color( struct lp_rasterizer *rast, - struct pipe_surface *cbuf, - boolean write_color ) -{ - RAST_DEBUG("%s\n", __FUNCTION__); + if (cbuf) { + rast->cbuf_transfer = screen->get_tex_transfer(rast->screen, + cbuf->texture, + cbuf->face, + cbuf->level, + cbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, width, height); + if (!rast->cbuf_transfer) + return FALSE; + + rast->cbuf_map = screen->transfer_map(rast->screen, + rast->cbuf_transfer); + if (!rast->cbuf_map) + return FALSE; + } - pipe_surface_reference(&rast->state.cbuf, cbuf); - rast->state.write_color = write_color; + return TRUE; } -void lp_rast_bind_zstencil( struct lp_rasterizer *rast, - struct pipe_surface *zsbuf, - boolean write_zstencil ) + +void lp_rast_end( struct lp_rasterizer *rast ) { - RAST_DEBUG("%s\n", __FUNCTION__); + struct pipe_screen *screen = rast->screen; - pipe_surface_reference(&rast->state.zsbuf, zsbuf); - rast->state.write_zstencil = write_zstencil; + if (rast->cbuf_map) + screen->transfer_unmap(screen, rast->cbuf_transfer); + + if (rast->zsbuf_map) + screen->transfer_unmap(screen, rast->zsbuf_transfer); + + if (rast->cbuf_transfer) + screen->tex_transfer_destroy(rast->cbuf_transfer); + + if (rast->zsbuf_transfer) + screen->tex_transfer_destroy(rast->cbuf_transfer); + + rast->cbuf_transfer = NULL; + rast->zsbuf_transfer = NULL; + rast->cbuf_map = NULL; + rast->zsbuf_map = NULL; } + + /* Begining of each tile: */ void lp_rast_start_tile( struct lp_rasterizer *rast, @@ -233,50 +270,17 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, static void lp_rast_store_color( struct lp_rasterizer *rast ) { - struct pipe_surface *surface; - struct pipe_screen *screen; - struct pipe_transfer *transfer; const unsigned x = rast->x; const unsigned y = rast->y; - unsigned w = TILE_SIZE; - unsigned h = TILE_SIZE; - void *map; - - RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); - - surface = rast->state.cbuf; - if(!surface) - return; - - screen = surface->texture->screen; - - if(x + w > rast->width) - w = rast->width - x; - if(y + h > rast->height) - h = rast->height - y; - - transfer = screen->get_tex_transfer(screen, - surface->texture, - surface->face, - surface->level, - surface->zslice, - PIPE_TRANSFER_READ_WRITE, - x, y, w, h); - if(!transfer) - return; - - map = screen->transfer_map(screen, transfer); - if(map) { - lp_tile_write_4ub(transfer->format, - rast->tile.color, - map, transfer->stride, - x, y, w, h); - - screen->transfer_unmap(screen, transfer); - } - screen->tex_transfer_destroy(transfer); + RAST_DEBUG("%s %d,%d\n", __FUNCTION__, x, y); + lp_tile_write_4ub(rast->cbuf_transfer->format, + rast->tile.color, + rast->cbuf_map, + rast->cbuf_transfer->stride, + x, y, + TILESIZE, TILESIZE); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 72f897503d..9dfdf25cda 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -37,6 +37,7 @@ * individual function calls like this. */ struct lp_rasterizer; +struct pipe_screen; #define TILESIZE 64 @@ -118,19 +119,17 @@ struct lp_rast_triangle { -struct lp_rasterizer *lp_rast_create( void ); +struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ); -void lp_rast_begin( struct lp_rasterizer *, - unsigned width, - unsigned height); +boolean lp_rast_begin( struct lp_rasterizer *rast, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf, + boolean write_color, + boolean write_zstencil, + unsigned width, + unsigned height ); -void lp_rast_bind_color( struct lp_rasterizer *, - struct pipe_surface *cbuf, - boolean write_when_done ); - -void lp_rast_bind_zstencil( struct lp_rasterizer *, - struct pipe_surface *zsbuf, - boolean write_when_done ); +void lp_rast_end( struct lp_rasterizer * ); /* Begining of each tile: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index f5a6699ed4..eae8138aaf 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -30,6 +30,8 @@ #include "lp_rast.h" +struct pipe_transfer; +struct pipe_screen; /* We can choose whatever layout for the internal tile storage we * prefer: @@ -49,7 +51,6 @@ struct lp_rasterizer { */ struct lp_rast_tile tile; - unsigned x; unsigned y; boolean clipped_tile; @@ -57,7 +58,13 @@ struct lp_rasterizer { boolean check_for_clipped_tiles; unsigned width; unsigned height; - + + struct pipe_screen *screen; + struct pipe_transfer *cbuf_transfer; + struct pipe_transfer *zsbuf_transfer; + void *cbuf_map; + void *zsbuf_map; + struct { struct pipe_surface *cbuf; struct pipe_surface *zsbuf; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ec1027bb40..ba9d801032 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -165,16 +165,14 @@ rasterize_bins( struct setup_context *setup, unsigned i,j,k; lp_rast_begin( rast, + setup->fb.cbuf, + setup->fb.zsbuf, + setup->fb.cbuf != NULL, + setup->fb.zsbuf != NULL && write_depth, setup->fb.width, setup->fb.height ); - lp_rast_bind_color( rast, - setup->fb.cbuf, - setup->fb.cbuf != NULL ); - lp_rast_bind_zstencil( rast, - setup->fb.zsbuf, - setup->fb.zsbuf != NULL && write_depth ); for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { @@ -193,6 +191,8 @@ rasterize_bins( struct setup_context *setup, } } + lp_rast_end( rast ); + reset_context( setup ); } @@ -528,12 +528,12 @@ lp_setup_destroy( struct setup_context *setup ) * rasterizer to use with it. */ struct setup_context * -lp_setup_create( void ) +lp_setup_create( struct pipe_screen *screen ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); unsigned i, j; - setup->rast = lp_rast_create(); + setup->rast = lp_rast_create( screen ); if (!setup->rast) goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 0dedc9e9fe..1edd7410fc 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -52,12 +52,13 @@ struct pipe_texture; struct pipe_surface; struct pipe_buffer; struct pipe_blend_color; +struct pipe_screen; struct setup_context; struct lp_fragment_shader; struct lp_jit_context; struct setup_context * -lp_setup_create( void ); +lp_setup_create( struct pipe_screen *screen ); void lp_setup_clear(struct setup_context *setup, -- cgit v1.2.3 From 608c22272327d3b554c7665b60f6322716e5fd9d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 14:30:25 +0100 Subject: llvmpipe: Put jit_context in store. --- src/gallium/drivers/llvmpipe/lp_setup.c | 26 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup_context.h | 2 ++ 2 files changed, 28 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ba9d801032..8a9c169634 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -480,12 +480,36 @@ lp_setup_is_texture_referenced( struct setup_context *setup, } +static INLINE void +lp_setup_update_shader_state( struct setup_context *setup ) +{ + + if(setup->fs.jit_context_dirty) { + if(!setup->fs.last_jc || + memcmp(setup->fs.last_jc, &setup->fs.jit_context, sizeof *setup->fs.last_jc)) { + struct lp_jit_context *jc; + + jc = get_data(&setup->data, sizeof *jc); + if(jc) { + memcpy(jc, &setup->fs.jit_context, sizeof *jc); + setup->fs.last_jc = jc; + } + } + + setup->fs.jit_context_dirty = FALSE; + } + + assert(setup->fs.last_jc); +} + + /* Stubs for lines & points for now: */ void lp_setup_point(struct setup_context *setup, const float (*v0)[4]) { + lp_setup_update_shader_state(setup); setup->point( setup, v0 ); } @@ -494,6 +518,7 @@ lp_setup_line(struct setup_context *setup, const float (*v0)[4], const float (*v1)[4]) { + lp_setup_update_shader_state(setup); setup->line( setup, v0, v1 ); } @@ -503,6 +528,7 @@ lp_setup_tri(struct setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { + lp_setup_update_shader_state(setup); setup->triangle( setup, v0, v1, v2 ); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 2e2380dd80..747e90fe20 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -114,6 +114,8 @@ struct setup_context { lp_jit_frag_func jit_function; boolean jit_context_dirty; + + const struct lp_jit_context *last_jc; } fs; void (*point)( struct setup_context *, -- cgit v1.2.3 From 163a31952c903034c8a70213b344e1b2ef287270 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 14:33:57 +0100 Subject: llvmpipe: initialize setup line/tri/point funcs --- src/gallium/drivers/llvmpipe/lp_setup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 8a9c169634..47839869ac 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -568,6 +568,10 @@ lp_setup_create( struct pipe_screen *screen ) setup->tile[i][j].head = setup->tile[i][j].tail = CALLOC_STRUCT(cmd_block); + setup->triangle = first_triangle; + setup->line = first_line; + setup->point = first_point; + return setup; fail: -- cgit v1.2.3 From 082b3b0a895615a60a7eae40fea14bf231960dba Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 14:36:41 +0100 Subject: llvmpipe: initialize setup data store --- src/gallium/drivers/llvmpipe/lp_setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 47839869ac..336a8b4e5b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -568,6 +568,9 @@ lp_setup_create( struct pipe_screen *screen ) setup->tile[i][j].head = setup->tile[i][j].tail = CALLOC_STRUCT(cmd_block); + setup->data.head = + setup->data.tail = CALLOC_STRUCT(data_block); + setup->triangle = first_triangle; setup->line = first_line; setup->point = first_point; -- cgit v1.2.3 From 402c189af7e95be99ba2e5fd71a71987ffd73c2f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 15:07:18 +0100 Subject: llvmpipe: always call begin_binning on transition to active state --- src/gallium/drivers/llvmpipe/lp_setup.c | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 336a8b4e5b..793b71e095 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -42,6 +42,8 @@ #include "lp_texture.h" #include "lp_setup_context.h" +#define SETUP_DEBUG debug_printf + static void set_state( struct setup_context *, unsigned ); void lp_setup_new_cmd_block( struct cmd_block_list *list ) @@ -97,6 +99,8 @@ static void reset_context( struct setup_context *setup ) { unsigned i, j; + SETUP_DEBUG("%s\n", __FUNCTION__); + /* Free binner command lists: */ for (i = 0; i < setup->tiles_x; i++) { @@ -164,6 +168,8 @@ rasterize_bins( struct setup_context *setup, struct cmd_block *block; unsigned i,j,k; + SETUP_DEBUG("%s\n", __FUNCTION__); + lp_rast_begin( rast, setup->fb.cbuf, setup->fb.zsbuf, @@ -201,6 +207,8 @@ rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + if (!setup->fb.cbuf && !setup->fb.zsbuf) { setup->fb.width = 0; setup->fb.height = 0; @@ -254,6 +262,8 @@ begin_binning( struct setup_context *setup ) static void execute_clears( struct setup_context *setup ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + begin_binning( setup ); rasterize_bins( setup, TRUE ); } @@ -268,10 +278,11 @@ set_state( struct setup_context *setup, if (old_state == new_state) return; + SETUP_DEBUG("%s old %d new %d\n", __FUNCTION__, old_state, new_state); + switch (new_state) { case SETUP_ACTIVE: - if (old_state == SETUP_FLUSHED) - begin_binning( setup ); + begin_binning( setup ); break; case SETUP_CLEARED: @@ -297,6 +308,8 @@ void lp_setup_flush( struct setup_context *setup, unsigned flags ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + set_state( setup, SETUP_FLUSHED ); } @@ -306,6 +319,8 @@ lp_setup_bind_framebuffer( struct setup_context *setup, struct pipe_surface *color, struct pipe_surface *zstencil ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + set_state( setup, SETUP_FLUSHED ); pipe_surface_reference( &setup->fb.cbuf, color ); @@ -321,6 +336,9 @@ lp_setup_clear( struct setup_context *setup, { unsigned i; + SETUP_DEBUG("%s state %d\n", __FUNCTION__, setup->state); + + if (flags & PIPE_CLEAR_COLOR) { for (i = 0; i < 4; ++i) setup->clear.color.clear_color[i] = float_to_ubyte(color[i]); @@ -368,6 +386,8 @@ lp_setup_set_triangle_state( struct setup_context *setup, unsigned cull_mode, boolean ccw_is_frontface) { + SETUP_DEBUG("%s\n", __FUNCTION__); + setup->ccw_is_frontface = ccw_is_frontface; setup->cullmode = cull_mode; setup->triangle = first_triangle; @@ -380,6 +400,8 @@ lp_setup_set_fs_inputs( struct setup_context *setup, const struct lp_shader_input *input, unsigned nr ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + memcpy( setup->fs.input, input, nr * sizeof input[0] ); setup->fs.nr_inputs = nr; } @@ -388,6 +410,7 @@ void lp_setup_set_fs( struct setup_context *setup, struct lp_fragment_shader *fs ) { + SETUP_DEBUG("%s\n", __FUNCTION__); /* FIXME: reference count */ setup->fs.jit_function = fs->current->jit_function; @@ -400,6 +423,8 @@ lp_setup_set_fs_constants(struct setup_context *setup, const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; struct pipe_buffer *dummy; + SETUP_DEBUG("%s\n", __FUNCTION__); + /* FIXME: hold on to the reference */ dummy = NULL; pipe_buffer_reference(&dummy, buffer); @@ -414,6 +439,8 @@ void lp_setup_set_alpha_ref_value( struct setup_context *setup, float alpha_ref_value ) { + SETUP_DEBUG("%s\n", __FUNCTION__); + if(setup->fs.jit_context.alpha_ref_value != alpha_ref_value) { setup->fs.jit_context.alpha_ref_value = alpha_ref_value; setup->fs.jit_context_dirty = TRUE; @@ -426,6 +453,8 @@ lp_setup_set_blend_color( struct setup_context *setup, { unsigned i, j; + SETUP_DEBUG("%s\n", __FUNCTION__); + if(!setup->fs.jit_context.blend_color) setup->fs.jit_context.blend_color = align_malloc(4 * 16, 16); @@ -445,6 +474,9 @@ lp_setup_set_sampler_textures( struct setup_context *setup, struct pipe_texture *dummy; unsigned i; + SETUP_DEBUG("%s\n", __FUNCTION__); + + assert(num <= PIPE_MAX_SAMPLERS); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { @@ -483,6 +515,7 @@ lp_setup_is_texture_referenced( struct setup_context *setup, static INLINE void lp_setup_update_shader_state( struct setup_context *setup ) { + SETUP_DEBUG("%s\n", __FUNCTION__); if(setup->fs.jit_context_dirty) { if(!setup->fs.last_jc || @@ -528,6 +561,8 @@ lp_setup_tri(struct setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { + SETUP_DEBUG("%s\n", __FUNCTION__); + lp_setup_update_shader_state(setup); setup->triangle( setup, v0, v1, v2 ); } -- cgit v1.2.3 From f406ffaea62005157f56ea17709291326c4dca8a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 15:29:10 +0100 Subject: llvmpipe: set block count/used values back to zero on reset --- src/gallium/drivers/llvmpipe/lp_setup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 793b71e095..03c54798dc 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -115,6 +115,7 @@ static void reset_context( struct setup_context *setup ) } list->head = list->tail; + list->head->count = 0; } } @@ -130,6 +131,7 @@ static void reset_context( struct setup_context *setup ) } list->head = list->tail; + list->head->used = 0; } /* Reset some state: -- cgit v1.2.3 From 85999695829823e459e11822b4846ed1db5c055d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 15:52:18 +0100 Subject: llvmpipe: Get jit_context/jit_function across the rasterizer. --- src/gallium/drivers/llvmpipe/lp_rast.c | 28 +++++-------- src/gallium/drivers/llvmpipe/lp_rast.h | 4 +- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 - src/gallium/drivers/llvmpipe/lp_setup.c | 53 ++++++++++++++----------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 9 ++--- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 2 + src/gallium/drivers/llvmpipe/lp_state_fs.c | 3 ++ 7 files changed, 50 insertions(+), 51 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 977f35c46c..cba50c8049 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -188,14 +188,6 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, /* Within a tile: */ -void lp_rast_set_state( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg arg ) -{ - RAST_DEBUG("%s\n", __FUNCTION__); - - rast->shader_state = arg.set_state; -} - void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) @@ -219,7 +211,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned x, unsigned y, const unsigned *masks) { - const struct lp_rast_state *state = rast->shader_state; + const struct lp_rast_state *state = inputs->state; struct lp_rast_tile *tile = &rast->tile; void *color; void *depth; @@ -249,17 +241,17 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, assert(lp_check_alignment(depth, 16)); assert(lp_check_alignment(color, 16)); - assert(lp_check_alignment(state->jc.blend_color, 16)); + assert(lp_check_alignment(state->jit_context.blend_color, 16)); /* run shader */ - state->shader( &state->jc, - x, y, - inputs->a0, - inputs->dadx, - inputs->dady, - &mask[0][0], - color, - depth); + state->jit_function( &state->jit_context, + x, y, + inputs->a0, + inputs->dadx, + inputs->dady, + &mask[0][0], + color, + depth); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 9dfdf25cda..f371b709df 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -45,12 +45,12 @@ struct pipe_screen; struct lp_rast_state { /* State for the shader: */ - struct lp_jit_context jc; + struct lp_jit_context jit_context; /* The shader itself. Probably we also need to pass a pointer to * the tile color/z/stencil data somehow: */ - lp_jit_frag_func shader; + lp_jit_frag_func jit_function; }; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index eae8138aaf..11e8e78e79 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -74,8 +74,6 @@ struct lp_rasterizer { unsigned clear_depth; char clear_stencil; } state; - - const struct lp_rast_state *shader_state; }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 03c54798dc..428d2d0085 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -415,7 +415,7 @@ lp_setup_set_fs( struct setup_context *setup, SETUP_DEBUG("%s\n", __FUNCTION__); /* FIXME: reference count */ - setup->fs.jit_function = fs->current->jit_function; + setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL; } void @@ -431,9 +431,9 @@ lp_setup_set_fs_constants(struct setup_context *setup, dummy = NULL; pipe_buffer_reference(&dummy, buffer); - setup->fs.jit_context.constants = data; + setup->fs.current.jit_context.constants = data; - setup->fs.jit_context_dirty = TRUE; + setup->fs.dirty = TRUE; } @@ -443,9 +443,9 @@ lp_setup_set_alpha_ref_value( struct setup_context *setup, { SETUP_DEBUG("%s\n", __FUNCTION__); - if(setup->fs.jit_context.alpha_ref_value != alpha_ref_value) { - setup->fs.jit_context.alpha_ref_value = alpha_ref_value; - setup->fs.jit_context_dirty = TRUE; + if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) { + setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value; + setup->fs.dirty = TRUE; } } @@ -457,16 +457,16 @@ lp_setup_set_blend_color( struct setup_context *setup, SETUP_DEBUG("%s\n", __FUNCTION__); - if(!setup->fs.jit_context.blend_color) - setup->fs.jit_context.blend_color = align_malloc(4 * 16, 16); + if(!setup->fs.current.jit_context.blend_color) + setup->fs.current.jit_context.blend_color = align_malloc(4 * 16, 16); for (i = 0; i < 4; ++i) { uint8_t c = float_to_ubyte(blend_color->color[i]); for (j = 0; j < 16; ++j) - setup->fs.jit_context.blend_color[i*4 + j] = c; + setup->fs.current.jit_context.blend_color[i*4 + j] = c; } - setup->fs.jit_context_dirty = TRUE; + setup->fs.dirty = TRUE; } void @@ -490,7 +490,8 @@ lp_setup_set_sampler_textures( struct setup_context *setup, if(tex) { struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); - struct lp_jit_texture *jit_tex = &setup->fs.jit_context.textures[i]; + struct lp_jit_texture *jit_tex; + jit_tex = &setup->fs.current.jit_context.textures[i]; jit_tex->width = tex->width[0]; jit_tex->height = tex->height[0]; jit_tex->stride = lp_tex->stride[0]; @@ -502,7 +503,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, } } - setup->fs.jit_context_dirty = TRUE; + setup->fs.dirty = TRUE; } boolean @@ -519,22 +520,28 @@ lp_setup_update_shader_state( struct setup_context *setup ) { SETUP_DEBUG("%s\n", __FUNCTION__); - if(setup->fs.jit_context_dirty) { - if(!setup->fs.last_jc || - memcmp(setup->fs.last_jc, &setup->fs.jit_context, sizeof *setup->fs.last_jc)) { - struct lp_jit_context *jc; - - jc = get_data(&setup->data, sizeof *jc); - if(jc) { - memcpy(jc, &setup->fs.jit_context, sizeof *jc); - setup->fs.last_jc = jc; + assert(setup->fs.current.jit_function); + + if(setup->fs.dirty) { + if(!setup->fs.stored || + memcmp(setup->fs.stored, + &setup->fs.current, + sizeof setup->fs.current) != 0) { + struct lp_rast_state *stored; + + stored = get_data(&setup->data, sizeof *stored); + if(stored) { + memcpy(stored, + &setup->fs.current, + sizeof setup->fs.current); + setup->fs.stored = stored; } } - setup->fs.jit_context_dirty = FALSE; + setup->fs.dirty = FALSE; } - assert(setup->fs.last_jc); + assert(setup->fs.stored); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 747e90fe20..c15a59e4d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -110,12 +110,9 @@ struct setup_context { struct lp_shader_input input[PIPE_MAX_ATTRIBS]; unsigned nr_inputs; - struct lp_jit_context jit_context; - lp_jit_frag_func jit_function; - - boolean jit_context_dirty; - - const struct lp_jit_context *last_jc; + const struct lp_rast_state *stored; + struct lp_rast_state current; + boolean dirty; } fs; void (*point)( struct setup_context *, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 857fb6a9f8..78e53292ec 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -272,6 +272,8 @@ do_triangle_ccw(struct setup_context *setup, float c1, c2, c3; int minx, maxx, miny, maxy; + tri->inputs.state = setup->fs.stored; + tri->dx12 = x1 - x2; tri->dx23 = x2 - x3; tri->dx31 = x3 - x1; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index a12581a486..0541d36580 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -84,6 +84,7 @@ #include "lp_screen.h" #include "lp_context.h" #include "lp_buffer.h" +#include "lp_setup.h" #include "lp_state.h" #include "lp_tex_sample.h" #include "lp_debug.h" @@ -765,4 +766,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) variant = generate_fragment(lp, shader, &key); shader->current = variant; + + lp_setup_set_fs(lp->setup, shader); } -- cgit v1.2.3 From 7908c239e0fdc11d878b8c68d126c3364af0ee24 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 19:17:30 +0100 Subject: llvmpipe: Additional checks for binner block lists. --- src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 428d2d0085..a74756de7c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -101,7 +101,7 @@ static void reset_context( struct setup_context *setup ) SETUP_DEBUG("%s\n", __FUNCTION__); - /* Free binner command lists: + /* Free all but last binner command lists: */ for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { @@ -114,12 +114,13 @@ static void reset_context( struct setup_context *setup ) FREE(block); } + assert(list->tail->next == NULL); list->head = list->tail; list->head->count = 0; } } - /* Free binned data: + /* Free all but last binned data block: */ { struct data_block_list *list = &setup->data; @@ -130,6 +131,7 @@ static void reset_context( struct setup_context *setup ) FREE(block); } + assert(list->tail->next == NULL); list->head = list->tail; list->head->used = 0; } @@ -588,6 +590,8 @@ lp_setup_destroy( struct setup_context *setup ) for (j = 0; j < TILES_Y; j++) FREE(setup->tile[i][j].head); + FREE(setup->data.head); + lp_rast_destroy( setup->rast ); FREE( setup ); } -- cgit v1.2.3 From 2e3580d994e2caf6d81763803c8525a7ed42b8fd Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 18 Oct 2009 11:57:43 +0100 Subject: llvmpipe: Maintain a copy of the shader constants to prevent clobbering. --- src/gallium/drivers/llvmpipe/lp_setup.c | 64 +++++++++++++++++++------ src/gallium/drivers/llvmpipe/lp_setup_context.h | 13 ++++- 2 files changed, 61 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index a74756de7c..08dac459db 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -101,6 +101,11 @@ static void reset_context( struct setup_context *setup ) SETUP_DEBUG("%s\n", __FUNCTION__); + /* Reset derived data */ + pipe_buffer_reference(&setup->constants.current, NULL); + setup->constants.stored_size = 0; + setup->constants.stored_data = NULL; + /* Free all but last binner command lists: */ for (i = 0; i < setup->tiles_x; i++) { @@ -424,18 +429,11 @@ void lp_setup_set_fs_constants(struct setup_context *setup, struct pipe_buffer *buffer) { - const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; - struct pipe_buffer *dummy; - SETUP_DEBUG("%s\n", __FUNCTION__); - /* FIXME: hold on to the reference */ - dummy = NULL; - pipe_buffer_reference(&dummy, buffer); + pipe_buffer_reference(&setup->constants.current, buffer); - setup->fs.current.jit_context.constants = data; - - setup->fs.dirty = TRUE; + setup->dirty |= LP_SETUP_NEW_CONSTANTS; } @@ -447,7 +445,7 @@ lp_setup_set_alpha_ref_value( struct setup_context *setup, if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) { setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value; - setup->fs.dirty = TRUE; + setup->dirty |= LP_SETUP_NEW_FS; } } @@ -468,7 +466,7 @@ lp_setup_set_blend_color( struct setup_context *setup, setup->fs.current.jit_context.blend_color[i*4 + j] = c; } - setup->fs.dirty = TRUE; + setup->dirty |= LP_SETUP_NEW_FS; } void @@ -505,7 +503,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, } } - setup->fs.dirty = TRUE; + setup->dirty |= LP_SETUP_NEW_FS; } boolean @@ -524,7 +522,43 @@ lp_setup_update_shader_state( struct setup_context *setup ) assert(setup->fs.current.jit_function); - if(setup->fs.dirty) { + if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { + struct pipe_buffer *buffer = setup->constants.current; + + if(buffer) { + unsigned current_size = buffer->size; + const void *current_data = llvmpipe_buffer(buffer)->data; + + /* TODO: copy only the actually used constants? */ + + if(setup->constants.stored_size != current_size || + !setup->constants.stored_data || + memcmp(setup->constants.stored_data, + current_data, + current_size) != 0) { + void *stored; + + stored = get_data(&setup->data, current_size); + if(stored) { + memcpy(stored, + current_data, + current_size); + setup->constants.stored_size = current_size; + setup->constants.stored_data = stored; + } + } + } + else { + setup->constants.stored_size = 0; + setup->constants.stored_data = NULL; + } + + setup->fs.current.jit_context.constants = setup->constants.stored_data; + setup->dirty |= LP_SETUP_NEW_FS; + } + + + if(setup->dirty & LP_SETUP_NEW_FS) { if(!setup->fs.stored || memcmp(setup->fs.stored, &setup->fs.current, @@ -539,10 +573,10 @@ lp_setup_update_shader_state( struct setup_context *setup ) setup->fs.stored = stored; } } - - setup->fs.dirty = FALSE; } + setup->dirty = 0; + assert(setup->fs.stored); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index c15a59e4d1..82ec71f100 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -43,6 +43,10 @@ #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) +#define LP_SETUP_NEW_FS 0x01 +#define LP_SETUP_NEW_CONSTANTS 0x02 + + /* switch to a non-pointer value for this: */ typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg ); @@ -112,9 +116,16 @@ struct setup_context { const struct lp_rast_state *stored; struct lp_rast_state current; - boolean dirty; } fs; + struct { + struct pipe_buffer *current; + unsigned stored_size; + const void *stored_data; + } constants; + + unsigned dirty; + void (*point)( struct setup_context *, const float (*v0)[4]); -- cgit v1.2.3 From f2be08ae0e20b3da8ff684ffeb94412cc6a5a5a1 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 19 Oct 2009 11:53:22 +0100 Subject: llvmpipe: Allocate the blend color from the data store, and ensure it's aligned. --- src/gallium/drivers/llvmpipe/lp_setup.c | 34 +++++++++++++++++-------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 28 ++++++++++++++++++-- 2 files changed, 50 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 08dac459db..da5a68cd40 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -105,6 +105,7 @@ static void reset_context( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); setup->constants.stored_size = 0; setup->constants.stored_data = NULL; + setup->dirty = ~0; /* Free all but last binner command lists: */ @@ -453,20 +454,14 @@ void lp_setup_set_blend_color( struct setup_context *setup, const struct pipe_blend_color *blend_color ) { - unsigned i, j; - SETUP_DEBUG("%s\n", __FUNCTION__); - if(!setup->fs.current.jit_context.blend_color) - setup->fs.current.jit_context.blend_color = align_malloc(4 * 16, 16); + assert(blend_color); - for (i = 0; i < 4; ++i) { - uint8_t c = float_to_ubyte(blend_color->color[i]); - for (j = 0; j < 16; ++j) - setup->fs.current.jit_context.blend_color[i*4 + j] = c; + if(memcmp(&setup->blend_color.current, blend_color, sizeof *blend_color) != 0) { + memcpy(&setup->blend_color.current, blend_color, sizeof *blend_color); + setup->dirty |= LP_SETUP_NEW_BLEND_COLOR; } - - setup->dirty |= LP_SETUP_NEW_FS; } void @@ -522,6 +517,25 @@ lp_setup_update_shader_state( struct setup_context *setup ) assert(setup->fs.current.jit_function); + if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) { + uint8_t *stored; + unsigned i, j; + + stored = get_data_aligned(&setup->data, 4 * 16, 16); + + for (i = 0; i < 4; ++i) { + uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); + for (j = 0; j < 16; ++j) + stored[i*4 + j] = c; + } + + setup->blend_color.stored = stored; + + setup->fs.current.jit_context.blend_color = setup->blend_color.stored; + setup->dirty |= LP_SETUP_NEW_FS; + } + + if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { struct pipe_buffer *buffer = setup->constants.current; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 82ec71f100..bcd3b9b7aa 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -43,8 +43,9 @@ #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) -#define LP_SETUP_NEW_FS 0x01 -#define LP_SETUP_NEW_CONSTANTS 0x02 +#define LP_SETUP_NEW_FS 0x01 +#define LP_SETUP_NEW_CONSTANTS 0x02 +#define LP_SETUP_NEW_BLEND_COLOR 0x04 /* switch to a non-pointer value for this: @@ -124,6 +125,11 @@ struct setup_context { const void *stored_data; } constants; + struct { + struct pipe_blend_color current; + uint8_t *stored; + } blend_color; + unsigned dirty; void (*point)( struct setup_context *, @@ -163,6 +169,24 @@ static INLINE void *get_data( struct data_block_list *list, } } +static INLINE void *get_data_aligned( struct data_block_list *list, + unsigned size, + unsigned alignment ) +{ + + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + lp_setup_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; + tail->used += offset + size; + return data + offset; + } +} + /* Add a command to a given bin. */ static INLINE void bin_command( struct cmd_block_list *list, -- cgit v1.2.3 From 301c1494b27ad92ff1237909f9c98c1660be8fc1 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 19 Oct 2009 13:14:33 +0100 Subject: llvmpipe: Reset the pointer to stored jit context. --- src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index da5a68cd40..c0f516e12c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -101,10 +101,10 @@ static void reset_context( struct setup_context *setup ) SETUP_DEBUG("%s\n", __FUNCTION__); - /* Reset derived data */ - pipe_buffer_reference(&setup->constants.current, NULL); + /* Reset derived state */ setup->constants.stored_size = 0; setup->constants.stored_data = NULL; + setup->fs.stored = NULL; setup->dirty = ~0; /* Free all but last binner command lists: @@ -634,6 +634,8 @@ lp_setup_destroy( struct setup_context *setup ) reset_context( setup ); + pipe_buffer_reference(&setup->constants.current, NULL); + for (i = 0; i < TILES_X; i++) for (j = 0; j < TILES_Y; j++) FREE(setup->tile[i][j].head); @@ -671,6 +673,8 @@ lp_setup_create( struct pipe_screen *screen ) setup->line = first_line; setup->point = first_point; + setup->dirty = ~0; + return setup; fail: -- cgit v1.2.3 From 694f05ac18c54253910678709f2dd35c36f1e912 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 Oct 2009 15:21:11 +0100 Subject: llvmpipe: remove one of two definitions of TILESIZE --- src/gallium/drivers/llvmpipe/lp_rast.c | 8 ++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 2 -- src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++---- src/gallium/drivers/llvmpipe/lp_setup_context.h | 5 +++-- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 20 ++++++++++---------- src/gallium/drivers/llvmpipe/lp_tile_soa.h | 3 ++- 6 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6fd6acc0fa..6e94e22e5b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -71,8 +71,8 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, rast->state.write_zstencil = write_zstencil; rast->state.write_color = write_color; - rast->check_for_clipped_tiles = (width % TILESIZE != 0 || - height % TILESIZE != 0); + rast->check_for_clipped_tiles = (width % TILE_SIZE != 0 || + height % TILE_SIZE != 0); if (cbuf) { rast->cbuf_transfer = screen->get_tex_transfer(rast->screen, @@ -311,8 +311,8 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) { const unsigned x = rast->x; const unsigned y = rast->y; - unsigned w = TILESIZE; - unsigned h = TILESIZE; + unsigned w = TILE_SIZE; + unsigned h = TILE_SIZE; if (x + w > rast->width) w -= x + w - rast->width; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 318bf73b15..282b9a46d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -41,8 +41,6 @@ struct pipe_screen; #define FIXED_ORDER 4 #define FIXED_ONE (1<tiles_y; j++) { lp_rast_start_tile( rast, - i * TILESIZE, - j * TILESIZE ); + i * TILE_SIZE, + j * TILE_SIZE ); for (block = setup->tile[i][j].head; block; block = block->next) { for (k = 0; k < block->count; k++) { @@ -241,8 +241,8 @@ begin_binning( struct setup_context *setup ) setup->fb.zsbuf->height); } - setup->tiles_x = align(setup->fb.width, TILESIZE) / TILESIZE; - setup->tiles_y = align(setup->fb.height, TILESIZE) / TILESIZE; + setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE; + setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE; if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index d91ffc7c20..938f6ce262 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -30,14 +30,15 @@ #include "lp_setup.h" #include "lp_rast.h" +#include "lp_tile_soa.h" /* for TILE_SIZE */ /* We're limited to 2K by 2K for 32bit fixed point rasterization. * Will need a 64-bit version for larger framebuffers. */ #define MAXHEIGHT 2048 #define MAXWIDTH 2048 -#define TILES_X (MAXWIDTH / TILESIZE) -#define TILES_Y (MAXHEIGHT / TILESIZE) +#define TILES_X (MAXWIDTH / TILE_SIZE) +#define TILES_Y (MAXHEIGHT / TILE_SIZE) #define CMD_BLOCK_MAX 128 #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 041716adc9..f2665c11df 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -372,10 +372,10 @@ do_triangle_ccw(struct setup_context *setup, } } - minx = tri->minx / TILESIZE; - miny = tri->miny / TILESIZE; - maxx = tri->maxx / TILESIZE; - maxy = tri->maxy / TILESIZE; + minx = tri->minx / TILE_SIZE; + miny = tri->miny / TILE_SIZE; + maxx = tri->maxx / TILE_SIZE; + maxy = tri->maxy / TILE_SIZE; /* Convert to tile coordinates: @@ -390,14 +390,14 @@ do_triangle_ccw(struct setup_context *setup, else { int c1 = (tri->c1 + - tri->dx12 * miny * TILESIZE - - tri->dy12 * minx * TILESIZE); + tri->dx12 * miny * TILE_SIZE - + tri->dy12 * minx * TILE_SIZE); int c2 = (tri->c2 + - tri->dx23 * miny * TILESIZE - - tri->dy23 * minx * TILESIZE); + tri->dx23 * miny * TILE_SIZE - + tri->dy23 * minx * TILE_SIZE); int c3 = (tri->c3 + - tri->dx31 * miny * TILESIZE - - tri->dy31 * minx * TILESIZE); + tri->dx31 * miny * TILE_SIZE - + tri->dy31 * minx * TILE_SIZE); int ei1 = tri->ei1 << TILE_ORDER; int ei2 = tri->ei2 << TILE_ORDER; diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.h b/src/gallium/drivers/llvmpipe/lp_tile_soa.h index d72d6d2ef1..0e874ce451 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.h @@ -43,7 +43,8 @@ struct pipe_transfer; /** * Cache tile size (width and height). This needs to be a power of two. */ -#define TILE_SIZE 64 +#define TILE_ORDER 6 +#define TILE_SIZE (1< Date: Mon, 30 Nov 2009 14:01:31 -0700 Subject: llvmpipe: minor refactoring of bin rasterization code --- src/gallium/drivers/llvmpipe/lp_setup.c | 44 +++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 6d84147468..7091232350 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -170,13 +170,35 @@ static void bin_everywhere( struct setup_context *setup, } +/** Rasterize commands for a single bin */ +static void +rasterize_bin( struct lp_rasterizer *rast, + struct cmd_block_list *commands, + int x, int y) +{ + struct cmd_block *block; + unsigned k; + + lp_rast_start_tile( rast, x, y ); + + /* simply execute each of the commands in the block list */ + for (block = commands->head; block; block = block->next) { + for (k = 0; k < block->count; k++) { + block->cmd[k]( rast, block->arg[k] ); + } + } + + lp_rast_end_tile( rast ); +} + + +/** Rasterize all tile's bins */ static void rasterize_bins( struct setup_context *setup, boolean write_depth ) { struct lp_rasterizer *rast = setup->rast; - struct cmd_block *block; - unsigned i,j,k; + unsigned i, j; SETUP_DEBUG("%s\n", __FUNCTION__); @@ -187,23 +209,13 @@ rasterize_bins( struct setup_context *setup, setup->fb.zsbuf != NULL && write_depth, setup->fb.width, setup->fb.height ); - - + /* loop over tile bins, rasterize each */ for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { - - lp_rast_start_tile( rast, - i * TILE_SIZE, - j * TILE_SIZE ); - - for (block = setup->tile[i][j].head; block; block = block->next) { - for (k = 0; k < block->count; k++) { - block->cmd[k]( rast, block->arg[k] ); - } - } - - lp_rast_end_tile( rast ); + rasterize_bin( rast, &setup->tile[i][j], + i * TILE_SIZE, + j * TILE_SIZE ); } } -- cgit v1.2.3 From 3094fc200920f9d5eb62136d3b25896229fb0dbf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 14:25:08 -0700 Subject: llvmpipe: more debug info --- src/gallium/drivers/llvmpipe/lp_setup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 7091232350..14b40dfe36 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -222,6 +222,8 @@ rasterize_bins( struct setup_context *setup, lp_rast_end( rast ); reset_context( setup ); + + SETUP_DEBUG("%s done \n", __FUNCTION__); } @@ -273,6 +275,8 @@ begin_binning( struct setup_context *setup ) else bin_everywhere( setup, lp_rast_load_zstencil, lp_rast_arg_null() ); } + + SETUP_DEBUG("%s done\n", __FUNCTION__); } @@ -422,7 +426,7 @@ lp_setup_set_fs_inputs( struct setup_context *setup, const struct lp_shader_input *input, unsigned nr ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + SETUP_DEBUG("%s %p %u\n", __FUNCTION__, (void *) input, nr); memcpy( setup->fs.input, input, nr * sizeof input[0] ); setup->fs.nr_inputs = nr; @@ -432,7 +436,7 @@ void lp_setup_set_fs( struct setup_context *setup, struct lp_fragment_shader *fs ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + SETUP_DEBUG("%s %p\n", __FUNCTION__, (void *) fs); /* FIXME: reference count */ setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL; @@ -442,7 +446,7 @@ void lp_setup_set_fs_constants(struct setup_context *setup, struct pipe_buffer *buffer) { - SETUP_DEBUG("%s\n", __FUNCTION__); + SETUP_DEBUG("%s %p\n", __FUNCTION__, (void *) buffer); pipe_buffer_reference(&setup->constants.current, buffer); @@ -454,7 +458,7 @@ void lp_setup_set_alpha_ref_value( struct setup_context *setup, float alpha_ref_value ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + SETUP_DEBUG("%s %f\n", __FUNCTION__, alpha_ref_value); if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) { setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value; -- cgit v1.2.3 From 0e042bed49c51fef38b02b7cc05efa504f2f703d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 14:25:46 -0700 Subject: llvmpipe: set LP_SETUP_NEW_FS in lp_setup_set_fs() Fixes progs/trivial/tri-blend.c, but I think we're just getting lucky in this case. --- src/gallium/drivers/llvmpipe/lp_setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 14b40dfe36..142fec4f80 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -440,6 +440,7 @@ lp_setup_set_fs( struct setup_context *setup, /* FIXME: reference count */ setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL; + setup->dirty |= LP_SETUP_NEW_FS; } void -- cgit v1.2.3 From e2f46344560f8f1193b311ad41883011e67eea00 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 16:05:12 -0700 Subject: llvmpipe: checkpoint some initial state binning code --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 ++ src/gallium/drivers/llvmpipe/lp_setup.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2d319777ee..d5fe6e9369 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -235,6 +235,8 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, void lp_rast_set_state( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { + const struct lp_rast_state *state = arg.set_state; + RAST_DEBUG("%s\n", __FUNCTION__); /* XXX to do */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 142fec4f80..36bd0ad4dd 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -594,14 +594,24 @@ lp_setup_update_shader_state( struct setup_context *setup ) memcmp(setup->fs.stored, &setup->fs.current, sizeof setup->fs.current) != 0) { - struct lp_rast_state *stored; - - stored = get_data(&setup->data, sizeof *stored); + /* The fs state that's been stored in the bins is different from + * the new, current state. So allocate a new lp_rast_state object + * and append it to the bin's setup data buffer. + */ + struct lp_rast_state *stored = + (struct lp_rast_state *) get_data(&setup->data, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, sizeof setup->fs.current); setup->fs.stored = stored; + +#if 0 + /* put the state-set command into all bins */ + bin_everywhere( setup, + lp_rast_set_state, + *setup->fs.stored ); +#endif } } } -- cgit v1.2.3 From 4e058f6c4803be5d9d676338d6aee2775b88b87c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 17:00:22 -0700 Subject: llvmpipe: fix incorrect array indexing when saving blend color --- src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 36bd0ad4dd..8ef764eb80 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -543,7 +543,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) for (i = 0; i < 4; ++i) { uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); for (j = 0; j < 16; ++j) - stored[i*4 + j] = c; + stored[i*16 + j] = c; } setup->blend_color.stored = stored; -- cgit v1.2.3 From 9c1debe208d07b57e88c65bae186bb339de7dee7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 17:28:02 -0700 Subject: llvmpipe: comment about blend color --- src/gallium/drivers/llvmpipe/lp_setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 8ef764eb80..1f303d7705 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -540,6 +540,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) stored = get_data_aligned(&setup->data, 4 * 16, 16); + /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); for (j = 0; j < 16; ++j) -- cgit v1.2.3 From 9dca0100489c7a7c02af77da42a39dbe1560d7e2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 10:41:38 -0700 Subject: llvmpipe: struct cmd_bin Just introducing a new structure to represent a per-tile bin. --- src/gallium/drivers/llvmpipe/lp_setup.c | 11 ++++++----- src/gallium/drivers/llvmpipe/lp_setup_context.h | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 1f303d7705..fc7f4f6778 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -111,7 +111,7 @@ static void reset_context( struct setup_context *setup ) */ for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { - struct cmd_block_list *list = &setup->tile[i][j]; + struct cmd_block_list *list = &setup->tile[i][j].commands; struct cmd_block *block; struct cmd_block *tmp; @@ -173,9 +173,10 @@ static void bin_everywhere( struct setup_context *setup, /** Rasterize commands for a single bin */ static void rasterize_bin( struct lp_rasterizer *rast, - struct cmd_block_list *commands, + const struct cmd_bin *bin, int x, int y) { + const struct cmd_block_list *commands = &bin->commands; struct cmd_block *block; unsigned k; @@ -666,7 +667,7 @@ lp_setup_destroy( struct setup_context *setup ) for (i = 0; i < TILES_X; i++) for (j = 0; j < TILES_Y; j++) - FREE(setup->tile[i][j].head); + FREE(setup->tile[i][j].commands.head); FREE(setup->data.head); @@ -691,8 +692,8 @@ lp_setup_create( struct pipe_screen *screen ) for (i = 0; i < TILES_X; i++) for (j = 0; j < TILES_Y; j++) - setup->tile[i][j].head = - setup->tile[i][j].tail = CALLOC_STRUCT(cmd_block); + setup->tile[i][j].commands.head = + setup->tile[i][j].commands.tail = CALLOC_STRUCT(cmd_block); setup->data.head = setup->data.tail = CALLOC_STRUCT(data_block); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index b502f00eea..1715048f76 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -71,11 +71,20 @@ struct cmd_block_list { struct cmd_block *tail; }; +/** + * For each screen tile we have one of these bins. + */ +struct cmd_bin { + struct cmd_block_list commands; + struct lp_rast_state *curr_state; +}; + + struct data_block_list { struct data_block *head; struct data_block *tail; }; - + /** * Point/line/triangle setup context. @@ -87,12 +96,12 @@ struct setup_context { struct lp_rasterizer *rast; /** - * Per-bin data goes into the 'tile' cmd_block_lists. + * Per-bin data goes into the 'tile' bins. * Shared bin data goes into the 'data' buffer. * When there are multiple threads, will want to double-buffer the * bin arrays: */ - struct cmd_block_list tile[TILES_X][TILES_Y]; + struct cmd_bin tile[TILES_X][TILES_Y]; struct data_block_list data; /* size of framebuffer, in tiles */ @@ -212,10 +221,12 @@ static INLINE void *get_data_aligned( struct data_block_list *list, /* Add a command to a given bin. */ -static INLINE void bin_command( struct cmd_block_list *list, +static INLINE void bin_command( struct cmd_bin *bin, lp_rast_cmd cmd, union lp_rast_cmd_arg arg ) { + struct cmd_block_list *list = &bin->commands; + if (list->tail->count == CMD_BLOCK_MAX) { lp_setup_new_cmd_block( list ); } -- cgit v1.2.3 From b1659b9213f3eeee440590dfe379f0d193948307 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 11:50:40 -0700 Subject: llvmpipe: bin state-change commands Previously, each triangle had a pointer to the state to use for shading. Now we insert state-change commands into the bins. When we execute one of those commands we just update a 'current state' pointer and use that pointer when calling the jit shader. When inserting state-change commands into a bin we check if the previous command was also a state-change command and simply replace it. This avoids accumulating useless/redundant state-change commands. --- src/gallium/drivers/llvmpipe/lp_rast.c | 9 +- src/gallium/drivers/llvmpipe/lp_rast.h | 15 ++-- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 + src/gallium/drivers/llvmpipe/lp_setup.c | 113 +++++++++++++++++------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 7 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 2 - 6 files changed, 101 insertions(+), 47 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d5fe6e9369..8f37a28e87 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -237,9 +237,10 @@ void lp_rast_set_state( struct lp_rasterizer *rast, { const struct lp_rast_state *state = arg.set_state; - RAST_DEBUG("%s\n", __FUNCTION__); + RAST_DEBUG("%s %p\n", __FUNCTION__, (void *) state); - /* XXX to do */ + /* just set the current state pointer for this rasterizer */ + rast->current_state = state; } @@ -279,7 +280,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned mask) { #if 1 - const struct lp_rast_state *state = inputs->state; + const struct lp_rast_state *state = rast->current_state; struct lp_rast_tile *tile = &rast->tile; void *color; void *depth; @@ -287,6 +288,8 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned ix, iy; int block_offset; + assert(state); + /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 435993d44d..e9a1fa49ad 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -55,18 +55,13 @@ struct lp_rast_state { }; -/* Coefficients necessary to run the shader at a given location: + +/** + * Coefficients necessary to run the shader at a given location. + * First coefficient is position. + * These pointers point into the bin data buffer. */ struct lp_rast_shader_inputs { - - /* Current rasterizer state: - */ - const struct lp_rast_state *state; - - /* Attribute interpolation: - * First coefficient is position. - * These pointers point into the bin data buffer. - */ float (*a0)[4]; float (*dadx)[4]; float (*dady)[4]; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 4c0dfe2282..98111edff7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -86,6 +86,8 @@ struct lp_rasterizer unsigned y; unsigned mask; } blocks[256]; + + const struct lp_rast_state *current_state; }; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index fc7f4f6778..11a9fd2637 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -155,6 +155,34 @@ static void reset_context( struct setup_context *setup ) } +/** + * Return last command in the bin + */ +static lp_rast_cmd +lp_get_last_command( const struct cmd_bin *bin ) +{ + const struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + if (i > 0) + return tail->cmd[i - 1]; + else + return NULL; +} + + +/** + * Replace the arg of the last command in the bin. + */ +static void +lp_replace_last_command_arg( struct cmd_bin *bin, + const union lp_rast_cmd_arg arg ) +{ + struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + assert(i > 0); + tail->arg[i - 1] = arg; +} + /* Add a command to all active bins. @@ -170,6 +198,32 @@ static void bin_everywhere( struct setup_context *setup, } +/** + * Put a state-change command into all bins. + * If we find that the last command in a bin was also a state-change + * command, we can simply replace that one with the new one. + */ +static void +bin_state_command( struct setup_context *setup, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < setup->tiles_x; i++) { + for (j = 0; j < setup->tiles_y; j++) { + struct cmd_bin *bin = &setup->tile[i][j]; + lp_rast_cmd last_cmd = lp_get_last_command(bin); + if (last_cmd == cmd) { + lp_replace_last_command_arg(bin, arg); + } + else { + bin_command( bin, cmd, arg ); + } + } + } +} + + /** Rasterize commands for a single bin */ static void rasterize_bin( struct lp_rasterizer *rast, @@ -234,31 +288,6 @@ begin_binning( struct setup_context *setup ) { SETUP_DEBUG("%s\n", __FUNCTION__); - if (!setup->fb.cbuf && !setup->fb.zsbuf) { - setup->fb.width = 0; - setup->fb.height = 0; - } - else if (!setup->fb.zsbuf) { - setup->fb.width = setup->fb.cbuf->width; - setup->fb.height = setup->fb.cbuf->height; - } - else if (!setup->fb.cbuf) { - setup->fb.width = setup->fb.zsbuf->width; - setup->fb.height = setup->fb.zsbuf->height; - } - else { - /* XXX: not sure what we're really supposed to do for - * mis-matched color & depth buffer sizes. - */ - setup->fb.width = MIN2(setup->fb.cbuf->width, - setup->fb.zsbuf->width); - setup->fb.height = MIN2(setup->fb.cbuf->height, - setup->fb.zsbuf->height); - } - - setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE; - setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE; - if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, @@ -352,8 +381,34 @@ lp_setup_bind_framebuffer( struct setup_context *setup, pipe_surface_reference( &setup->fb.cbuf, color ); pipe_surface_reference( &setup->fb.zsbuf, zstencil ); + + if (!setup->fb.cbuf && !setup->fb.zsbuf) { + setup->fb.width = 0; + setup->fb.height = 0; + } + else if (!setup->fb.zsbuf) { + setup->fb.width = setup->fb.cbuf->width; + setup->fb.height = setup->fb.cbuf->height; + } + else if (!setup->fb.cbuf) { + setup->fb.width = setup->fb.zsbuf->width; + setup->fb.height = setup->fb.zsbuf->height; + } + else { + /* XXX: not sure what we're really supposed to do for + * mis-matched color & depth buffer sizes. + */ + setup->fb.width = MIN2(setup->fb.cbuf->width, + setup->fb.zsbuf->width); + setup->fb.height = MIN2(setup->fb.cbuf->height, + setup->fb.zsbuf->height); + } + + setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE; + setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE; } + void lp_setup_clear( struct setup_context *setup, const float *color, @@ -608,12 +663,10 @@ lp_setup_update_shader_state( struct setup_context *setup ) sizeof setup->fs.current); setup->fs.stored = stored; -#if 0 /* put the state-set command into all bins */ - bin_everywhere( setup, - lp_rast_set_state, - *setup->fs.stored ); -#endif + bin_state_command( setup, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); } } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 1715048f76..7c7c34f3f7 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -76,10 +76,14 @@ struct cmd_block_list { */ struct cmd_bin { struct cmd_block_list commands; - struct lp_rast_state *curr_state; }; +/** + * This stores bulk data which is shared by all bins. + * Examples include triangle data and state data. The commands in + * the per-tile bins will point to chunks of data in this structure. + */ struct data_block_list { struct data_block *head; struct data_block *tail; @@ -241,5 +245,4 @@ static INLINE void bin_command( struct cmd_bin *bin, } - #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 74ed0a9e8f..48733a599b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -295,8 +295,6 @@ do_triangle_ccw(struct setup_context *setup, return; } - tri->inputs.state = setup->fs.stored; - /* */ tri->oneoverarea = ((float)FIXED_ONE) / (float)area; -- cgit v1.2.3 From d9dc3d59760a28d54013d3d164f61d85ec807651 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 12:54:37 -0700 Subject: llvmpipe: move bin-related structures and functions into new lp_bin.[ch] And put lp_ prefixes on some functions. --- src/gallium/drivers/llvmpipe/Makefile | 1 + src/gallium/drivers/llvmpipe/SConscript | 7 +- src/gallium/drivers/llvmpipe/lp_bin.c | 51 ++++++++ src/gallium/drivers/llvmpipe/lp_bin.h | 167 ++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 5 + src/gallium/drivers/llvmpipe/lp_setup.c | 27 +--- src/gallium/drivers/llvmpipe/lp_setup_context.h | 116 +--------------- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 18 +-- 8 files changed, 243 insertions(+), 149 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_bin.c create mode 100644 src/gallium/drivers/llvmpipe/lp_bin.h (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index bfe34396d9..0a5d1b9f1b 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -6,6 +6,7 @@ LIBNAME = llvmpipe CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS C_SOURCES = \ + lp_bin.c \ lp_bld_alpha.c \ lp_bld_arit.c \ lp_bld_blend_aos.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 3530e739cc..4aef338735 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -19,6 +19,7 @@ env.CodeGenerate( llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ + 'lp_bin.c', 'lp_bld_alpha.c', 'lp_bld_arit.c', 'lp_bld_blend_aos.c', @@ -46,7 +47,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_flush.c', 'lp_jit.c', 'lp_prim_vbuf.c', - 'lp_query.c', + 'lp_query.c', 'lp_setup.c', 'lp_setup_tri.c', 'lp_setup_line.c', @@ -62,8 +63,8 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_vertex.c', 'lp_state_vs.c', 'lp_surface.c', - 'lp_rast.c', - 'lp_rast_tri.c', + 'lp_rast.c', + 'lp_rast_tri.c', 'lp_tex_sample_llvm.c', 'lp_texture.c', 'lp_tile_soa.c', diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c new file mode 100644 index 0000000000..f43cdcbf3d --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bin.c @@ -0,0 +1,51 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_memory.h" +#include "lp_bin.h" + + +void +lp_bin_new_cmd_block( struct cmd_block_list *list ) +{ + struct cmd_block *block = MALLOC_STRUCT(cmd_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; +} + + +void +lp_bin_new_data_block( struct data_block_list *list ) +{ + struct data_block *block = MALLOC_STRUCT(data_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; +} diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h new file mode 100644 index 0000000000..fa25d78631 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -0,0 +1,167 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Binner data structures and bin-related functions. + * Note: the "setup" code is concerned with building bins while + * The "rast" code is concerned with consuming/executing bins. + */ + +#ifndef LP_BIN_H +#define LP_BIN_H + +#include "lp_rast.h" + + +#define CMD_BLOCK_MAX 128 +#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) + + + +/* switch to a non-pointer value for this: + */ +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg ); + +struct cmd_block { + lp_rast_cmd cmd[CMD_BLOCK_MAX]; + union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; + unsigned count; + struct cmd_block *next; +}; + +struct data_block { + ubyte data[DATA_BLOCK_SIZE]; + unsigned used; + struct data_block *next; +}; + +struct cmd_block_list { + struct cmd_block *head; + struct cmd_block *tail; +}; + +/** + * For each screen tile we have one of these bins. + */ +struct cmd_bin { + struct cmd_block_list commands; +}; + + +/** + * This stores bulk data which is shared by all bins. + * Examples include triangle data and state data. The commands in + * the per-tile bins will point to chunks of data in this structure. + */ +struct data_block_list { + struct data_block *head; + struct data_block *tail; +}; + + + +extern void lp_bin_new_data_block( struct data_block_list *list ); + +extern void lp_bin_new_cmd_block( struct cmd_block_list *list ); + + +/** + * Allocate space for a command/data in the given block list. + * Grow the block list if needed. + */ +static INLINE void * +lp_bin_alloc( struct data_block_list *list, unsigned size) +{ + if (list->tail->used + size > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + tail->used += size; + return data; + } +} + + +/** + * As above, but with specific alignment. + */ +static INLINE void * +lp_bin_alloc_aligned( struct data_block_list *list, unsigned size, + unsigned alignment ) +{ + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; + tail->used += offset + size; + return data + offset; + } +} + + +/* Put back data if we decide not to use it, eg. culled triangles. + */ +static INLINE void +lp_bin_putback_data( struct data_block_list *list, unsigned size) +{ + assert(list->tail->used >= size); + list->tail->used -= size; +} + + +/* Add a command to a given bin. + */ +static INLINE void +lp_bin_command( struct cmd_bin *bin, + lp_rast_cmd cmd, + union lp_rast_cmd_arg arg ) +{ + struct cmd_block_list *list = &bin->commands; + + if (list->tail->count == CMD_BLOCK_MAX) { + lp_bin_new_cmd_block( list ); + } + + { + struct cmd_block *tail = list->tail; + unsigned i = tail->count; + tail->cmd[i] = cmd; + tail->arg[i] = arg; + tail->count++; + } +} + + +#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index a119b089bd..307c45cb9f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -43,6 +43,11 @@ struct pipe_screen; #define FIXED_ONE (1<tail->next = block; - list->tail = block; - block->next = NULL; - block->count = 0; -} - -void lp_setup_new_data_block( struct data_block_list *list ) -{ - struct data_block *block = MALLOC_STRUCT(data_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->used = 0; -} static void @@ -194,7 +177,7 @@ static void bin_everywhere( struct setup_context *setup, unsigned i, j; for (i = 0; i < setup->tiles_x; i++) for (j = 0; j < setup->tiles_y; j++) - bin_command( &setup->tile[i][j], cmd, arg ); + lp_bin_command( &setup->tile[i][j], cmd, arg ); } @@ -217,7 +200,7 @@ bin_state_command( struct setup_context *setup, lp_replace_last_command_arg(bin, arg); } else { - bin_command( bin, cmd, arg ); + lp_bin_command( bin, cmd, arg ); } } } @@ -594,7 +577,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) uint8_t *stored; unsigned i, j; - stored = get_data_aligned(&setup->data, 4 * 16, 16); + stored = lp_bin_alloc_aligned(&setup->data, 4 * 16, 16); /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { @@ -626,7 +609,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) current_size) != 0) { void *stored; - stored = get_data(&setup->data, current_size); + stored = lp_bin_alloc(&setup->data, current_size); if(stored) { memcpy(stored, current_data, @@ -656,7 +639,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) * and append it to the bin's setup data buffer. */ struct lp_rast_state *stored = - (struct lp_rast_state *) get_data(&setup->data, sizeof *stored); + (struct lp_rast_state *) lp_bin_alloc(&setup->data, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 7c7c34f3f7..5abe66f586 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -31,6 +31,7 @@ #include "lp_setup.h" #include "lp_rast.h" #include "lp_tile_soa.h" /* for TILE_SIZE */ +#include "lp_bin.h" /* We're limited to 2K by 2K for 32bit fixed point rasterization. * Will need a 64-bit version for larger framebuffers. @@ -40,56 +41,12 @@ #define TILES_X (MAXWIDTH / TILE_SIZE) #define TILES_Y (MAXHEIGHT / TILE_SIZE) -#define CMD_BLOCK_MAX 128 -#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) - #define LP_SETUP_NEW_FS 0x01 #define LP_SETUP_NEW_CONSTANTS 0x02 #define LP_SETUP_NEW_BLEND_COLOR 0x04 -/* switch to a non-pointer value for this: - */ -typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg ); - -struct cmd_block { - lp_rast_cmd cmd[CMD_BLOCK_MAX]; - union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; - unsigned count; - struct cmd_block *next; -}; - -struct data_block { - ubyte data[DATA_BLOCK_SIZE]; - unsigned used; - struct data_block *next; -}; - -struct cmd_block_list { - struct cmd_block *head; - struct cmd_block *tail; -}; - -/** - * For each screen tile we have one of these bins. - */ -struct cmd_bin { - struct cmd_block_list commands; -}; - - -/** - * This stores bulk data which is shared by all bins. - * Examples include triangle data and state data. The commands in - * the per-tile bins will point to chunks of data in this structure. - */ -struct data_block_list { - struct data_block *head; - struct data_block *tail; -}; - - /** * Point/line/triangle setup context. * Note: "stored" below indicates data which is stored in the bins, @@ -174,75 +131,4 @@ void lp_setup_choose_line( struct setup_context *setup ); void lp_setup_choose_point( struct setup_context *setup ); -void lp_setup_new_data_block( struct data_block_list *list ); -void lp_setup_new_cmd_block( struct cmd_block_list *list ); - - -/** - * Allocate space for a command/data in the given block list. - * Grow the block list if needed. - */ -static INLINE void *get_data( struct data_block_list *list, - unsigned size) -{ - if (list->tail->used + size > DATA_BLOCK_SIZE) { - lp_setup_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - tail->used += size; - return data; - } -} - -/* Put back data if we decide not to use it, eg. culled triangles. - */ -static INLINE void putback_data( struct data_block_list *list, - unsigned size) -{ - list->tail->used -= size; -} - - -static INLINE void *get_data_aligned( struct data_block_list *list, - unsigned size, - unsigned alignment ) -{ - if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { - lp_setup_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; - tail->used += offset + size; - return data + offset; - } -} - -/* Add a command to a given bin. - */ -static INLINE void bin_command( struct cmd_bin *bin, - lp_rast_cmd cmd, - union lp_rast_cmd_arg arg ) -{ - struct cmd_block_list *list = &bin->commands; - - if (list->tail->count == CMD_BLOCK_MAX) { - lp_setup_new_cmd_block( list ); - } - - { - struct cmd_block *tail = list->tail; - unsigned i = tail->count; - tail->cmd[i] = cmd; - tail->arg[i] = arg; - tail->count++; - } -} - - #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 56a32d0ac0..5e53b4050e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -185,9 +185,9 @@ static void setup_tri_coefficients( struct setup_context *setup, { unsigned bytes; bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float); - tri->inputs.a0 = get_data_aligned( &setup->data, bytes, 16 ); - tri->inputs.dadx = get_data_aligned( &setup->data, bytes, 16 ); - tri->inputs.dady = get_data_aligned( &setup->data, bytes, 16 ); + tri->inputs.a0 = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); + tri->inputs.dadx = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); + tri->inputs.dady = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); } /* The internal position input is in slot zero: @@ -263,7 +263,7 @@ do_triangle_ccw(struct setup_context *setup, const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - struct lp_rast_triangle *tri = get_data( &setup->data, sizeof *tri ); + struct lp_rast_triangle *tri = lp_bin_alloc( &setup->data, sizeof *tri ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -283,7 +283,7 @@ do_triangle_ccw(struct setup_context *setup, * XXX: subject to overflow?? */ if (area <= 0) { - putback_data( &setup->data, sizeof *tri ); + lp_bin_putback_data( &setup->data, sizeof *tri ); return; } @@ -295,7 +295,7 @@ do_triangle_ccw(struct setup_context *setup, if (tri->miny == tri->maxy || tri->minx == tri->maxx) { - putback_data( &setup->data, sizeof *tri ); + lp_bin_putback_data( &setup->data, sizeof *tri ); return; } @@ -405,7 +405,7 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - bin_command( &setup->tile[minx][miny], lp_rast_triangle, + lp_bin_command( &setup->tile[minx][miny], lp_rast_triangle, lp_rast_arg_triangle(tri) ); } else @@ -464,7 +464,7 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ - bin_command( &setup->tile[x][y], + lp_bin_command( &setup->tile[x][y], lp_rast_shade_tile, lp_rast_arg_inputs(&tri->inputs) ); } @@ -472,7 +472,7 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* shade partial tile */ - bin_command( &setup->tile[x][y], + lp_bin_command( &setup->tile[x][y], lp_rast_triangle, lp_rast_arg_triangle(tri) ); } -- cgit v1.2.3 From a08d6302168341001003da32d42cfcff2311fa04 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 14:11:25 -0700 Subject: llvmpipe: use LP_DBG() macro everywhere --- src/gallium/drivers/llvmpipe/lp_rast.c | 24 +++++++++--------- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup.c | 40 +++++++++++++++--------------- 3 files changed, 34 insertions(+), 33 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 8f37a28e87..5891a2a706 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -27,13 +27,13 @@ #include "util/u_memory.h" +#include "lp_debug.h" #include "lp_state.h" #include "lp_rast.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" #include "lp_bld_debug.h" -#define RAST_DEBUG debug_printf struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) { @@ -65,7 +65,7 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, { struct pipe_screen *screen = rast->screen; - RAST_DEBUG("%s %dx%d\n", __FUNCTION__, width, height); + LP_DBG(DEBUG_RAST, "%s %dx%d\n", __FUNCTION__, width, height); pipe_surface_reference(&rast->state.cbuf, cbuf); pipe_surface_reference(&rast->state.zsbuf, zsbuf); @@ -152,7 +152,7 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, unsigned x, unsigned y ) { - RAST_DEBUG("%s %d,%d\n", __FUNCTION__, x, y); + LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); rast->x = x; rast->y = y; @@ -168,7 +168,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, { const uint8_t *clear_color = arg.clear_color; - RAST_DEBUG("%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, + LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, clear_color[0], clear_color[1], clear_color[2], @@ -198,7 +198,7 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, { unsigned i, j; - RAST_DEBUG("%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); + LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); for (i = 0; i < TILE_SIZE; i++) for (j = 0; j < TILE_SIZE; j++) @@ -213,7 +213,7 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, void lp_rast_load_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg) { - RAST_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); /* call u_tile func to load colors from surface */ } @@ -226,7 +226,7 @@ void lp_rast_load_color( struct lp_rasterizer *rast, void lp_rast_load_zstencil( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { - RAST_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); /* call u_tile func to load depth (and stencil?) from surface */ } @@ -237,7 +237,7 @@ void lp_rast_set_state( struct lp_rasterizer *rast, { const struct lp_rast_state *state = arg.set_state; - RAST_DEBUG("%s %p\n", __FUNCTION__, (void *) state); + LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state); /* just set the current state pointer for this rasterizer */ rast->current_state = state; @@ -260,7 +260,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, const unsigned mask = ~0; unsigned x, y; - RAST_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); /* Use the existing preference for 4x4 (four quads) shading: */ @@ -398,7 +398,7 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) if (y + h > rast->height) h -= y + h - rast->height; - RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); lp_tile_write_4ub(rast->cbuf_transfer->format, rast->tile.color, @@ -440,7 +440,7 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) if (y + h > rast->height) h -= y + h - rast->height; - RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); assert(rast->zsbuf_transfer->format == PIPE_FORMAT_Z32_UNORM); lp_tile_write_z32(rast->tile.depth, @@ -455,7 +455,7 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) */ void lp_rast_end_tile( struct lp_rasterizer *rast ) { - RAST_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); if (rast->state.write_color) lp_rast_store_color(rast); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index e772a0158a..81a9c1c142 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -30,6 +30,7 @@ */ #include "util/u_math.h" +#include "lp_debug.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" @@ -185,7 +186,7 @@ lp_rast_triangle( struct lp_rasterizer *rast, assert(Elements(rast->blocks) == (TILE_SIZE * TILE_SIZE) / (4*4)); - debug_printf("%s\n", __FUNCTION__); + LP_DBG(DEBUG_RAST, "lp_rast_triangle\n"); rast->nr_blocks = 0; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 6136d1b57e..7f31df6ae5 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -37,12 +37,12 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_pack_color.h" +#include "lp_debug.h" #include "lp_state.h" #include "lp_buffer.h" #include "lp_texture.h" #include "lp_setup_context.h" -#define SETUP_DEBUG debug_printf static void set_state( struct setup_context *, unsigned ); @@ -82,7 +82,7 @@ static void reset_context( struct setup_context *setup ) { unsigned i, j; - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); /* Reset derived state */ setup->constants.stored_size = 0; @@ -238,7 +238,7 @@ rasterize_bins( struct setup_context *setup, struct lp_rasterizer *rast = setup->rast; unsigned i, j; - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); lp_rast_begin( rast, setup->fb.cbuf, @@ -261,7 +261,7 @@ rasterize_bins( struct setup_context *setup, reset_context( setup ); - SETUP_DEBUG("%s done \n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); } @@ -269,7 +269,7 @@ rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (setup->fb.cbuf) { if (setup->clear.flags & PIPE_CLEAR_COLOR) @@ -289,7 +289,7 @@ begin_binning( struct setup_context *setup ) bin_everywhere( setup, lp_rast_load_zstencil, lp_rast_arg_null() ); } - SETUP_DEBUG("%s done\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__); } @@ -301,7 +301,7 @@ begin_binning( struct setup_context *setup ) static void execute_clears( struct setup_context *setup ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); begin_binning( setup ); rasterize_bins( setup, TRUE ); @@ -317,7 +317,7 @@ set_state( struct setup_context *setup, if (old_state == new_state) return; - SETUP_DEBUG("%s old %d new %d\n", __FUNCTION__, old_state, new_state); + LP_DBG(DEBUG_SETUP, "%s old %d new %d\n", __FUNCTION__, old_state, new_state); switch (new_state) { case SETUP_ACTIVE: @@ -347,7 +347,7 @@ void lp_setup_flush( struct setup_context *setup, unsigned flags ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); set_state( setup, SETUP_FLUSHED ); } @@ -358,7 +358,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, struct pipe_surface *color, struct pipe_surface *zstencil ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); set_state( setup, SETUP_FLUSHED ); @@ -401,7 +401,7 @@ lp_setup_clear( struct setup_context *setup, { unsigned i; - SETUP_DEBUG("%s state %d\n", __FUNCTION__, setup->state); + LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); if (flags & PIPE_CLEAR_COLOR) { @@ -451,7 +451,7 @@ lp_setup_set_triangle_state( struct setup_context *setup, unsigned cull_mode, boolean ccw_is_frontface) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); setup->ccw_is_frontface = ccw_is_frontface; setup->cullmode = cull_mode; @@ -465,7 +465,7 @@ lp_setup_set_fs_inputs( struct setup_context *setup, const struct lp_shader_input *input, unsigned nr ) { - SETUP_DEBUG("%s %p %u\n", __FUNCTION__, (void *) input, nr); + LP_DBG(DEBUG_SETUP, "%s %p %u\n", __FUNCTION__, (void *) input, nr); memcpy( setup->fs.input, input, nr * sizeof input[0] ); setup->fs.nr_inputs = nr; @@ -475,7 +475,7 @@ void lp_setup_set_fs( struct setup_context *setup, struct lp_fragment_shader *fs ) { - SETUP_DEBUG("%s %p\n", __FUNCTION__, (void *) fs); + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) fs); /* FIXME: reference count */ setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL; @@ -486,7 +486,7 @@ void lp_setup_set_fs_constants(struct setup_context *setup, struct pipe_buffer *buffer) { - SETUP_DEBUG("%s %p\n", __FUNCTION__, (void *) buffer); + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer); pipe_buffer_reference(&setup->constants.current, buffer); @@ -498,7 +498,7 @@ void lp_setup_set_alpha_ref_value( struct setup_context *setup, float alpha_ref_value ) { - SETUP_DEBUG("%s %f\n", __FUNCTION__, alpha_ref_value); + LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value); if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) { setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value; @@ -510,7 +510,7 @@ void lp_setup_set_blend_color( struct setup_context *setup, const struct pipe_blend_color *blend_color ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); assert(blend_color); @@ -527,7 +527,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, struct pipe_texture *dummy; unsigned i; - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); assert(num <= PIPE_MAX_SAMPLERS); @@ -569,7 +569,7 @@ lp_setup_is_texture_referenced( struct setup_context *setup, static INLINE void lp_setup_update_shader_state( struct setup_context *setup ) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); assert(setup->fs.current.jit_function); @@ -685,7 +685,7 @@ lp_setup_tri(struct setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { - SETUP_DEBUG("%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); lp_setup_update_shader_state(setup); setup->triangle( setup, v0, v1, v2 ); -- cgit v1.2.3 From 9fca3e065b9ab5ef1389a76934bc24ed2b287a76 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 14:22:08 -0700 Subject: llvmpipe: simplify framebuffer state code --- src/gallium/drivers/llvmpipe/lp_setup.c | 29 +++++++++++++++---------- src/gallium/drivers/llvmpipe/lp_setup.h | 5 ++--- src/gallium/drivers/llvmpipe/lp_setup_context.h | 7 +----- src/gallium/drivers/llvmpipe/lp_state_surface.c | 4 +--- 4 files changed, 21 insertions(+), 24 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 7f31df6ae5..38609ec88a 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -241,12 +241,12 @@ rasterize_bins( struct setup_context *setup, LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); lp_rast_begin( rast, - setup->fb.cbuf, - setup->fb.zsbuf, - setup->fb.cbuf != NULL, - setup->fb.zsbuf != NULL && write_depth, - setup->fb.width, - setup->fb.height ); + setup->fb->cbufs[0], + setup->fb->zsbuf, + setup->fb->cbufs[0] != NULL, + setup->fb->zsbuf != NULL && write_depth, + setup->fb->width, + setup->fb->height ); /* loop over tile bins, rasterize each */ for (i = 0; i < setup->tiles_x; i++) { @@ -271,7 +271,7 @@ begin_binning( struct setup_context *setup ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (setup->fb.cbuf) { + if (setup->fb->cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) bin_everywhere( setup, lp_rast_clear_color, @@ -280,7 +280,7 @@ begin_binning( struct setup_context *setup ) bin_everywhere( setup, lp_rast_load_color, lp_rast_arg_null() ); } - if (setup->fb.zsbuf) { + if (setup->fb->zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) bin_everywhere( setup, lp_rast_clear_zstencil, @@ -355,13 +355,13 @@ lp_setup_flush( struct setup_context *setup, void lp_setup_bind_framebuffer( struct setup_context *setup, - struct pipe_surface *color, - struct pipe_surface *zstencil ) + const struct pipe_framebuffer_state *fb ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); set_state( setup, SETUP_FLUSHED ); +#if 0 pipe_surface_reference( &setup->fb.cbuf, color ); pipe_surface_reference( &setup->fb.zsbuf, zstencil ); @@ -386,9 +386,14 @@ lp_setup_bind_framebuffer( struct setup_context *setup, setup->fb.height = MIN2(setup->fb.cbuf->height, setup->fb.zsbuf->height); } - setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE; setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE; +#else + setup->fb = fb; + setup->tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; + setup->tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; +#endif + } @@ -411,7 +416,7 @@ lp_setup_clear( struct setup_context *setup, if (flags & PIPE_CLEAR_DEPTHSTENCIL) { setup->clear.zstencil.clear_zstencil = - util_pack_z_stencil(setup->fb.zsbuf->format, + util_pack_z_stencil(setup->fb->zsbuf->format, depth, stencil); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 1edd7410fc..66a7f29f1e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -53,7 +53,7 @@ struct pipe_surface; struct pipe_buffer; struct pipe_blend_color; struct pipe_screen; -struct setup_context; +struct pipe_framebuffer_state; struct lp_fragment_shader; struct lp_jit_context; @@ -90,8 +90,7 @@ lp_setup_flush( struct setup_context *setup, void lp_setup_bind_framebuffer( struct setup_context *setup, - struct pipe_surface *color, - struct pipe_surface *zstencil ); + const struct pipe_framebuffer_state *fb ); void lp_setup_set_triangle_state( struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 180b8f6e88..dc12eb7847 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -79,12 +79,7 @@ struct setup_context { boolean ccw_is_frontface; unsigned cullmode; - struct { - struct pipe_surface *cbuf; - struct pipe_surface *zsbuf; - unsigned width; - unsigned height; - } fb; + const struct pipe_framebuffer_state *fb; struct { unsigned flags; diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index 909ca9f117..3eff40e3f1 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -83,9 +83,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, } if (dirty) { - lp_setup_bind_framebuffer( lp->setup, - fb->cbufs[0], - fb->zsbuf ); + lp_setup_bind_framebuffer( lp->setup, fb ); lp->dirty |= LP_NEW_FRAMEBUFFER; } -- cgit v1.2.3 From b533b56750aca8c7e8cb22af93a0fc2a0cfc0d97 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 14:47:40 -0700 Subject: llvmpipe: move lp_rasterize_bin() into lp_rast.c First step of moving bin rasterization/execution code out of lp_setup.c --- src/gallium/drivers/llvmpipe/lp_rast.c | 37 +++++++++++++++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 18 ++++++---------- src/gallium/drivers/llvmpipe/lp_setup.c | 29 +++----------------------- 3 files changed, 42 insertions(+), 42 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 5891a2a706..a466aec379 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -33,6 +33,7 @@ #include "lp_rast_priv.h" #include "lp_tile_soa.h" #include "lp_bld_debug.h" +#include "lp_bin.h" struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) @@ -148,9 +149,9 @@ void lp_rast_end( struct lp_rasterizer *rast ) * \param x window X position of the tile, in pixels * \param y window Y position of the tile, in pixels */ -void lp_rast_start_tile( struct lp_rasterizer *rast, - unsigned x, - unsigned y ) +static void +lp_rast_start_tile( struct lp_rasterizer *rast, + unsigned x, unsigned y ) { LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); @@ -453,7 +454,8 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) /** * Write the rasterizer's tiles to the framebuffer. */ -void lp_rast_end_tile( struct lp_rasterizer *rast ) +static void +lp_rast_end_tile( struct lp_rasterizer *rast ) { LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -465,6 +467,33 @@ void lp_rast_end_tile( struct lp_rasterizer *rast ) } +/** + * Rasterize commands for a single bin. + * Must be called between lp_rast_begin() and lp_rast_end(). + */ +void +lp_rasterize_bin( struct lp_rasterizer *rast, + const struct cmd_bin *bin, + int x, int y) +{ + const struct cmd_block_list *commands = &bin->commands; + struct cmd_block *block; + unsigned k; + + lp_rast_start_tile( rast, x, y ); + + /* simply execute each of the commands in the block list */ + for (block = commands->head; block; block = block->next) { + for (k = 0; k < block->count; k++) { + block->cmd[k]( rast, block->arg[k] ); + } + } + + lp_rast_end_tile( rast ); +} + + + /* Shutdown: */ void lp_rast_destroy( struct lp_rasterizer *rast ) diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 21bbf104b1..3d2388b894 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -47,6 +47,7 @@ * individual function calls like this. */ struct lp_rasterizer; +struct cmd_bin; struct pipe_screen; #define FIXED_ORDER 4 @@ -141,14 +142,13 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, unsigned width, unsigned height ); -void lp_rast_end( struct lp_rasterizer * ); +void +lp_rasterize_bin( struct lp_rasterizer *rast, + const struct cmd_bin *bin, + int x, int y); -/* Begining of each tile: - */ -void lp_rast_start_tile( struct lp_rasterizer *, - unsigned x, - unsigned y ); +void lp_rast_end( struct lp_rasterizer * ); union lp_rast_cmd_arg { @@ -224,10 +224,4 @@ void lp_rast_shade_tile( struct lp_rasterizer *, const union lp_rast_cmd_arg ); -/* End of tile: - */ - -void lp_rast_end_tile( struct lp_rasterizer *rast ); - - #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 38609ec88a..47d2ac8e11 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -207,29 +207,6 @@ bin_state_command( struct setup_context *setup, } -/** Rasterize commands for a single bin */ -static void -rasterize_bin( struct lp_rasterizer *rast, - const struct cmd_bin *bin, - int x, int y) -{ - const struct cmd_block_list *commands = &bin->commands; - struct cmd_block *block; - unsigned k; - - lp_rast_start_tile( rast, x, y ); - - /* simply execute each of the commands in the block list */ - for (block = commands->head; block; block = block->next) { - for (k = 0; k < block->count; k++) { - block->cmd[k]( rast, block->arg[k] ); - } - } - - lp_rast_end_tile( rast ); -} - - /** Rasterize all tile's bins */ static void rasterize_bins( struct setup_context *setup, @@ -251,9 +228,9 @@ rasterize_bins( struct setup_context *setup, /* loop over tile bins, rasterize each */ for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { - rasterize_bin( rast, &setup->tile[i][j], - i * TILE_SIZE, - j * TILE_SIZE ); + lp_rasterize_bin( rast, &setup->tile[i][j], + i * TILE_SIZE, + j * TILE_SIZE ); } } -- cgit v1.2.3 From 01b1900084152dbacd4025a31ced25f75666ce59 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 15:31:09 -0700 Subject: llvmpipe: reorganization of binning data structions and funtions New lp_bins struct contains all bin information. More move bin-related code into lp_bin.[ch] Use new/updated bin-access functions to hide implementation details. The result is more/cleaner separation between the setup and rast components. This will make double-buffering of the bins easier, etc. --- src/gallium/drivers/llvmpipe/lp_bin.c | 78 +++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_bin.h | 61 +++++++++++++--- src/gallium/drivers/llvmpipe/lp_rast.c | 51 ++++++++++++-- src/gallium/drivers/llvmpipe/lp_rast.h | 21 ++---- src/gallium/drivers/llvmpipe/lp_setup.c | 93 ++++--------------------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 17 +---- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 26 +++---- 7 files changed, 209 insertions(+), 138 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c index f43cdcbf3d..1f05416b3e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.c +++ b/src/gallium/drivers/llvmpipe/lp_bin.c @@ -29,6 +29,84 @@ #include "lp_bin.h" +void +lp_init_bins(struct lp_bins *bins) +{ + unsigned i, j; + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_get_bin(bins, i, j); + bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); + } + + bins->data.head = + bins->data.tail = CALLOC_STRUCT(data_block); +} + + +void +lp_reset_bins(struct lp_bins *bins, unsigned tiles_x, unsigned tiles_y) +{ + unsigned i, j; + + /* Free all but last binner command lists: + */ + for (i = 0; i < tiles_x; i++) { + for (j = 0; j < tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(bins, i, j); + struct cmd_block_list *list = &bin->commands; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->count = 0; + } + } + + /* Free all but last binned data block: + */ + { + struct data_block_list *list = &bins->data; + struct data_block *block, *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->used = 0; + } +} + + +void +lp_free_bin_data(struct lp_bins *bins) +{ + unsigned i, j; + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_get_bin(bins, i, j); + /* lp_reset_bins() should have been already called */ + assert(bin->commands.head == bin->commands.tail); + FREE(bin->commands.head); + bin->commands.head = NULL; + bin->commands.tail = NULL; + } + + FREE(bins->data.head); + bins->data.head = NULL; +} + + void lp_bin_new_cmd_block( struct cmd_block_list *list ) { diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h index fa25d78631..4d12b93274 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -35,9 +35,19 @@ #ifndef LP_BIN_H #define LP_BIN_H +#include "lp_tile_soa.h" #include "lp_rast.h" +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. + */ +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 +#define TILES_X (MAXWIDTH / TILE_SIZE) +#define TILES_Y (MAXHEIGHT / TILE_SIZE) + + #define CMD_BLOCK_MAX 128 #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) @@ -84,19 +94,40 @@ struct data_block_list { }; +/** + * All bins and bin data are contained here. + * Per-bin data goes into the 'tile' bins. + * Shared bin data goes into the 'data' buffer. + * When there are multiple threads, will want to double-buffer the + * bin arrays: + */ +struct lp_bins { + struct cmd_bin tile[TILES_X][TILES_Y]; + struct data_block_list data; +}; + + + +void lp_init_bins(struct lp_bins *bins); -extern void lp_bin_new_data_block( struct data_block_list *list ); +void lp_reset_bins(struct lp_bins *bins, unsigned tiles_x, unsigned tiles_y); -extern void lp_bin_new_cmd_block( struct cmd_block_list *list ); +void lp_free_bin_data(struct lp_bins *bins); + +void lp_bin_new_data_block( struct data_block_list *list ); + +void lp_bin_new_cmd_block( struct cmd_block_list *list ); /** - * Allocate space for a command/data in the given block list. + * Allocate space for a command/data in the bin's data buffer. * Grow the block list if needed. */ static INLINE void * -lp_bin_alloc( struct data_block_list *list, unsigned size) +lp_bin_alloc( struct lp_bins *bins, unsigned size) { + struct data_block_list *list = &bins->data; + if (list->tail->used + size > DATA_BLOCK_SIZE) { lp_bin_new_data_block( list ); } @@ -114,9 +145,11 @@ lp_bin_alloc( struct data_block_list *list, unsigned size) * As above, but with specific alignment. */ static INLINE void * -lp_bin_alloc_aligned( struct data_block_list *list, unsigned size, +lp_bin_alloc_aligned( struct lp_bins *bins, unsigned size, unsigned alignment ) { + struct data_block_list *list = &bins->data; + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { lp_bin_new_data_block( list ); } @@ -134,20 +167,32 @@ lp_bin_alloc_aligned( struct data_block_list *list, unsigned size, /* Put back data if we decide not to use it, eg. culled triangles. */ static INLINE void -lp_bin_putback_data( struct data_block_list *list, unsigned size) +lp_bin_putback_data( struct lp_bins *bins, unsigned size) { + struct data_block_list *list = &bins->data; assert(list->tail->used >= size); list->tail->used -= size; } -/* Add a command to a given bin. +/** Return pointer to a particular tile's bin. */ +static INLINE struct cmd_bin * +lp_get_bin(struct lp_bins *bins, unsigned x, unsigned y) +{ + return &bins->tile[x][y]; +} + + + +/* Add a command to bin[x][y]. */ static INLINE void -lp_bin_command( struct cmd_bin *bin, +lp_bin_command( struct lp_bins *bins, + unsigned x, unsigned y, lp_rast_cmd cmd, union lp_rast_cmd_arg arg ) { + struct cmd_bin *bin = lp_get_bin(bins, x, y); struct cmd_block_list *list = &bin->commands; if (list->tail->count == CMD_BLOCK_MAX) { diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index a466aec379..87e3bfcd3f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -56,7 +56,8 @@ struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) * Begin the rasterization phase. * Map the framebuffer surfaces. Initialize the 'rast' state. */ -boolean lp_rast_begin( struct lp_rasterizer *rast, +static boolean +lp_rast_begin( struct lp_rasterizer *rast, struct pipe_surface *cbuf, struct pipe_surface *zsbuf, boolean write_color, @@ -121,7 +122,8 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, * Finish the rasterization phase. * Unmap framebuffer surfaces. */ -void lp_rast_end( struct lp_rasterizer *rast ) +static void +lp_rast_end( struct lp_rasterizer *rast ) { struct pipe_screen *screen = rast->screen; @@ -469,12 +471,13 @@ lp_rast_end_tile( struct lp_rasterizer *rast ) /** * Rasterize commands for a single bin. + * \param x, y position of the bin's tile in the framebuffer * Must be called between lp_rast_begin() and lp_rast_end(). */ -void -lp_rasterize_bin( struct lp_rasterizer *rast, - const struct cmd_bin *bin, - int x, int y) +static void +rasterize_bin( struct lp_rasterizer *rast, + const struct cmd_bin *bin, + int x, int y) { const struct cmd_block_list *commands = &bin->commands; struct cmd_block *block; @@ -493,6 +496,42 @@ lp_rasterize_bin( struct lp_rasterizer *rast, } +/** + * Rasterize/execute all bins. + */ +void +lp_rasterize_bins( struct lp_rasterizer *rast, + struct lp_bins *bins, + unsigned tiles_x, unsigned tiles_y, + const struct pipe_framebuffer_state *fb, + bool write_depth ) +{ + unsigned i, j; + + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + + lp_rast_begin( rast, + fb->cbufs[0], + fb->zsbuf, + fb->cbufs[0] != NULL, + fb->zsbuf != NULL && write_depth, + fb->width, + fb->height ); + + /* loop over tile bins, rasterize each */ + for (i = 0; i < tiles_x; i++) { + for (j = 0; j < tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(bins, i, j); + rasterize_bin( rast, bin, i * TILE_SIZE, j * TILE_SIZE ); + } + } + + lp_rast_end( rast ); + + LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); +} + + /* Shutdown: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 3d2388b894..e623eafc9a 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -47,6 +47,7 @@ * individual function calls like this. */ struct lp_rasterizer; +struct lp_bins; struct cmd_bin; struct pipe_screen; @@ -133,22 +134,12 @@ struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ); void lp_rast_destroy( struct lp_rasterizer * ); +void lp_rasterize_bins( struct lp_rasterizer *rast, + struct lp_bins *bins, + unsigned tiles_x, unsigned tiles_y, + const struct pipe_framebuffer_state *fb, + bool write_depth ); -boolean lp_rast_begin( struct lp_rasterizer *rast, - struct pipe_surface *cbuf, - struct pipe_surface *zsbuf, - boolean write_color, - boolean write_zstencil, - unsigned width, - unsigned height ); - -void -lp_rasterize_bin( struct lp_rasterizer *rast, - const struct cmd_bin *bin, - int x, int y); - - -void lp_rast_end( struct lp_rasterizer * ); union lp_rast_cmd_arg { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 47d2ac8e11..efaf5acfe8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -80,8 +80,6 @@ first_point( struct setup_context *setup, static void reset_context( struct setup_context *setup ) { - unsigned i, j; - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); /* Reset derived state */ @@ -90,40 +88,7 @@ static void reset_context( struct setup_context *setup ) setup->fs.stored = NULL; setup->dirty = ~0; - /* Free all but last binner command lists: - */ - for (i = 0; i < setup->tiles_x; i++) { - for (j = 0; j < setup->tiles_y; j++) { - struct cmd_block_list *list = &setup->tile[i][j].commands; - struct cmd_block *block; - struct cmd_block *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->count = 0; - } - } - - /* Free all but last binned data block: - */ - { - struct data_block_list *list = &setup->data; - struct data_block *block, *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->used = 0; - } + lp_reset_bins(&setup->bins, setup->tiles_x, setup->tiles_y); /* Reset some state: */ @@ -177,7 +142,7 @@ static void bin_everywhere( struct setup_context *setup, unsigned i, j; for (i = 0; i < setup->tiles_x; i++) for (j = 0; j < setup->tiles_y; j++) - lp_bin_command( &setup->tile[i][j], cmd, arg ); + lp_bin_command( &setup->bins, i, j, cmd, arg ); } @@ -194,13 +159,13 @@ bin_state_command( struct setup_context *setup, unsigned i, j; for (i = 0; i < setup->tiles_x; i++) { for (j = 0; j < setup->tiles_y; j++) { - struct cmd_bin *bin = &setup->tile[i][j]; + struct cmd_bin *bin = &setup->bins.tile[i][j]; lp_rast_cmd last_cmd = lp_get_last_command(bin); if (last_cmd == cmd) { lp_replace_last_command_arg(bin, arg); } else { - lp_bin_command( bin, cmd, arg ); + lp_bin_command( &setup->bins, i, j, cmd, arg ); } } } @@ -212,29 +177,10 @@ static void rasterize_bins( struct setup_context *setup, boolean write_depth ) { - struct lp_rasterizer *rast = setup->rast; - unsigned i, j; - - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - - lp_rast_begin( rast, - setup->fb->cbufs[0], - setup->fb->zsbuf, - setup->fb->cbufs[0] != NULL, - setup->fb->zsbuf != NULL && write_depth, - setup->fb->width, - setup->fb->height ); - - /* loop over tile bins, rasterize each */ - for (i = 0; i < setup->tiles_x; i++) { - for (j = 0; j < setup->tiles_y; j++) { - lp_rasterize_bin( rast, &setup->tile[i][j], - i * TILE_SIZE, - j * TILE_SIZE ); - } - } - - lp_rast_end( rast ); + lp_rasterize_bins(setup->rast, + &setup->bins, setup->tiles_x, setup->tiles_y, + setup->fb, + write_depth); reset_context( setup ); @@ -559,7 +505,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) uint8_t *stored; unsigned i, j; - stored = lp_bin_alloc_aligned(&setup->data, 4 * 16, 16); + stored = lp_bin_alloc_aligned(&setup->bins, 4 * 16, 16); /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { @@ -591,7 +537,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) current_size) != 0) { void *stored; - stored = lp_bin_alloc(&setup->data, current_size); + stored = lp_bin_alloc(&setup->bins, current_size); if(stored) { memcpy(stored, current_data, @@ -621,7 +567,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) * and append it to the bin's setup data buffer. */ struct lp_rast_state *stored = - (struct lp_rast_state *) lp_bin_alloc(&setup->data, sizeof *stored); + (struct lp_rast_state *) lp_bin_alloc(&setup->bins, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, @@ -677,17 +623,11 @@ lp_setup_tri(struct setup_context *setup, void lp_setup_destroy( struct setup_context *setup ) { - unsigned i, j; - reset_context( setup ); pipe_buffer_reference(&setup->constants.current, NULL); - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) - FREE(setup->tile[i][j].commands.head); - - FREE(setup->data.head); + lp_free_bin_data(&setup->bins); lp_rast_destroy( setup->rast ); FREE( setup ); @@ -702,19 +642,12 @@ struct setup_context * lp_setup_create( struct pipe_screen *screen ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); - unsigned i, j; setup->rast = lp_rast_create( screen ); if (!setup->rast) goto fail; - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) - setup->tile[i][j].commands.head = - setup->tile[i][j].commands.tail = CALLOC_STRUCT(cmd_block); - - setup->data.head = - setup->data.tail = CALLOC_STRUCT(data_block); + lp_init_bins(&setup->bins); setup->triangle = first_triangle; setup->line = first_line; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index dc12eb7847..8478bb9014 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -40,14 +40,6 @@ #include "lp_tile_soa.h" /* for TILE_SIZE */ #include "lp_bin.h" -/* We're limited to 2K by 2K for 32bit fixed point rasterization. - * Will need a 64-bit version for larger framebuffers. - */ -#define MAXHEIGHT 2048 -#define MAXWIDTH 2048 -#define TILES_X (MAXWIDTH / TILE_SIZE) -#define TILES_Y (MAXHEIGHT / TILE_SIZE) - #define LP_SETUP_NEW_FS 0x01 #define LP_SETUP_NEW_CONSTANTS 0x02 @@ -63,14 +55,7 @@ struct setup_context { struct lp_rasterizer *rast; - /** - * Per-bin data goes into the 'tile' bins. - * Shared bin data goes into the 'data' buffer. - * When there are multiple threads, will want to double-buffer the - * bin arrays: - */ - struct cmd_bin tile[TILES_X][TILES_Y]; - struct data_block_list data; + struct lp_bins bins; /* size of framebuffer, in tiles */ unsigned tiles_x; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 5e53b4050e..b8f79849e8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -185,9 +185,9 @@ static void setup_tri_coefficients( struct setup_context *setup, { unsigned bytes; bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float); - tri->inputs.a0 = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); - tri->inputs.dadx = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); - tri->inputs.dady = lp_bin_alloc_aligned( &setup->data, bytes, 16 ); + tri->inputs.a0 = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); + tri->inputs.dadx = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); + tri->inputs.dady = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); } /* The internal position input is in slot zero: @@ -263,7 +263,7 @@ do_triangle_ccw(struct setup_context *setup, const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - struct lp_rast_triangle *tri = lp_bin_alloc( &setup->data, sizeof *tri ); + struct lp_rast_triangle *tri = lp_bin_alloc( &setup->bins, sizeof *tri ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -283,7 +283,7 @@ do_triangle_ccw(struct setup_context *setup, * XXX: subject to overflow?? */ if (area <= 0) { - lp_bin_putback_data( &setup->data, sizeof *tri ); + lp_bin_putback_data( &setup->bins, sizeof *tri ); return; } @@ -295,7 +295,7 @@ do_triangle_ccw(struct setup_context *setup, if (tri->miny == tri->maxy || tri->minx == tri->maxx) { - lp_bin_putback_data( &setup->data, sizeof *tri ); + lp_bin_putback_data( &setup->bins, sizeof *tri ); return; } @@ -405,7 +405,7 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - lp_bin_command( &setup->tile[minx][miny], lp_rast_triangle, + lp_bin_command( &setup->bins, minx, miny, lp_rast_triangle, lp_rast_arg_triangle(tri) ); } else @@ -464,17 +464,17 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ - lp_bin_command( &setup->tile[x][y], - lp_rast_shade_tile, - lp_rast_arg_inputs(&tri->inputs) ); + lp_bin_command( &setup->bins, x, y, + lp_rast_shade_tile, + lp_rast_arg_inputs(&tri->inputs) ); } else { in = 1; /* shade partial tile */ - lp_bin_command( &setup->tile[x][y], - lp_rast_triangle, - lp_rast_arg_triangle(tri) ); + lp_bin_command( &setup->bins, x, y, + lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } /* Iterate cx values across the region: -- cgit v1.2.3 From 2c8d5c66ce2ddc0b7182e4844690736fc4c47212 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 15:46:37 -0700 Subject: llvmpipe: remove dead code left over from a previous commit --- src/gallium/drivers/llvmpipe/lp_setup.c | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index efaf5acfe8..e561e8e9b6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -284,39 +284,9 @@ lp_setup_bind_framebuffer( struct setup_context *setup, set_state( setup, SETUP_FLUSHED ); -#if 0 - pipe_surface_reference( &setup->fb.cbuf, color ); - pipe_surface_reference( &setup->fb.zsbuf, zstencil ); - - if (!setup->fb.cbuf && !setup->fb.zsbuf) { - setup->fb.width = 0; - setup->fb.height = 0; - } - else if (!setup->fb.zsbuf) { - setup->fb.width = setup->fb.cbuf->width; - setup->fb.height = setup->fb.cbuf->height; - } - else if (!setup->fb.cbuf) { - setup->fb.width = setup->fb.zsbuf->width; - setup->fb.height = setup->fb.zsbuf->height; - } - else { - /* XXX: not sure what we're really supposed to do for - * mis-matched color & depth buffer sizes. - */ - setup->fb.width = MIN2(setup->fb.cbuf->width, - setup->fb.zsbuf->width); - setup->fb.height = MIN2(setup->fb.cbuf->height, - setup->fb.zsbuf->height); - } - setup->tiles_x = align(setup->fb.width, TILE_SIZE) / TILE_SIZE; - setup->tiles_y = align(setup->fb.height, TILE_SIZE) / TILE_SIZE; -#else setup->fb = fb; setup->tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; setup->tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; -#endif - } -- cgit v1.2.3 From 8a23105fa016ec4368f407ca64e7763f110da4e5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Dec 2009 15:59:25 -0700 Subject: llvmpipe: still more bin code reorganization Move tiles_x,y fields from setup state into bin state. Move more bin-adding commands into lp_bin.[ch]. --- src/gallium/drivers/llvmpipe/lp_bin.c | 70 +++++++++++++- src/gallium/drivers/llvmpipe/lp_bin.h | 32 ++++++- src/gallium/drivers/llvmpipe/lp_rast.c | 5 +- src/gallium/drivers/llvmpipe/lp_rast.h | 1 - src/gallium/drivers/llvmpipe/lp_setup.c | 120 ++++++------------------ src/gallium/drivers/llvmpipe/lp_setup_context.h | 4 - 6 files changed, 130 insertions(+), 102 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c index 1f05416b3e..160a8d865b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.c +++ b/src/gallium/drivers/llvmpipe/lp_bin.c @@ -45,14 +45,14 @@ lp_init_bins(struct lp_bins *bins) void -lp_reset_bins(struct lp_bins *bins, unsigned tiles_x, unsigned tiles_y) +lp_reset_bins(struct lp_bins *bins ) { unsigned i, j; /* Free all but last binner command lists: */ - for (i = 0; i < tiles_x; i++) { - for (j = 0; j < tiles_y; j++) { + for (i = 0; i < bins->tiles_x; i++) { + for (j = 0; j < bins->tiles_y; j++) { struct cmd_bin *bin = lp_get_bin(bins, i, j); struct cmd_block_list *list = &bin->commands; struct cmd_block *block; @@ -107,6 +107,14 @@ lp_free_bin_data(struct lp_bins *bins) } +void +lp_bin_set_num_bins( struct lp_bins *bins, + unsigned tiles_x, unsigned tiles_y ) +{ + bins->tiles_x = tiles_x; + bins->tiles_y = tiles_y; +} + void lp_bin_new_cmd_block( struct cmd_block_list *list ) { @@ -127,3 +135,59 @@ lp_bin_new_data_block( struct data_block_list *list ) block->next = NULL; block->used = 0; } + + +/** + * Return last command in the bin + */ +static lp_rast_cmd +lp_get_last_command( const struct cmd_bin *bin ) +{ + const struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + if (i > 0) + return tail->cmd[i - 1]; + else + return NULL; +} + + +/** + * Replace the arg of the last command in the bin. + */ +static void +lp_replace_last_command_arg( struct cmd_bin *bin, + const union lp_rast_cmd_arg arg ) +{ + struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + assert(i > 0); + tail->arg[i - 1] = arg; +} + + + +/** + * Put a state-change command into all bins. + * If we find that the last command in a bin was also a state-change + * command, we can simply replace that one with the new one. + */ +void +lp_bin_state_command( struct lp_bins *bins, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < bins->tiles_x; i++) { + for (j = 0; j < bins->tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(bins, i, j); + lp_rast_cmd last_cmd = lp_get_last_command(bin); + if (last_cmd == cmd) { + lp_replace_last_command_arg(bin, arg); + } + else { + lp_bin_command( bins, i, j, cmd, arg ); + } + } + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h index 4d12b93274..fcbb975ad6 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -104,16 +104,26 @@ struct data_block_list { struct lp_bins { struct cmd_bin tile[TILES_X][TILES_Y]; struct data_block_list data; + + /** + * Number of active tiles in each dimension. + * This basically the framebuffer size divided by tile size + */ + unsigned tiles_x, tiles_y; }; void lp_init_bins(struct lp_bins *bins); -void lp_reset_bins(struct lp_bins *bins, unsigned tiles_x, unsigned tiles_y); +void lp_reset_bins(struct lp_bins *bins ); void lp_free_bin_data(struct lp_bins *bins); +void +lp_bin_set_num_bins( struct lp_bins *bins, + unsigned tiles_x, unsigned tiles_y ); + void lp_bin_new_data_block( struct data_block_list *list ); void lp_bin_new_cmd_block( struct cmd_block_list *list ); @@ -209,4 +219,24 @@ lp_bin_command( struct lp_bins *bins, } +/* Add a command to all active bins. + */ +static INLINE void +lp_bin_everywhere( struct lp_bins *bins, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < bins->tiles_x; i++) + for (j = 0; j < bins->tiles_y; j++) + lp_bin_command( bins, i, j, cmd, arg ); +} + + +void +lp_bin_state_command( struct lp_bins *bins, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ); + + #endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 87e3bfcd3f..642f1b9079 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -502,7 +502,6 @@ rasterize_bin( struct lp_rasterizer *rast, void lp_rasterize_bins( struct lp_rasterizer *rast, struct lp_bins *bins, - unsigned tiles_x, unsigned tiles_y, const struct pipe_framebuffer_state *fb, bool write_depth ) { @@ -519,8 +518,8 @@ lp_rasterize_bins( struct lp_rasterizer *rast, fb->height ); /* loop over tile bins, rasterize each */ - for (i = 0; i < tiles_x; i++) { - for (j = 0; j < tiles_y; j++) { + for (i = 0; i < bins->tiles_x; i++) { + for (j = 0; j < bins->tiles_y; j++) { struct cmd_bin *bin = lp_get_bin(bins, i, j); rasterize_bin( rast, bin, i * TILE_SIZE, j * TILE_SIZE ); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index e623eafc9a..e77c77b776 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -136,7 +136,6 @@ void lp_rast_destroy( struct lp_rasterizer * ); void lp_rasterize_bins( struct lp_rasterizer *rast, struct lp_bins *bins, - unsigned tiles_x, unsigned tiles_y, const struct pipe_framebuffer_state *fb, bool write_depth ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index e561e8e9b6..4935d5b540 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -88,7 +88,7 @@ static void reset_context( struct setup_context *setup ) setup->fs.stored = NULL; setup->dirty = ~0; - lp_reset_bins(&setup->bins, setup->tiles_x, setup->tiles_y); + lp_reset_bins( &setup->bins ); /* Reset some state: */ @@ -103,82 +103,13 @@ static void reset_context( struct setup_context *setup ) } -/** - * Return last command in the bin - */ -static lp_rast_cmd -lp_get_last_command( const struct cmd_bin *bin ) -{ - const struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - if (i > 0) - return tail->cmd[i - 1]; - else - return NULL; -} - - -/** - * Replace the arg of the last command in the bin. - */ -static void -lp_replace_last_command_arg( struct cmd_bin *bin, - const union lp_rast_cmd_arg arg ) -{ - struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - assert(i > 0); - tail->arg[i - 1] = arg; -} - - - -/* Add a command to all active bins. - */ -static void bin_everywhere( struct setup_context *setup, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < setup->tiles_x; i++) - for (j = 0; j < setup->tiles_y; j++) - lp_bin_command( &setup->bins, i, j, cmd, arg ); -} - - -/** - * Put a state-change command into all bins. - * If we find that the last command in a bin was also a state-change - * command, we can simply replace that one with the new one. - */ -static void -bin_state_command( struct setup_context *setup, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < setup->tiles_x; i++) { - for (j = 0; j < setup->tiles_y; j++) { - struct cmd_bin *bin = &setup->bins.tile[i][j]; - lp_rast_cmd last_cmd = lp_get_last_command(bin); - if (last_cmd == cmd) { - lp_replace_last_command_arg(bin, arg); - } - else { - lp_bin_command( &setup->bins, i, j, cmd, arg ); - } - } - } -} - - /** Rasterize all tile's bins */ static void rasterize_bins( struct setup_context *setup, boolean write_depth ) { lp_rasterize_bins(setup->rast, - &setup->bins, setup->tiles_x, setup->tiles_y, + &setup->bins, setup->fb, write_depth); @@ -196,20 +127,24 @@ begin_binning( struct setup_context *setup ) if (setup->fb->cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) - bin_everywhere( setup, - lp_rast_clear_color, - setup->clear.color ); + lp_bin_everywhere( &setup->bins, + lp_rast_clear_color, + setup->clear.color ); else - bin_everywhere( setup, lp_rast_load_color, lp_rast_arg_null() ); + lp_bin_everywhere( &setup->bins, + lp_rast_load_color, + lp_rast_arg_null() ); } if (setup->fb->zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - bin_everywhere( setup, - lp_rast_clear_zstencil, - setup->clear.zstencil ); + lp_bin_everywhere( &setup->bins, + lp_rast_clear_zstencil, + setup->clear.zstencil ); else - bin_everywhere( setup, lp_rast_load_zstencil, lp_rast_arg_null() ); + lp_bin_everywhere( &setup->bins, + lp_rast_load_zstencil, + lp_rast_arg_null() ); } LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__); @@ -280,13 +215,18 @@ void lp_setup_bind_framebuffer( struct setup_context *setup, const struct pipe_framebuffer_state *fb ) { + unsigned tiles_x, tiles_y; + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); set_state( setup, SETUP_FLUSHED ); setup->fb = fb; - setup->tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; - setup->tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; + + tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; + tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; + + lp_bin_set_num_bins(&setup->bins, tiles_x, tiles_y); } @@ -321,14 +261,14 @@ lp_setup_clear( struct setup_context *setup, * don't see that as being a common usage. */ if (flags & PIPE_CLEAR_COLOR) - bin_everywhere( setup, - lp_rast_clear_color, - setup->clear.color ); + lp_bin_everywhere( &setup->bins, + lp_rast_clear_color, + setup->clear.color ); if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - bin_everywhere( setup, - lp_rast_clear_zstencil, - setup->clear.zstencil ); + lp_bin_everywhere( &setup->bins, + lp_rast_clear_zstencil, + setup->clear.zstencil ); } else { /* Put ourselves into the 'pre-clear' state, specifically to try @@ -545,9 +485,9 @@ lp_setup_update_shader_state( struct setup_context *setup ) setup->fs.stored = stored; /* put the state-set command into all bins */ - bin_state_command( setup, - lp_rast_set_state, - lp_rast_arg_state(setup->fs.stored) ); + lp_bin_state_command( &setup->bins, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); } } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 8478bb9014..9b47b595c6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -57,10 +57,6 @@ struct setup_context { struct lp_bins bins; - /* size of framebuffer, in tiles */ - unsigned tiles_x; - unsigned tiles_y; - boolean ccw_is_frontface; unsigned cullmode; -- cgit v1.2.3 From 22b07b8be4c2939b00e10f17fa91e68682808594 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Dec 2009 12:28:54 -0700 Subject: llvmpipe: use new lp_setup_get_current_bins() function This stub function will interface to the queue system... --- src/gallium/drivers/llvmpipe/lp_setup.c | 46 +++++++++++++++++-------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 3 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 20 ++++++----- 3 files changed, 44 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 4935d5b540..484a609e6e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -47,6 +47,13 @@ static void set_state( struct setup_context *, unsigned ); +struct lp_bins * +lp_setup_get_current_bins(struct setup_context *setup) +{ + /* XXX eventually get bin from queue */ + return setup->bins; +} + static void first_triangle( struct setup_context *setup, @@ -88,7 +95,7 @@ static void reset_context( struct setup_context *setup ) setup->fs.stored = NULL; setup->dirty = ~0; - lp_reset_bins( &setup->bins ); + lp_reset_bins( setup->bins ); /* Reset some state: */ @@ -108,8 +115,10 @@ static void rasterize_bins( struct setup_context *setup, boolean write_depth ) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); + lp_rasterize_bins(setup->rast, - &setup->bins, + bins, setup->fb, write_depth); @@ -123,26 +132,28 @@ rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (setup->fb->cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_clear_color, setup->clear.color ); else - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_load_color, lp_rast_arg_null() ); } if (setup->fb->zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_clear_zstencil, setup->clear.zstencil ); else - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_load_zstencil, lp_rast_arg_null() ); } @@ -215,6 +226,7 @@ void lp_setup_bind_framebuffer( struct setup_context *setup, const struct pipe_framebuffer_state *fb ) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); unsigned tiles_x, tiles_y; LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -226,7 +238,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; - lp_bin_set_num_bins(&setup->bins, tiles_x, tiles_y); + lp_bin_set_num_bins(bins, tiles_x, tiles_y); } @@ -237,6 +249,7 @@ lp_setup_clear( struct setup_context *setup, unsigned stencil, unsigned flags ) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); unsigned i; LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); @@ -261,12 +274,12 @@ lp_setup_clear( struct setup_context *setup, * don't see that as being a common usage. */ if (flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_clear_color, setup->clear.color ); if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( &setup->bins, + lp_bin_everywhere( bins, lp_rast_clear_zstencil, setup->clear.zstencil ); } @@ -407,6 +420,8 @@ lp_setup_is_texture_referenced( struct setup_context *setup, static INLINE void lp_setup_update_shader_state( struct setup_context *setup ) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); assert(setup->fs.current.jit_function); @@ -415,7 +430,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) uint8_t *stored; unsigned i, j; - stored = lp_bin_alloc_aligned(&setup->bins, 4 * 16, 16); + stored = lp_bin_alloc_aligned(bins, 4 * 16, 16); /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { @@ -447,7 +462,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) current_size) != 0) { void *stored; - stored = lp_bin_alloc(&setup->bins, current_size); + stored = lp_bin_alloc(bins, current_size); if(stored) { memcpy(stored, current_data, @@ -477,7 +492,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) * and append it to the bin's setup data buffer. */ struct lp_rast_state *stored = - (struct lp_rast_state *) lp_bin_alloc(&setup->bins, sizeof *stored); + (struct lp_rast_state *) lp_bin_alloc(bins, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, @@ -485,7 +500,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) setup->fs.stored = stored; /* put the state-set command into all bins */ - lp_bin_state_command( &setup->bins, + lp_bin_state_command( bins, lp_rast_set_state, lp_rast_arg_state(setup->fs.stored) ); } @@ -537,9 +552,10 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); - lp_free_bin_data(&setup->bins); + lp_bins_destroy(setup->bins); lp_rast_destroy( setup->rast ); + FREE( setup ); } @@ -557,7 +573,7 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup->rast) goto fail; - lp_init_bins(&setup->bins); + setup->bins = lp_bins_create(); setup->triangle = first_triangle; setup->line = first_line; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 9b47b595c6..782c05122c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -55,7 +55,7 @@ struct setup_context { struct lp_rasterizer *rast; - struct lp_bins bins; + struct lp_bins *bins; boolean ccw_is_frontface; unsigned cullmode; @@ -113,5 +113,6 @@ void lp_setup_choose_triangle( struct setup_context *setup ); void lp_setup_choose_line( struct setup_context *setup ); void lp_setup_choose_point( struct setup_context *setup ); +struct lp_bins *lp_setup_get_current_bins(struct setup_context *setup); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index b8f79849e8..80617120b1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -178,6 +178,7 @@ static void setup_tri_coefficients( struct setup_context *setup, const float (*v3)[4], boolean frontface) { + struct lp_bins *bins = lp_setup_get_current_bins(setup); unsigned slot; /* Allocate space for the a0, dadx and dady arrays @@ -185,9 +186,9 @@ static void setup_tri_coefficients( struct setup_context *setup, { unsigned bytes; bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float); - tri->inputs.a0 = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); - tri->inputs.dadx = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); - tri->inputs.dady = lp_bin_alloc_aligned( &setup->bins, bytes, 16 ); + tri->inputs.a0 = lp_bin_alloc_aligned( bins, bytes, 16 ); + tri->inputs.dadx = lp_bin_alloc_aligned( bins, bytes, 16 ); + tri->inputs.dady = lp_bin_alloc_aligned( bins, bytes, 16 ); } /* The internal position input is in slot zero: @@ -263,7 +264,8 @@ do_triangle_ccw(struct setup_context *setup, const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - struct lp_rast_triangle *tri = lp_bin_alloc( &setup->bins, sizeof *tri ); + struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_rast_triangle *tri = lp_bin_alloc( bins, sizeof *tri ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -283,7 +285,7 @@ do_triangle_ccw(struct setup_context *setup, * XXX: subject to overflow?? */ if (area <= 0) { - lp_bin_putback_data( &setup->bins, sizeof *tri ); + lp_bin_putback_data( bins, sizeof *tri ); return; } @@ -295,7 +297,7 @@ do_triangle_ccw(struct setup_context *setup, if (tri->miny == tri->maxy || tri->minx == tri->maxx) { - lp_bin_putback_data( &setup->bins, sizeof *tri ); + lp_bin_putback_data( bins, sizeof *tri ); return; } @@ -405,7 +407,7 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - lp_bin_command( &setup->bins, minx, miny, lp_rast_triangle, + lp_bin_command( bins, minx, miny, lp_rast_triangle, lp_rast_arg_triangle(tri) ); } else @@ -464,7 +466,7 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ - lp_bin_command( &setup->bins, x, y, + lp_bin_command( bins, x, y, lp_rast_shade_tile, lp_rast_arg_inputs(&tri->inputs) ); } @@ -472,7 +474,7 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* shade partial tile */ - lp_bin_command( &setup->bins, x, y, + lp_bin_command( bins, x, y, lp_rast_triangle, lp_rast_arg_triangle(tri) ); } -- cgit v1.2.3 From d7dbc666367438ee9efe748505907b36bba6b66a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Dec 2009 14:53:33 -0700 Subject: llvmpipe: checkpoint: begin plugging in bin queue code --- src/gallium/drivers/llvmpipe/lp_rast.c | 12 ++++++++- src/gallium/drivers/llvmpipe/lp_rast.h | 4 ++- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 4 +++ src/gallium/drivers/llvmpipe/lp_setup.c | 33 ++++++++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 7 +++++- 5 files changed, 56 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 7cd046cc39..0471ad7e2f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -29,6 +29,7 @@ #include "util/u_math.h" #include "util/u_cpu_detect.h" +#include "lp_bin_queue.h" #include "lp_debug.h" #include "lp_state.h" #include "lp_rast.h" @@ -655,7 +656,13 @@ create_rast_threads(struct lp_rasterizer *rast) -struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) +/** + * Create new lp_rasterizer. + * \param empty the queue to put empty bins on after we've finished + * processing them. + */ +struct lp_rasterizer * +lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) { struct lp_rasterizer *rast; unsigned i; @@ -666,6 +673,9 @@ struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) rast->screen = screen; + rast->empty_bins = empty; + rast->full_bins = lp_bins_queue_create(); + for (i = 0; i < Elements(rast->tasks); i++) { rast->tasks[i].tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); rast->tasks[i].tile.depth = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 25e7f8e008..0000fbc5c7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -48,6 +48,7 @@ */ struct lp_rasterizer; struct lp_bins; +struct lp_bins_queue; struct cmd_bin; struct pipe_screen; @@ -130,7 +131,8 @@ struct lp_rast_triangle { -struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ); +struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen, + struct lp_bins_queue *empty ); void lp_rast_destroy( struct lp_rasterizer * ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 5502419a92..4e4f8b36a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -95,6 +95,10 @@ struct lp_rasterizer boolean clipped_tile; boolean check_for_clipped_tiles; + struct lp_bins_queue *full_bins; + struct lp_bins_queue *empty_bins; + pipe_mutex get_bin_mutex; + /* Framebuffer stuff */ struct pipe_screen *screen; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 484a609e6e..c8cdc32853 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -37,6 +37,8 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_pack_color.h" +#include "lp_bin.h" +#include "lp_bin_queue.h" #include "lp_debug.h" #include "lp_state.h" #include "lp_buffer.h" @@ -44,6 +46,10 @@ #include "lp_setup_context.h" +/** XXX temporary value, temporary here */ +#define MAX_BINS 2 + + static void set_state( struct setup_context *, unsigned ); @@ -554,6 +560,14 @@ lp_setup_destroy( struct setup_context *setup ) lp_bins_destroy(setup->bins); + /* free the bins in the 'empty' queue */ + while (lp_bins_queue_size(setup->empty_bins) > 0) { + struct lp_bins *bins = lp_bins_dequeue(setup->empty_bins); + if (!bins) + break; + lp_bins_destroy(bins); + } + lp_rast_destroy( setup->rast ); FREE( setup ); @@ -567,14 +581,28 @@ lp_setup_destroy( struct setup_context *setup ) struct setup_context * lp_setup_create( struct pipe_screen *screen ) { + unsigned i; struct setup_context *setup = CALLOC_STRUCT(setup_context); - setup->rast = lp_rast_create( screen ); + if (!setup) + return NULL; + + setup->empty_bins = lp_bins_queue_create(); + if (!setup->empty_bins) + goto fail; + + setup->rast = lp_rast_create( screen, setup->empty_bins ); if (!setup->rast) goto fail; setup->bins = lp_bins_create(); + /* create some empty bins */ + for (i = 0; i < MAX_BINS; i++) { + struct lp_bins *bins = lp_bins_create(); + lp_bins_enqueue(setup->empty_bins, bins); + } + setup->triangle = first_triangle; setup->line = first_line; setup->point = first_point; @@ -584,6 +612,9 @@ lp_setup_create( struct pipe_screen *screen ) return setup; fail: + if (setup->empty_bins) + lp_bins_queue_destroy(setup->empty_bins); + FREE(setup); return NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 782c05122c..584e37665b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -46,6 +46,9 @@ #define LP_SETUP_NEW_BLEND_COLOR 0x04 +struct lp_bins_queue; + + /** * Point/line/triangle setup context. * Note: "stored" below indicates data which is stored in the bins, @@ -55,7 +58,9 @@ struct setup_context { struct lp_rasterizer *rast; - struct lp_bins *bins; + + struct lp_bins *bins; /**< current bins */ + struct lp_bins_queue *empty_bins; /**< queue of empty bins */ boolean ccw_is_frontface; unsigned cullmode; -- cgit v1.2.3 From 3bee8c2e7c17893f91f6b62e2db090ef495dca9d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Dec 2009 16:02:30 -0700 Subject: llvmpipe: use the empty_bins queue now --- src/gallium/drivers/llvmpipe/lp_rast.c | 8 ++++++++ src/gallium/drivers/llvmpipe/lp_setup.c | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 0471ad7e2f..3165128f8f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -569,6 +569,10 @@ lp_rasterize_bins( struct lp_rasterizer *rast, /* no threading */ lp_bin_iter_begin( bins ); rasterize_bins( rast, 0, bins, fb, write_depth ); + + /* reset bins and put into the empty queue */ + lp_reset_bins( bins ); + lp_bins_enqueue( rast->empty_bins, bins); } else { /* threaded rendering! */ @@ -589,6 +593,10 @@ lp_rasterize_bins( struct lp_rasterizer *rast, for (i = 0; i < rast->num_threads; i++) { pipe_semaphore_wait(&rast->tasks[i].work_done); } + + /* reset bins and put into the empty queue */ + lp_reset_bins( bins ); + lp_bins_enqueue( rast->empty_bins, bins); } lp_rast_end( rast ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c8cdc32853..889f92a0d5 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -56,7 +56,17 @@ static void set_state( struct setup_context *, unsigned ); struct lp_bins * lp_setup_get_current_bins(struct setup_context *setup) { - /* XXX eventually get bin from queue */ + if (!setup->bins) { + /* wait for a free/empty bin */ + setup->bins = lp_bins_dequeue(setup->empty_bins); + if(0)lp_reset_bins( setup->bins ); /* XXX temporary? */ + + if (setup->fb) { + unsigned tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; + unsigned tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; + lp_bin_set_num_bins(setup->bins, tiles_x, tiles_y); + } + } return setup->bins; } @@ -101,7 +111,8 @@ static void reset_context( struct setup_context *setup ) setup->fs.stored = NULL; setup->dirty = ~0; - lp_reset_bins( setup->bins ); + /* no current bin */ + setup->bins = NULL; /* Reset some state: */ @@ -558,8 +569,6 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); - lp_bins_destroy(setup->bins); - /* free the bins in the 'empty' queue */ while (lp_bins_queue_size(setup->empty_bins) > 0) { struct lp_bins *bins = lp_bins_dequeue(setup->empty_bins); @@ -595,8 +604,6 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup->rast) goto fail; - setup->bins = lp_bins_create(); - /* create some empty bins */ for (i = 0; i < MAX_BINS; i++) { struct lp_bins *bins = lp_bins_create(); -- cgit v1.2.3 From ad3c16c127f167513a136759a1700e111a0ef7b8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Dec 2009 16:30:05 -0700 Subject: llvmpipe: simplify the tiles_x, tiles_y code a bit --- src/gallium/drivers/llvmpipe/lp_bin.c | 10 ++++++---- src/gallium/drivers/llvmpipe/lp_bin.h | 5 ++--- src/gallium/drivers/llvmpipe/lp_setup.c | 12 +++--------- 3 files changed, 11 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c index f2d3c2df4d..703cdd2de5 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.c +++ b/src/gallium/drivers/llvmpipe/lp_bin.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "util/u_math.h" #include "util/u_memory.h" #include "lp_bin.h" @@ -137,13 +138,14 @@ lp_free_bin_data(struct lp_bins *bins) void -lp_bin_set_num_bins( struct lp_bins *bins, - unsigned tiles_x, unsigned tiles_y ) +lp_bin_set_framebuffer_size( struct lp_bins *bins, + unsigned width, unsigned height ) { - bins->tiles_x = tiles_x; - bins->tiles_y = tiles_y; + bins->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; + bins->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; } + void lp_bin_new_cmd_block( struct cmd_block_list *list ) { diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h index c49b0264d6..4394e7bda0 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -131,9 +131,8 @@ void lp_reset_bins(struct lp_bins *bins ); void lp_free_bin_data(struct lp_bins *bins); -void -lp_bin_set_num_bins( struct lp_bins *bins, - unsigned tiles_x, unsigned tiles_y ); +void lp_bin_set_framebuffer_size( struct lp_bins *bins, + unsigned width, unsigned height ); void lp_bin_new_data_block( struct data_block_list *list ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 889f92a0d5..3ef9cdaa0c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -34,7 +34,6 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "util/u_math.h" #include "util/u_memory.h" #include "util/u_pack_color.h" #include "lp_bin.h" @@ -62,9 +61,8 @@ lp_setup_get_current_bins(struct setup_context *setup) if(0)lp_reset_bins( setup->bins ); /* XXX temporary? */ if (setup->fb) { - unsigned tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; - unsigned tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; - lp_bin_set_num_bins(setup->bins, tiles_x, tiles_y); + lp_bin_set_framebuffer_size(setup->bins, + setup->fb->width, setup->fb->height); } } return setup->bins; @@ -244,7 +242,6 @@ lp_setup_bind_framebuffer( struct setup_context *setup, const struct pipe_framebuffer_state *fb ) { struct lp_bins *bins = lp_setup_get_current_bins(setup); - unsigned tiles_x, tiles_y; LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -252,10 +249,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, setup->fb = fb; - tiles_x = align(setup->fb->width, TILE_SIZE) / TILE_SIZE; - tiles_y = align(setup->fb->height, TILE_SIZE) / TILE_SIZE; - - lp_bin_set_num_bins(bins, tiles_x, tiles_y); + lp_bin_set_framebuffer_size(bins, setup->fb->width, setup->fb->height); } -- cgit v1.2.3 From 9a6567f1ed88727545f747e8670b713f17627c94 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Dec 2009 14:56:11 -0700 Subject: llvmpipe: updated comment --- src/gallium/drivers/llvmpipe/lp_setup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 3ef9cdaa0c..d976934a5d 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -280,9 +280,10 @@ lp_setup_clear( struct setup_context *setup, if (setup->state == SETUP_ACTIVE) { /* Add the clear to existing bins. In the unusual case where - * both color and depth-stencilare being cleared, we could - * discard the currently binned scene and start again, but I - * don't see that as being a common usage. + * both color and depth-stencil are being cleared when there's + * already been some rendering, we could discard the currently + * binned scene and start again, but I don't see that as being + * a common usage. */ if (flags & PIPE_CLEAR_COLOR) lp_bin_everywhere( bins, -- cgit v1.2.3 From 6cbb1219a3f6b83ee4d24aecb61f5b5943e3cac3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 17:59:26 -0700 Subject: llvmpipe: checkpoint: plug in the new fencing code This has only been very lightly tested. More work to come. --- src/gallium/drivers/llvmpipe/lp_flush.c | 20 +++++++++++++++++--- src/gallium/drivers/llvmpipe/lp_setup.c | 23 +++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup.h | 4 ++++ 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index f7a1d89701..e6519cb216 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -49,6 +49,23 @@ llvmpipe_flush( struct pipe_context *pipe, draw_flush(llvmpipe->draw); + if (fence) { + if ((flags & (PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_RENDER_CACHE))) { + /* if we're going to flush the setup/rasterization modules, emit + * a fence. + * XXX this (and the code below) may need fine tuning... + */ + *fence = lp_setup_fence( llvmpipe->setup ); + } + else { + *fence = NULL; + } + } + + /* XXX the lp_setup_flush(flags) param is not a bool, and it's ignored + * at this time! + */ if (flags & PIPE_FLUSH_SWAPBUFFERS) { lp_setup_flush( llvmpipe->setup, FALSE ); } @@ -68,8 +85,5 @@ llvmpipe_flush( struct pipe_context *pipe, ++frame_no; } #endif - - if (fence) - *fence = NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index d976934a5d..3967b4f21e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -39,6 +39,7 @@ #include "lp_bin.h" #include "lp_bin_queue.h" #include "lp_debug.h" +#include "lp_fence.h" #include "lp_state.h" #include "lp_buffer.h" #include "lp_texture.h" @@ -308,6 +309,28 @@ lp_setup_clear( struct setup_context *setup, } +/** + * Emit a fence. + */ +struct pipe_fence_handle * +lp_setup_fence( struct setup_context *setup ) +{ + struct lp_bins *bins = lp_setup_get_current_bins(setup); + const unsigned rank = lp_bin_get_num_bins( bins ); + struct lp_fence *fence = lp_fence_create(rank); + + LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank); + + set_state( setup, SETUP_ACTIVE ); + + /* insert the fence into all command bins */ + lp_bin_everywhere( bins, + lp_rast_fence, + lp_rast_arg_fence(fence) ); + + return (struct pipe_fence_handle *) fence; +} + void lp_setup_set_triangle_state( struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 66a7f29f1e..5c606e86af 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -67,6 +67,10 @@ lp_setup_clear(struct setup_context *setup, unsigned clear_stencil, unsigned flags); +struct pipe_fence_handle * +lp_setup_fence( struct setup_context *setup ); + + void lp_setup_tri(struct setup_context *setup, const float (*v0)[4], -- cgit v1.2.3 From 314d3cd751448f9ae36126937b3bbf0330542da3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 12 Dec 2009 20:19:46 +0000 Subject: llvmpipe: rename one of the two rasterize_bins functions --- src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 3967b4f21e..6d20975cb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -128,8 +128,8 @@ static void reset_context( struct setup_context *setup ) /** Rasterize all tile's bins */ static void -rasterize_bins( struct setup_context *setup, - boolean write_depth ) +lp_setup_rasterize_bins( struct setup_context *setup, + boolean write_depth ) { struct lp_bins *bins = lp_setup_get_current_bins(setup); @@ -189,7 +189,7 @@ execute_clears( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); begin_binning( setup ); - rasterize_bins( setup, TRUE ); + lp_setup_rasterize_bins( setup, TRUE ); } @@ -220,7 +220,7 @@ set_state( struct setup_context *setup, if (old_state == SETUP_CLEARED) execute_clears( setup ); else - rasterize_bins( setup, TRUE ); + lp_setup_rasterize_bins( setup, TRUE ); break; } -- cgit v1.2.3 From 39dd7108bf6014a8430dffc290e98c7b47432cd3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 12 Dec 2009 20:29:39 +0000 Subject: llvmpipe: rename queue size to count --- src/gallium/drivers/llvmpipe/lp_bin_queue.c | 44 ++++++++++++++--------------- src/gallium/drivers/llvmpipe/lp_bin_queue.h | 4 +-- src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.c b/src/gallium/drivers/llvmpipe/lp_bin_queue.c index b4bc439089..b39b46b72b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.c +++ b/src/gallium/drivers/llvmpipe/lp_bin_queue.c @@ -51,9 +51,9 @@ struct lp_bins_queue * probably always be pretty short. */ struct lp_bins *bins[MAX_BINS]; - unsigned size; + unsigned count; - pipe_condvar size_change; + pipe_condvar count_change; pipe_mutex mutex; }; @@ -65,7 +65,7 @@ lp_bins_queue_create(void) { struct lp_bins_queue *queue = CALLOC_STRUCT(lp_bins_queue); if (queue) { - pipe_condvar_init(queue->size_change); + pipe_condvar_init(queue->count_change); pipe_mutex_init(queue->mutex); } return queue; @@ -76,7 +76,7 @@ lp_bins_queue_create(void) void lp_bins_queue_destroy(struct lp_bins_queue *queue) { - pipe_condvar_destroy(queue->size_change); + pipe_condvar_destroy(queue->count_change); pipe_mutex_destroy(queue->mutex); } @@ -89,24 +89,24 @@ lp_bins_dequeue(struct lp_bins_queue *queue) unsigned i; pipe_mutex_lock(queue->mutex); - while (queue->size == 0) { - pipe_condvar_wait(queue->size_change, queue->mutex); + while (queue->count == 0) { + pipe_condvar_wait(queue->count_change, queue->mutex); } - assert(queue->size >= 1); + assert(queue->count >= 1); /* get head */ bins = queue->bins[0]; /* shift entries */ - for (i = 0; i < queue->size - 1; i++) { + for (i = 0; i < queue->count - 1; i++) { queue->bins[i] = queue->bins[i + 1]; } - queue->size--; + queue->count--; /* signal size change */ - pipe_condvar_signal(queue->size_change); + pipe_condvar_signal(queue->count_change); pipe_mutex_unlock(queue->mutex); @@ -120,21 +120,21 @@ lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins) { pipe_mutex_lock(queue->mutex); - assert(queue->size < MAX_BINS); + assert(queue->count < MAX_BINS); /* debug: check that bins is not already in the queue */ if (0) { unsigned i; - for (i = 0; i < queue->size; i++) { + for (i = 0; i < queue->count; i++) { assert(queue->bins[i] != bins); } } /* add to end */ - queue->bins[queue->size++] = bins; + queue->bins[queue->count++] = bins; /* signal size change */ - pipe_condvar_signal(queue->size_change); + pipe_condvar_signal(queue->count_change); pipe_mutex_unlock(queue->mutex); } @@ -142,23 +142,23 @@ lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins) /** Return number of entries in the queue */ unsigned -lp_bins_queue_size(struct lp_bins_queue *queue) +lp_bins_queue_count(struct lp_bins_queue *queue) { - unsigned sz; + unsigned count; pipe_mutex_lock(queue->mutex); - sz = queue->size; + count = queue->count; pipe_mutex_unlock(queue->mutex); - return sz; + return count; } -/** Wait until the queue as 'size' entries */ +/** Wait until the queue has exactly 'count' entries */ void -lp_bins_queue_wait_size(struct lp_bins_queue *queue, unsigned size) +lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned count) { pipe_mutex_lock(queue->mutex); - while (queue->size != size) { - pipe_condvar_wait(queue->size_change, queue->mutex); + while (queue->count != count) { + pipe_condvar_wait(queue->count_change, queue->mutex); } pipe_mutex_unlock(queue->mutex); } diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.h b/src/gallium/drivers/llvmpipe/lp_bin_queue.h index 8946a54158..1a0f8832db 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.h +++ b/src/gallium/drivers/llvmpipe/lp_bin_queue.h @@ -46,10 +46,10 @@ void lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins); unsigned -lp_bins_queue_size(struct lp_bins_queue *queue); +lp_bins_queue_count(struct lp_bins_queue *queue); void -lp_bins_queue_wait_size(struct lp_bins_queue *queue, unsigned size); +lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned size); #endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 6d20975cb8..0972c16784 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -588,7 +588,7 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); /* free the bins in the 'empty' queue */ - while (lp_bins_queue_size(setup->empty_bins) > 0) { + while (lp_bins_queue_count(setup->empty_bins) > 0) { struct lp_bins *bins = lp_bins_dequeue(setup->empty_bins); if (!bins) break; -- cgit v1.2.3 From 663750d5564a225b4720f7ee8bea93ffb309fc88 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 13 Dec 2009 18:17:25 +0000 Subject: llvmpipe: rename bins to scene It was pretty confusing having an entity named "bin" and another named "bins", not least because sometimes there was a need to talk about >1 of the "bins" objects, which couldn't be pluralized any further... Scene is a term used in a bunch of places to talk about what a binner operates on, so it's a decent choice here. --- src/gallium/drivers/llvmpipe/SConscript | 10 +- src/gallium/drivers/llvmpipe/lp_bin.c | 310 ------------------------ src/gallium/drivers/llvmpipe/lp_bin.h | 275 --------------------- src/gallium/drivers/llvmpipe/lp_bin_queue.c | 164 ------------- src/gallium/drivers/llvmpipe/lp_bin_queue.h | 55 ----- src/gallium/drivers/llvmpipe/lp_rast.c | 96 ++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 14 +- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 12 +- src/gallium/drivers/llvmpipe/lp_scene.c | 310 ++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_scene.h | 276 +++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_scene_queue.c | 164 +++++++++++++ src/gallium/drivers/llvmpipe/lp_scene_queue.h | 55 +++++ src/gallium/drivers/llvmpipe/lp_setup.c | 112 ++++----- src/gallium/drivers/llvmpipe/lp_setup_context.h | 12 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 36 +-- 15 files changed, 952 insertions(+), 949 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin.h delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin_queue.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin_queue.h create mode 100644 src/gallium/drivers/llvmpipe/lp_scene.c create mode 100644 src/gallium/drivers/llvmpipe/lp_scene.h create mode 100644 src/gallium/drivers/llvmpipe/lp_scene_queue.c create mode 100644 src/gallium/drivers/llvmpipe/lp_scene_queue.h (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index bc725b65f6..f0b71ef3ee 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -19,8 +19,6 @@ env.CodeGenerate( llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ - 'lp_bin.c', - 'lp_bin_queue.c', 'lp_bld_alpha.c', 'lp_bld_arit.c', 'lp_bld_blend_aos.c', @@ -35,9 +33,9 @@ llvmpipe = env.ConvenienceLibrary( 'lp_bld_format_soa.c', 'lp_bld_interp.c', 'lp_bld_intr.c', + 'lp_bld_logic.c', 'lp_bld_sample_soa.c', 'lp_bld_struct.c', - 'lp_bld_logic.c', 'lp_bld_swizzle.c', 'lp_bld_tgsi_soa.c', 'lp_bld_type.c', @@ -50,11 +48,13 @@ llvmpipe = env.ConvenienceLibrary( 'lp_jit.c', 'lp_prim_vbuf.c', 'lp_query.c', + 'lp_scene.c', + 'lp_scene_queue.c', + 'lp_screen.c', 'lp_setup.c', - 'lp_setup_tri.c', 'lp_setup_line.c', 'lp_setup_point.c', - 'lp_screen.c', + 'lp_setup_tri.c', 'lp_state_blend.c', 'lp_state_clip.c', 'lp_state_derived.c', diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c deleted file mode 100644 index 703cdd2de5..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin.c +++ /dev/null @@ -1,310 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "util/u_math.h" -#include "util/u_memory.h" -#include "lp_bin.h" - - -struct lp_bins * -lp_bins_create(void) -{ - struct lp_bins *bins = CALLOC_STRUCT(lp_bins); - if (bins) - lp_init_bins(bins); - return bins; -} - - -void -lp_bins_destroy(struct lp_bins *bins) -{ - lp_reset_bins(bins); - lp_free_bin_data(bins); - FREE(bins); -} - - -void -lp_init_bins(struct lp_bins *bins) -{ - unsigned i, j; - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); - } - - bins->data.head = - bins->data.tail = CALLOC_STRUCT(data_block); - - pipe_mutex_init(bins->mutex); -} - - -/** - * Set bins to empty state. - */ -void -lp_reset_bins(struct lp_bins *bins ) -{ - unsigned i, j; - - /* Free all but last binner command lists: - */ - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - struct cmd_block_list *list = &bin->commands; - struct cmd_block *block; - struct cmd_block *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->count = 0; - } - } - - /* Free all but last binned data block: - */ - { - struct data_block_list *list = &bins->data; - struct data_block *block, *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->used = 0; - } -} - - -/** - * Free all data associated with the given bin, but don't free(bins). - */ -void -lp_free_bin_data(struct lp_bins *bins) -{ - unsigned i, j; - - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - /* lp_reset_bins() should have been already called */ - assert(bin->commands.head == bin->commands.tail); - FREE(bin->commands.head); - bin->commands.head = NULL; - bin->commands.tail = NULL; - } - - FREE(bins->data.head); - bins->data.head = NULL; - - pipe_mutex_destroy(bins->mutex); -} - - -void -lp_bin_set_framebuffer_size( struct lp_bins *bins, - unsigned width, unsigned height ) -{ - bins->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; - bins->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; -} - - -void -lp_bin_new_cmd_block( struct cmd_block_list *list ) -{ - struct cmd_block *block = MALLOC_STRUCT(cmd_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->count = 0; -} - - -void -lp_bin_new_data_block( struct data_block_list *list ) -{ - struct data_block *block = MALLOC_STRUCT(data_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->used = 0; -} - - -/** Return number of bytes used for bin data */ -unsigned -lp_bin_data_size( const struct lp_bins *bins ) -{ - unsigned size = 0; - const struct data_block *block; - for (block = bins->data.head; block; block = block->next) { - size += block->used; - } - return size; -} - - -/** Return number of bytes used for a tile bin */ -unsigned -lp_bin_cmd_size( const struct lp_bins *bins, unsigned x, unsigned y ) -{ - struct cmd_bin *bin = lp_get_bin((struct lp_bins *) bins, x, y); - const struct cmd_block *cmd; - unsigned size = 0; - for (cmd = bin->commands.head; cmd; cmd = cmd->next) { - size += (cmd->count * - (sizeof(lp_rast_cmd) + sizeof(union lp_rast_cmd_arg))); - } - return size; -} - - -/** - * Return last command in the bin - */ -static lp_rast_cmd -lp_get_last_command( const struct cmd_bin *bin ) -{ - const struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - if (i > 0) - return tail->cmd[i - 1]; - else - return NULL; -} - - -/** - * Replace the arg of the last command in the bin. - */ -static void -lp_replace_last_command_arg( struct cmd_bin *bin, - const union lp_rast_cmd_arg arg ) -{ - struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - assert(i > 0); - tail->arg[i - 1] = arg; -} - - - -/** - * Put a state-change command into all bins. - * If we find that the last command in a bin was also a state-change - * command, we can simply replace that one with the new one. - */ -void -lp_bin_state_command( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - lp_rast_cmd last_cmd = lp_get_last_command(bin); - if (last_cmd == cmd) { - lp_replace_last_command_arg(bin, arg); - } - else { - lp_bin_command( bins, i, j, cmd, arg ); - } - } - } -} - - -/** advance curr_x,y to the next bin */ -static boolean -next_bin(struct lp_bins *bins) -{ - bins->curr_x++; - if (bins->curr_x >= bins->tiles_x) { - bins->curr_x = 0; - bins->curr_y++; - } - if (bins->curr_y >= bins->tiles_y) { - /* no more bins */ - return FALSE; - } - return TRUE; -} - - -void -lp_bin_iter_begin( struct lp_bins *bins ) -{ - bins->curr_x = bins->curr_y = -1; -} - - -/** - * Return point to next bin to be rendered. - * The lp_bins::curr_x and ::curr_y fields will be advanced. - * Multiple rendering threads will call this function to get a chunk - * of work (a bin) to work on. - */ -struct cmd_bin * -lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y ) -{ - struct cmd_bin *bin = NULL; - - pipe_mutex_lock(bins->mutex); - - if (bins->curr_x < 0) { - /* first bin */ - bins->curr_x = 0; - bins->curr_y = 0; - } - else if (!next_bin(bins)) { - /* no more bins left */ - goto end; - } - - bin = lp_get_bin(bins, bins->curr_x, bins->curr_y); - *bin_x = bins->curr_x; - *bin_y = bins->curr_y; - -end: - /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ - pipe_mutex_unlock(bins->mutex); - return bin; -} diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h deleted file mode 100644 index e763b16ffe..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Binner data structures and bin-related functions. - * Note: the "setup" code is concerned with building bins while - * The "rast" code is concerned with consuming/executing bins. - */ - -#ifndef LP_BIN_H -#define LP_BIN_H - -#include "pipe/p_thread.h" -#include "lp_tile_soa.h" -#include "lp_rast.h" - - -/* We're limited to 2K by 2K for 32bit fixed point rasterization. - * Will need a 64-bit version for larger framebuffers. - */ -#define MAXHEIGHT 2048 -#define MAXWIDTH 2048 -#define TILES_X (MAXWIDTH / TILE_SIZE) -#define TILES_Y (MAXHEIGHT / TILE_SIZE) - - -#define CMD_BLOCK_MAX 128 -#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) - - - -/* switch to a non-pointer value for this: - */ -typedef void (*lp_rast_cmd)( struct lp_rasterizer *, - unsigned thread_index, - const union lp_rast_cmd_arg ); - -struct cmd_block { - lp_rast_cmd cmd[CMD_BLOCK_MAX]; - union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; - unsigned count; - struct cmd_block *next; -}; - -struct data_block { - ubyte data[DATA_BLOCK_SIZE]; - unsigned used; - struct data_block *next; -}; - -struct cmd_block_list { - struct cmd_block *head; - struct cmd_block *tail; -}; - -/** - * For each screen tile we have one of these bins. - */ -struct cmd_bin { - struct cmd_block_list commands; -}; - - -/** - * This stores bulk data which is shared by all bins. - * Examples include triangle data and state data. The commands in - * the per-tile bins will point to chunks of data in this structure. - */ -struct data_block_list { - struct data_block *head; - struct data_block *tail; -}; - - -/** - * All bins and bin data are contained here. - * Per-bin data goes into the 'tile' bins. - * Shared bin data goes into the 'data' buffer. - * When there are multiple threads, will want to double-buffer the - * bin arrays: - */ -struct lp_bins { - struct cmd_bin tile[TILES_X][TILES_Y]; - struct data_block_list data; - - /** the framebuffer to render the bins into */ - struct pipe_framebuffer_state fb; - - boolean write_depth; - - /** - * Number of active tiles in each dimension. - * This basically the framebuffer size divided by tile size - */ - unsigned tiles_x, tiles_y; - - int curr_x, curr_y; /**< for iterating over bins */ - pipe_mutex mutex; -}; - - - -struct lp_bins *lp_bins_create(void); - -void lp_bins_destroy(struct lp_bins *bins); - - -void lp_init_bins(struct lp_bins *bins); - -void lp_reset_bins(struct lp_bins *bins ); - -void lp_free_bin_data(struct lp_bins *bins); - -void lp_bin_set_framebuffer_size( struct lp_bins *bins, - unsigned width, unsigned height ); - -void lp_bin_new_data_block( struct data_block_list *list ); - -void lp_bin_new_cmd_block( struct cmd_block_list *list ); - -unsigned lp_bin_data_size( const struct lp_bins *bins ); - -unsigned lp_bin_cmd_size( const struct lp_bins *bins, unsigned x, unsigned y ); - - -/** - * Allocate space for a command/data in the bin's data buffer. - * Grow the block list if needed. - */ -static INLINE void * -lp_bin_alloc( struct lp_bins *bins, unsigned size) -{ - struct data_block_list *list = &bins->data; - - if (list->tail->used + size > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - tail->used += size; - return data; - } -} - - -/** - * As above, but with specific alignment. - */ -static INLINE void * -lp_bin_alloc_aligned( struct lp_bins *bins, unsigned size, - unsigned alignment ) -{ - struct data_block_list *list = &bins->data; - - if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; - tail->used += offset + size; - return data + offset; - } -} - - -/* Put back data if we decide not to use it, eg. culled triangles. - */ -static INLINE void -lp_bin_putback_data( struct lp_bins *bins, unsigned size) -{ - struct data_block_list *list = &bins->data; - assert(list->tail->used >= size); - list->tail->used -= size; -} - - -/** Return pointer to a particular tile's bin. */ -static INLINE struct cmd_bin * -lp_get_bin(struct lp_bins *bins, unsigned x, unsigned y) -{ - return &bins->tile[x][y]; -} - - - -/* Add a command to bin[x][y]. - */ -static INLINE void -lp_bin_command( struct lp_bins *bins, - unsigned x, unsigned y, - lp_rast_cmd cmd, - union lp_rast_cmd_arg arg ) -{ - struct cmd_bin *bin = lp_get_bin(bins, x, y); - struct cmd_block_list *list = &bin->commands; - - if (list->tail->count == CMD_BLOCK_MAX) { - lp_bin_new_cmd_block( list ); - } - - { - struct cmd_block *tail = list->tail; - unsigned i = tail->count; - tail->cmd[i] = cmd; - tail->arg[i] = arg; - tail->count++; - } -} - - -/* Add a command to all active bins. - */ -static INLINE void -lp_bin_everywhere( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) - for (j = 0; j < bins->tiles_y; j++) - lp_bin_command( bins, i, j, cmd, arg ); -} - - -void -lp_bin_state_command( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ); - - -static INLINE unsigned -lp_bin_get_num_bins( const struct lp_bins *bins ) -{ - return bins->tiles_x * bins->tiles_y; -} - - -void -lp_bin_iter_begin( struct lp_bins *bins ); - -struct cmd_bin * -lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y ); - - -#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.c b/src/gallium/drivers/llvmpipe/lp_bin_queue.c deleted file mode 100644 index b39b46b72b..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.c +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Bin queue. We'll use two queues. One contains "full" bins which - * are produced by the "setup" code. The other contains "empty" bins - * which are produced by the "rast" code when it finishes rendering a bin. - */ - - -#include "pipe/p_thread.h" -#include "util/u_memory.h" -#include "lp_bin_queue.h" - - - -#define MAX_BINS 4 - - -/** - * A queue of bins - */ -struct lp_bins_queue -{ - /** XXX might use a linked list here somedone, but the list will - * probably always be pretty short. - */ - struct lp_bins *bins[MAX_BINS]; - unsigned count; - - pipe_condvar count_change; - pipe_mutex mutex; -}; - - - -/** Allocate a new bins queue */ -struct lp_bins_queue * -lp_bins_queue_create(void) -{ - struct lp_bins_queue *queue = CALLOC_STRUCT(lp_bins_queue); - if (queue) { - pipe_condvar_init(queue->count_change); - pipe_mutex_init(queue->mutex); - } - return queue; -} - - -/** Delete a new bins queue */ -void -lp_bins_queue_destroy(struct lp_bins_queue *queue) -{ - pipe_condvar_destroy(queue->count_change); - pipe_mutex_destroy(queue->mutex); -} - - -/** Remove first lp_bins from head of queue */ -struct lp_bins * -lp_bins_dequeue(struct lp_bins_queue *queue) -{ - struct lp_bins *bins; - unsigned i; - - pipe_mutex_lock(queue->mutex); - while (queue->count == 0) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - - assert(queue->count >= 1); - - /* get head */ - bins = queue->bins[0]; - - /* shift entries */ - for (i = 0; i < queue->count - 1; i++) { - queue->bins[i] = queue->bins[i + 1]; - } - - queue->count--; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); - - return bins; -} - - -/** Add an lp_bins to tail of queue */ -void -lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins) -{ - pipe_mutex_lock(queue->mutex); - - assert(queue->count < MAX_BINS); - - /* debug: check that bins is not already in the queue */ - if (0) { - unsigned i; - for (i = 0; i < queue->count; i++) { - assert(queue->bins[i] != bins); - } - } - - /* add to end */ - queue->bins[queue->count++] = bins; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); -} - - -/** Return number of entries in the queue */ -unsigned -lp_bins_queue_count(struct lp_bins_queue *queue) -{ - unsigned count; - pipe_mutex_lock(queue->mutex); - count = queue->count; - pipe_mutex_unlock(queue->mutex); - return count; -} - - -/** Wait until the queue has exactly 'count' entries */ -void -lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned count) -{ - pipe_mutex_lock(queue->mutex); - while (queue->count != count) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - pipe_mutex_unlock(queue->mutex); -} diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.h b/src/gallium/drivers/llvmpipe/lp_bin_queue.h deleted file mode 100644 index 1a0f8832db..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef LP_BIN_QUEUE -#define LP_BIN_QUEUE - -struct lp_bin_queue; -struct lp_bins; - - -struct lp_bins_queue * -lp_bins_queue_create(void); - -void -lp_bins_queue_destroy(struct lp_bins_queue *queue); - -struct lp_bins * -lp_bins_dequeue(struct lp_bins_queue *queue); - -void -lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins); - -unsigned -lp_bins_queue_count(struct lp_bins_queue *queue); - -void -lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned size); - - -#endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3e7b3d7ab4..fd9cd67d85 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -30,7 +30,7 @@ #include "util/u_cpu_detect.h" #include "util/u_surface.h" -#include "lp_bin_queue.h" +#include "lp_scene_queue.h" #include "lp_debug.h" #include "lp_fence.h" #include "lp_state.h" @@ -38,7 +38,7 @@ #include "lp_rast_priv.h" #include "lp_tile_soa.h" #include "lp_bld_debug.h" -#include "lp_bin.h" +#include "lp_scene.h" /** @@ -531,18 +531,18 @@ void lp_rast_fence( struct lp_rasterizer *rast, /** - * When all the threads are done rasterizing a bin, one thread will - * call this function to reset the bin and put it onto the empty queue. + * When all the threads are done rasterizing a scene, one thread will + * call this function to reset the scene and put it onto the empty queue. */ static void -release_bins( struct lp_rasterizer *rast, - struct lp_bins *bins ) +release_scene( struct lp_rasterizer *rast, + struct lp_scene *scene ) { - util_unreference_framebuffer_state( &bins->fb ); + util_unreference_framebuffer_state( &scene->fb ); - lp_reset_bins( bins ); - lp_bins_enqueue( rast->empty_bins, bins ); - rast->curr_bins = NULL; + lp_scene_reset( scene ); + lp_scene_enqueue( rast->empty_scenes, scene ); + rast->curr_scene = NULL; } @@ -576,22 +576,22 @@ rasterize_bin( struct lp_rasterizer *rast, /** - * Rasterize/execute all bins. + * Rasterize/execute all bins within a scene. * Called per thread. */ static void -rasterize_bins( struct lp_rasterizer *rast, +rasterize_scene( struct lp_rasterizer *rast, unsigned thread_index, - struct lp_bins *bins, + struct lp_scene *scene, bool write_depth ) { - /* loop over tile bins, rasterize each */ + /* loop over scene bins, rasterize each */ #if 0 { unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(scene, i, j); rasterize_bin( rast, thread_index, bin, i * TILE_SIZE, j * TILE_SIZE ); } @@ -602,8 +602,8 @@ rasterize_bins( struct lp_rasterizer *rast, struct cmd_bin *bin; int x, y; - assert(bins); - while ((bin = lp_bin_iter_next(bins, &x, &y))) { + assert(scene); + while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); } } @@ -615,8 +615,8 @@ rasterize_bins( struct lp_rasterizer *rast, * Called by setup module when it has something for us to render. */ void -lp_rasterize_bins( struct lp_rasterizer *rast, - struct lp_bins *bins, +lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, const struct pipe_framebuffer_state *fb, bool write_depth ) { @@ -626,19 +626,19 @@ lp_rasterize_bins( struct lp_rasterizer *rast, if (debug) { unsigned x, y; - printf("rasterize bins:\n"); - printf(" data size: %u\n", lp_bin_data_size(bins)); - for (y = 0; y < bins->tiles_y; y++) { - for (x = 0; x < bins->tiles_x; x++) { + printf("rasterize scene:\n"); + printf(" data size: %u\n", lp_scene_data_size(scene)); + for (y = 0; y < scene->tiles_y; y++) { + for (x = 0; x < scene->tiles_x; x++) { printf(" bin %u, %u size: %u\n", x, y, - lp_bin_cmd_size(bins, x, y)); + lp_scene_bin_size(scene, x, y)); } } } /* save framebuffer state in the bin */ - util_copy_framebuffer_state(&bins->fb, fb); - bins->write_depth = write_depth; + util_copy_framebuffer_state(&scene->fb, fb); + scene->write_depth = write_depth; if (rast->num_threads == 0) { /* no threading */ @@ -647,10 +647,10 @@ lp_rasterize_bins( struct lp_rasterizer *rast, fb->cbufs[0]!= NULL, fb->zsbuf != NULL && write_depth ); - lp_bin_iter_begin( bins ); - rasterize_bins( rast, 0, bins, write_depth ); + lp_scene_bin_iter_begin( scene ); + rasterize_scene( rast, 0, scene, write_depth ); - release_bins( rast, bins ); + release_scene( rast, scene ); lp_rast_end( rast ); } @@ -658,7 +658,7 @@ lp_rasterize_bins( struct lp_rasterizer *rast, /* threaded rendering! */ unsigned i; - lp_bins_enqueue( rast->full_bins, bins ); + lp_scene_enqueue( rast->full_scenes, scene ); /* signal the threads that there's work to do */ for (i = 0; i < rast->num_threads; i++) { @@ -697,18 +697,18 @@ thread_func( void *init_data ) if (task->thread_index == 0) { /* thread[0]: - * - get next set of bins to rasterize + * - get next scene to rasterize * - map the framebuffer surfaces */ const struct pipe_framebuffer_state *fb; boolean write_depth; - rast->curr_bins = lp_bins_dequeue( rast->full_bins ); + rast->curr_scene = lp_scene_dequeue( rast->full_scenes ); - lp_bin_iter_begin( rast->curr_bins ); + lp_scene_bin_iter_begin( rast->curr_scene ); - fb = &rast->curr_bins->fb; - write_depth = rast->curr_bins->write_depth; + fb = &rast->curr_scene->fb; + write_depth = rast->curr_scene->write_depth; lp_rast_begin( rast, fb, fb->cbufs[0] != NULL, @@ -716,25 +716,27 @@ thread_func( void *init_data ) } /* Wait for all threads to get here so that threads[1+] don't - * get a null rast->curr_bins pointer. + * get a null rast->curr_scene pointer. */ pipe_barrier_wait( &rast->barrier ); /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); - rasterize_bins(rast, task->thread_index, - rast->curr_bins, rast->curr_bins->write_depth); + rasterize_scene(rast, + task->thread_index, + rast->curr_scene, + rast->curr_scene->write_depth); - /* wait for all threads to finish with this set of bins */ + /* wait for all threads to finish with this scene */ pipe_barrier_wait( &rast->barrier ); if (task->thread_index == 0) { /* thread[0]: - * - release the bins object + * - release the scene object * - unmap the framebuffer surfaces */ - release_bins( rast, rast->curr_bins ); + release_scene( rast, rast->curr_scene ); lp_rast_end( rast ); } @@ -773,11 +775,11 @@ create_rast_threads(struct lp_rasterizer *rast) /** * Create new lp_rasterizer. - * \param empty the queue to put empty bins on after we've finished + * \param empty the queue to put empty scenes on after we've finished * processing them. */ struct lp_rasterizer * -lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) +lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) { struct lp_rasterizer *rast; unsigned i; @@ -788,8 +790,8 @@ lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) rast->screen = screen; - rast->empty_bins = empty; - rast->full_bins = lp_bins_queue_create(); + rast->empty_scenes = empty; + rast->full_scenes = lp_scene_queue_create(); for (i = 0; i < Elements(rast->tasks); i++) { rast->tasks[i].tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index bd8f1ae1c9..2dd0193d8d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -42,8 +42,8 @@ struct lp_rasterizer; -struct lp_bins; -struct lp_bins_queue; +struct lp_scene; +struct lp_scene_queue; struct lp_fence; struct cmd_bin; struct pipe_screen; @@ -130,16 +130,16 @@ struct lp_rast_triangle { struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen, - struct lp_bins_queue *empty ); + struct lp_scene_queue *empty ); void lp_rast_destroy( struct lp_rasterizer * ); unsigned lp_rast_get_num_threads( struct lp_rasterizer * ); -void lp_rasterize_bins( struct lp_rasterizer *rast, - struct lp_bins *bins, - const struct pipe_framebuffer_state *fb, - bool write_depth ); +void lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, + const struct pipe_framebuffer_state *fb, + bool write_depth ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index ba14fc3675..79a90f6610 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -110,13 +110,13 @@ struct lp_rasterizer char clear_stencil; } state; - /** The incoming queue of filled bins to rasterize */ - struct lp_bins_queue *full_bins; - /** The outgoing queue of emptied bins to return to setup modulee */ - struct lp_bins_queue *empty_bins; + /** The incoming queue of scenes ready to rasterize */ + struct lp_scene_queue *full_scenes; + /** The outgoing queue of processed scenes to return to setup modulee */ + struct lp_scene_queue *empty_scenes; - /** The bins currently being rasterized by the threads */ - struct lp_bins *curr_bins; + /** The scene currently being rasterized by the threads */ + struct lp_scene *curr_scene; /** A task object for each rasterization thread */ struct lp_rasterizer_task tasks[MAX_THREADS]; diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c new file mode 100644 index 0000000000..774a1fecd7 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -0,0 +1,310 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_scene.h" + + +struct lp_scene * +lp_scene_create(void) +{ + struct lp_scene *scene = CALLOC_STRUCT(lp_scene); + if (scene) + lp_scene_init(scene); + return scene; +} + + +void +lp_scene_destroy(struct lp_scene *scene) +{ + lp_scene_reset(scene); + lp_scene_free_bin_data(scene); + FREE(scene); +} + + +void +lp_scene_init(struct lp_scene *scene) +{ + unsigned i, j; + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); + } + + scene->data.head = + scene->data.tail = CALLOC_STRUCT(data_block); + + pipe_mutex_init(scene->mutex); +} + + +/** + * Set scene to empty state. + */ +void +lp_scene_reset(struct lp_scene *scene ) +{ + unsigned i, j; + + /* Free all but last binner command lists: + */ + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + struct cmd_block_list *list = &bin->commands; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->count = 0; + } + } + + /* Free all but last binned data block: + */ + { + struct data_block_list *list = &scene->data; + struct data_block *block, *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->used = 0; + } +} + + +/** + * Free all data associated with the given bin, but don't free(scene). + */ +void +lp_scene_free_bin_data(struct lp_scene *scene) +{ + unsigned i, j; + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + /* lp_reset_scene() should have been already called */ + assert(bin->commands.head == bin->commands.tail); + FREE(bin->commands.head); + bin->commands.head = NULL; + bin->commands.tail = NULL; + } + + FREE(scene->data.head); + scene->data.head = NULL; + + pipe_mutex_destroy(scene->mutex); +} + + +void +lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ) +{ + scene->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; + scene->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; +} + + +void +lp_bin_new_cmd_block( struct cmd_block_list *list ) +{ + struct cmd_block *block = MALLOC_STRUCT(cmd_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; +} + + +void +lp_bin_new_data_block( struct data_block_list *list ) +{ + struct data_block *block = MALLOC_STRUCT(data_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; +} + + +/** Return number of bytes used for all bin data within a scene */ +unsigned +lp_scene_data_size( const struct lp_scene *scene ) +{ + unsigned size = 0; + const struct data_block *block; + for (block = scene->data.head; block; block = block->next) { + size += block->used; + } + return size; +} + + +/** Return number of bytes used for a single bin */ +unsigned +lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) +{ + struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y); + const struct cmd_block *cmd; + unsigned size = 0; + for (cmd = bin->commands.head; cmd; cmd = cmd->next) { + size += (cmd->count * + (sizeof(lp_rast_cmd) + sizeof(union lp_rast_cmd_arg))); + } + return size; +} + + +/** + * Return last command in the bin + */ +static lp_rast_cmd +lp_get_last_command( const struct cmd_bin *bin ) +{ + const struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + if (i > 0) + return tail->cmd[i - 1]; + else + return NULL; +} + + +/** + * Replace the arg of the last command in the bin. + */ +static void +lp_replace_last_command_arg( struct cmd_bin *bin, + const union lp_rast_cmd_arg arg ) +{ + struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + assert(i > 0); + tail->arg[i - 1] = arg; +} + + + +/** + * Put a state-change command into all bins. + * If we find that the last command in a bin was also a state-change + * command, we can simply replace that one with the new one. + */ +void +lp_scene_bin_state_command( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + lp_rast_cmd last_cmd = lp_get_last_command(bin); + if (last_cmd == cmd) { + lp_replace_last_command_arg(bin, arg); + } + else { + lp_scene_bin_command( scene, i, j, cmd, arg ); + } + } + } +} + + +/** advance curr_x,y to the next bin */ +static boolean +next_bin(struct lp_scene *scene) +{ + scene->curr_x++; + if (scene->curr_x >= scene->tiles_x) { + scene->curr_x = 0; + scene->curr_y++; + } + if (scene->curr_y >= scene->tiles_y) { + /* no more bins */ + return FALSE; + } + return TRUE; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ) +{ + scene->curr_x = scene->curr_y = -1; +} + + +/** + * Return point to next bin to be rendered. + * The lp_scene::curr_x and ::curr_y fields will be advanced. + * Multiple rendering threads will call this function to get a chunk + * of work (a bin) to work on. + */ +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ) +{ + struct cmd_bin *bin = NULL; + + pipe_mutex_lock(scene->mutex); + + if (scene->curr_x < 0) { + /* first bin */ + scene->curr_x = 0; + scene->curr_y = 0; + } + else if (!next_bin(scene)) { + /* no more bins left */ + goto end; + } + + bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y); + *bin_x = scene->curr_x; + *bin_y = scene->curr_y; + +end: + /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ + pipe_mutex_unlock(scene->mutex); + return bin; +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h new file mode 100644 index 0000000000..796fc516cc --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -0,0 +1,276 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Binner data structures and bin-related functions. + * Note: the "setup" code is concerned with building scenes while + * The "rast" code is concerned with consuming/executing scenes. + */ + +#ifndef LP_SCENE_H +#define LP_SCENE_H + +#include "pipe/p_thread.h" +#include "lp_tile_soa.h" +#include "lp_rast.h" + + +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. + */ +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 +#define TILES_X (MAXWIDTH / TILE_SIZE) +#define TILES_Y (MAXHEIGHT / TILE_SIZE) + + +#define CMD_BLOCK_MAX 128 +#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) + + + +/* switch to a non-pointer value for this: + */ +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +struct cmd_block { + lp_rast_cmd cmd[CMD_BLOCK_MAX]; + union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; + unsigned count; + struct cmd_block *next; +}; + +struct data_block { + ubyte data[DATA_BLOCK_SIZE]; + unsigned used; + struct data_block *next; +}; + +struct cmd_block_list { + struct cmd_block *head; + struct cmd_block *tail; +}; + +/** + * For each screen tile we have one of these bins. + */ +struct cmd_bin { + struct cmd_block_list commands; +}; + + +/** + * This stores bulk data which is shared by all bins within a scene. + * Examples include triangle data and state data. The commands in + * the per-tile bins will point to chunks of data in this structure. + */ +struct data_block_list { + struct data_block *head; + struct data_block *tail; +}; + + +/** + * All bins and bin data are contained here. + * Per-bin data goes into the 'tile' bins. + * Shared data goes into the 'data' buffer. + * + * When there are multiple threads, will want to double-buffer between + * scenes: + */ +struct lp_scene { + struct cmd_bin tile[TILES_X][TILES_Y]; + struct data_block_list data; + + /** the framebuffer to render the scene into */ + struct pipe_framebuffer_state fb; + + boolean write_depth; + + /** + * Number of active tiles in each dimension. + * This basically the framebuffer size divided by tile size + */ + unsigned tiles_x, tiles_y; + + int curr_x, curr_y; /**< for iterating over bins */ + pipe_mutex mutex; +}; + + + +struct lp_scene *lp_scene_create(void); + +void lp_scene_destroy(struct lp_scene *scene); + + +void lp_scene_init(struct lp_scene *scene); + +void lp_scene_reset(struct lp_scene *scene ); + +void lp_scene_free_bin_data(struct lp_scene *scene); + +void lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ); + +void lp_bin_new_data_block( struct data_block_list *list ); + +void lp_bin_new_cmd_block( struct cmd_block_list *list ); + +unsigned lp_scene_data_size( const struct lp_scene *scene ); + +unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); + + +/** + * Allocate space for a command/data in the bin's data buffer. + * Grow the block list if needed. + */ +static INLINE void * +lp_scene_alloc( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + tail->used += size; + return data; + } +} + + +/** + * As above, but with specific alignment. + */ +static INLINE void * +lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size, + unsigned alignment ) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; + tail->used += offset + size; + return data + offset; + } +} + + +/* Put back data if we decide not to use it, eg. culled triangles. + */ +static INLINE void +lp_scene_putback_data( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + assert(list->tail->used >= size); + list->tail->used -= size; +} + + +/** Return pointer to a particular tile's bin. */ +static INLINE struct cmd_bin * +lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y) +{ + return &scene->tile[x][y]; +} + + + +/* Add a command to bin[x][y]. + */ +static INLINE void +lp_scene_bin_command( struct lp_scene *scene, + unsigned x, unsigned y, + lp_rast_cmd cmd, + union lp_rast_cmd_arg arg ) +{ + struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + struct cmd_block_list *list = &bin->commands; + + if (list->tail->count == CMD_BLOCK_MAX) { + lp_bin_new_cmd_block( list ); + } + + { + struct cmd_block *tail = list->tail; + unsigned i = tail->count; + tail->cmd[i] = cmd; + tail->arg[i] = arg; + tail->count++; + } +} + + +/* Add a command to all active bins. + */ +static INLINE void +lp_scene_bin_everywhere( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < scene->tiles_x; i++) + for (j = 0; j < scene->tiles_y; j++) + lp_scene_bin_command( scene, i, j, cmd, arg ); +} + + +void +lp_scene_bin_state_command( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ); + + +static INLINE unsigned +lp_scene_get_num_bins( const struct lp_scene *scene ) +{ + return scene->tiles_x * scene->tiles_y; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ); + +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ); + + +#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c new file mode 100644 index 0000000000..8d65a6a6fa --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Scene queue. We'll use two queues. One contains "full" scenes which + * are produced by the "setup" code. The other contains "empty" scenes + * which are produced by the "rast" code when it finishes rendering a scene. + */ + + +#include "pipe/p_thread.h" +#include "util/u_memory.h" +#include "lp_scene_queue.h" + + + +#define MAX_SCENE_QUEUE 4 + + +/** + * A queue of scenes + */ +struct lp_scene_queue +{ + /** XXX might use a linked list here somedone, but the list will + * probably always be pretty short. + */ + struct lp_scene *scenes[MAX_SCENE_QUEUE]; + unsigned count; + + pipe_condvar count_change; + pipe_mutex mutex; +}; + + + +/** Allocate a new scene queue */ +struct lp_scene_queue * +lp_scene_queue_create(void) +{ + struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue); + if (queue) { + pipe_condvar_init(queue->count_change); + pipe_mutex_init(queue->mutex); + } + return queue; +} + + +/** Delete a scene queue */ +void +lp_scene_queue_destroy(struct lp_scene_queue *queue) +{ + pipe_condvar_destroy(queue->count_change); + pipe_mutex_destroy(queue->mutex); +} + + +/** Remove first lp_scene from head of queue */ +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue) +{ + struct lp_scene *scene; + unsigned i; + + pipe_mutex_lock(queue->mutex); + while (queue->count == 0) { + pipe_condvar_wait(queue->count_change, queue->mutex); + } + + assert(queue->count >= 1); + + /* get head */ + scene = queue->scenes[0]; + + /* shift entries */ + for (i = 0; i < queue->count - 1; i++) { + queue->scenes[i] = queue->scenes[i + 1]; + } + + queue->count--; + + /* signal size change */ + pipe_condvar_signal(queue->count_change); + + pipe_mutex_unlock(queue->mutex); + + return scene; +} + + +/** Add an lp_scene to tail of queue */ +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene) +{ + pipe_mutex_lock(queue->mutex); + + assert(queue->count < MAX_SCENE_QUEUE); + + /* debug: check that scene is not already in the queue */ + if (0) { + unsigned i; + for (i = 0; i < queue->count; i++) { + assert(queue->scenes[i] != scene); + } + } + + /* add to end */ + queue->scenes[queue->count++] = scene; + + /* signal size change */ + pipe_condvar_signal(queue->count_change); + + pipe_mutex_unlock(queue->mutex); +} + + +/** Return number of entries in the queue */ +unsigned +lp_scene_queue_count(struct lp_scene_queue *queue) +{ + unsigned count; + pipe_mutex_lock(queue->mutex); + count = queue->count; + pipe_mutex_unlock(queue->mutex); + return count; +} + + +/** Wait until the queue has exactly 'count' entries */ +void +lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned count) +{ + pipe_mutex_lock(queue->mutex); + while (queue->count != count) { + pipe_condvar_wait(queue->count_change, queue->mutex); + } + pipe_mutex_unlock(queue->mutex); +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h new file mode 100644 index 0000000000..1bd475fa50 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h @@ -0,0 +1,55 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef LP_SCENE_QUEUE +#define LP_SCENE_QUEUE + +struct lp_scene_queue; +struct lp_scene; + + +struct lp_scene_queue * +lp_scene_queue_create(void); + +void +lp_scene_queue_destroy(struct lp_scene_queue *queue); + +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue); + +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *bins); + +unsigned +lp_scene_queue_count(struct lp_scene_queue *queue); + +void +lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned size); + + +#endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 0972c16784..76e0955237 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -36,8 +36,8 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" -#include "lp_bin.h" -#include "lp_bin_queue.h" +#include "lp_scene.h" +#include "lp_scene_queue.h" #include "lp_debug.h" #include "lp_fence.h" #include "lp_state.h" @@ -47,26 +47,26 @@ /** XXX temporary value, temporary here */ -#define MAX_BINS 2 +#define MAX_SCENES 2 static void set_state( struct setup_context *, unsigned ); -struct lp_bins * -lp_setup_get_current_bins(struct setup_context *setup) +struct lp_scene * +lp_setup_get_current_scene(struct setup_context *setup) { - if (!setup->bins) { + if (!setup->scene) { /* wait for a free/empty bin */ - setup->bins = lp_bins_dequeue(setup->empty_bins); - if(0)lp_reset_bins( setup->bins ); /* XXX temporary? */ + setup->scene = lp_scene_dequeue(setup->empty_scenes); + if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ if (setup->fb) { - lp_bin_set_framebuffer_size(setup->bins, + lp_scene_set_framebuffer_size(setup->scene, setup->fb->width, setup->fb->height); } } - return setup->bins; + return setup->scene; } @@ -111,7 +111,7 @@ static void reset_context( struct setup_context *setup ) setup->dirty = ~0; /* no current bin */ - setup->bins = NULL; + setup->scene = NULL; /* Reset some state: */ @@ -126,15 +126,15 @@ static void reset_context( struct setup_context *setup ) } -/** Rasterize all tile's bins */ +/** Rasterize all scene's bins */ static void -lp_setup_rasterize_bins( struct setup_context *setup, +lp_setup_rasterize_scene( struct setup_context *setup, boolean write_depth ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); - lp_rasterize_bins(setup->rast, - bins, + lp_rasterize_scene(setup->rast, + scene, setup->fb, write_depth); @@ -148,28 +148,28 @@ lp_setup_rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (setup->fb->cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_color, setup->clear.color ); else - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_load_color, lp_rast_arg_null() ); } if (setup->fb->zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_zstencil, setup->clear.zstencil ); else - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_load_zstencil, lp_rast_arg_null() ); } @@ -189,7 +189,7 @@ execute_clears( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); begin_binning( setup ); - lp_setup_rasterize_bins( setup, TRUE ); + lp_setup_rasterize_scene( setup, TRUE ); } @@ -220,7 +220,7 @@ set_state( struct setup_context *setup, if (old_state == SETUP_CLEARED) execute_clears( setup ); else - lp_setup_rasterize_bins( setup, TRUE ); + lp_setup_rasterize_scene( setup, TRUE ); break; } @@ -242,7 +242,7 @@ void lp_setup_bind_framebuffer( struct setup_context *setup, const struct pipe_framebuffer_state *fb ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -250,7 +250,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, setup->fb = fb; - lp_bin_set_framebuffer_size(bins, setup->fb->width, setup->fb->height); + lp_scene_set_framebuffer_size(scene, setup->fb->width, setup->fb->height); } @@ -261,7 +261,7 @@ lp_setup_clear( struct setup_context *setup, unsigned stencil, unsigned flags ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); unsigned i; LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); @@ -280,19 +280,19 @@ lp_setup_clear( struct setup_context *setup, } if (setup->state == SETUP_ACTIVE) { - /* Add the clear to existing bins. In the unusual case where + /* Add the clear to existing scene. In the unusual case where * both color and depth-stencil are being cleared when there's * already been some rendering, we could discard the currently * binned scene and start again, but I don't see that as being * a common usage. */ if (flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_color, setup->clear.color ); if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_zstencil, setup->clear.zstencil ); } @@ -315,8 +315,8 @@ lp_setup_clear( struct setup_context *setup, struct pipe_fence_handle * lp_setup_fence( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); - const unsigned rank = lp_bin_get_num_bins( bins ); + struct lp_scene *scene = lp_setup_get_current_scene(setup); + const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */ struct lp_fence *fence = lp_fence_create(rank); LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank); @@ -324,9 +324,9 @@ lp_setup_fence( struct setup_context *setup ) set_state( setup, SETUP_ACTIVE ); /* insert the fence into all command bins */ - lp_bin_everywhere( bins, - lp_rast_fence, - lp_rast_arg_fence(fence) ); + lp_scene_bin_everywhere( scene, + lp_rast_fence, + lp_rast_arg_fence(fence) ); return (struct pipe_fence_handle *) fence; } @@ -455,7 +455,7 @@ lp_setup_is_texture_referenced( struct setup_context *setup, static INLINE void lp_setup_update_shader_state( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -465,7 +465,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) uint8_t *stored; unsigned i, j; - stored = lp_bin_alloc_aligned(bins, 4 * 16, 16); + stored = lp_scene_alloc_aligned(scene, 4 * 16, 16); /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { @@ -497,7 +497,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) current_size) != 0) { void *stored; - stored = lp_bin_alloc(bins, current_size); + stored = lp_scene_alloc(scene, current_size); if(stored) { memcpy(stored, current_data, @@ -522,12 +522,12 @@ lp_setup_update_shader_state( struct setup_context *setup ) memcmp(setup->fs.stored, &setup->fs.current, sizeof setup->fs.current) != 0) { - /* The fs state that's been stored in the bins is different from + /* The fs state that's been stored in the scene is different from * the new, current state. So allocate a new lp_rast_state object * and append it to the bin's setup data buffer. */ struct lp_rast_state *stored = - (struct lp_rast_state *) lp_bin_alloc(bins, sizeof *stored); + (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, @@ -535,9 +535,9 @@ lp_setup_update_shader_state( struct setup_context *setup ) setup->fs.stored = stored; /* put the state-set command into all bins */ - lp_bin_state_command( bins, - lp_rast_set_state, - lp_rast_arg_state(setup->fs.stored) ); + lp_scene_bin_state_command( scene, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); } } } @@ -587,12 +587,12 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); - /* free the bins in the 'empty' queue */ - while (lp_bins_queue_count(setup->empty_bins) > 0) { - struct lp_bins *bins = lp_bins_dequeue(setup->empty_bins); - if (!bins) + /* free the scenes in the 'empty' queue */ + while (lp_scene_queue_count(setup->empty_scenes) > 0) { + struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes); + if (!scene) break; - lp_bins_destroy(bins); + lp_scene_destroy(scene); } lp_rast_destroy( setup->rast ); @@ -614,18 +614,18 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup) return NULL; - setup->empty_bins = lp_bins_queue_create(); - if (!setup->empty_bins) + setup->empty_scenes = lp_scene_queue_create(); + if (!setup->empty_scenes) goto fail; - setup->rast = lp_rast_create( screen, setup->empty_bins ); + setup->rast = lp_rast_create( screen, setup->empty_scenes ); if (!setup->rast) goto fail; - /* create some empty bins */ - for (i = 0; i < MAX_BINS; i++) { - struct lp_bins *bins = lp_bins_create(); - lp_bins_enqueue(setup->empty_bins, bins); + /* create some empty scenes */ + for (i = 0; i < MAX_SCENES; i++) { + struct lp_scene *scene = lp_scene_create(); + lp_scene_enqueue(setup->empty_scenes, scene); } setup->triangle = first_triangle; @@ -637,8 +637,8 @@ lp_setup_create( struct pipe_screen *screen ) return setup; fail: - if (setup->empty_bins) - lp_bins_queue_destroy(setup->empty_bins); + if (setup->empty_scenes) + lp_scene_queue_destroy(setup->empty_scenes); FREE(setup); return NULL; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 584e37665b..180d9eca84 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -38,7 +38,7 @@ #include "lp_setup.h" #include "lp_rast.h" #include "lp_tile_soa.h" /* for TILE_SIZE */ -#include "lp_bin.h" +#include "lp_scene.h" #define LP_SETUP_NEW_FS 0x01 @@ -46,7 +46,7 @@ #define LP_SETUP_NEW_BLEND_COLOR 0x04 -struct lp_bins_queue; +struct lp_scene_queue; /** @@ -59,8 +59,8 @@ struct setup_context { struct lp_rasterizer *rast; - struct lp_bins *bins; /**< current bins */ - struct lp_bins_queue *empty_bins; /**< queue of empty bins */ + struct lp_scene *scene; /**< current scene */ + struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */ boolean ccw_is_frontface; unsigned cullmode; @@ -83,7 +83,7 @@ struct setup_context { struct lp_shader_input input[PIPE_MAX_ATTRIBS]; unsigned nr_inputs; - const struct lp_rast_state *stored; /**< what's in the bins */ + const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ } fs; @@ -118,6 +118,6 @@ void lp_setup_choose_triangle( struct setup_context *setup ); void lp_setup_choose_line( struct setup_context *setup ); void lp_setup_choose_point( struct setup_context *setup ); -struct lp_bins *lp_setup_get_current_bins(struct setup_context *setup); +struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 80617120b1..aeaf260af2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -178,7 +178,7 @@ static void setup_tri_coefficients( struct setup_context *setup, const float (*v3)[4], boolean frontface) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); unsigned slot; /* Allocate space for the a0, dadx and dady arrays @@ -186,9 +186,9 @@ static void setup_tri_coefficients( struct setup_context *setup, { unsigned bytes; bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float); - tri->inputs.a0 = lp_bin_alloc_aligned( bins, bytes, 16 ); - tri->inputs.dadx = lp_bin_alloc_aligned( bins, bytes, 16 ); - tri->inputs.dady = lp_bin_alloc_aligned( bins, bytes, 16 ); + tri->inputs.a0 = lp_scene_alloc_aligned( scene, bytes, 16 ); + tri->inputs.dadx = lp_scene_alloc_aligned( scene, bytes, 16 ); + tri->inputs.dady = lp_scene_alloc_aligned( scene, bytes, 16 ); } /* The internal position input is in slot zero: @@ -246,8 +246,8 @@ static inline int subpixel_snap( float a ) /** * Do basic setup for triangle rasterization and determine which - * framebuffer tiles are touched. Put the triangle in the bins for the - * tiles which we overlap. + * framebuffer tiles are touched. Put the triangle in the scene's + * bins for the tiles which we overlap. */ static void do_triangle_ccw(struct setup_context *setup, @@ -264,8 +264,8 @@ do_triangle_ccw(struct setup_context *setup, const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - struct lp_bins *bins = lp_setup_get_current_bins(setup); - struct lp_rast_triangle *tri = lp_bin_alloc( bins, sizeof *tri ); + struct lp_scene *scene = lp_setup_get_current_scene(setup); + struct lp_rast_triangle *tri = lp_scene_alloc( scene, sizeof *tri ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -285,7 +285,7 @@ do_triangle_ccw(struct setup_context *setup, * XXX: subject to overflow?? */ if (area <= 0) { - lp_bin_putback_data( bins, sizeof *tri ); + lp_scene_putback_data( scene, sizeof *tri ); return; } @@ -297,7 +297,7 @@ do_triangle_ccw(struct setup_context *setup, if (tri->miny == tri->maxy || tri->minx == tri->maxx) { - lp_bin_putback_data( bins, sizeof *tri ); + lp_scene_putback_data( scene, sizeof *tri ); return; } @@ -407,8 +407,8 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - lp_bin_command( bins, minx, miny, lp_rast_triangle, - lp_rast_arg_triangle(tri) ); + lp_scene_bin_command( scene, minx, miny, lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } else { @@ -466,17 +466,17 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ - lp_bin_command( bins, x, y, - lp_rast_shade_tile, - lp_rast_arg_inputs(&tri->inputs) ); + lp_scene_bin_command( scene, x, y, + lp_rast_shade_tile, + lp_rast_arg_inputs(&tri->inputs) ); } else { in = 1; /* shade partial tile */ - lp_bin_command( bins, x, y, - lp_rast_triangle, - lp_rast_arg_triangle(tri) ); + lp_scene_bin_command( scene, x, y, + lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } /* Iterate cx values across the region: -- cgit v1.2.3 From 7f2ba80025e4b534db72427a206e6a542fc2f520 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Dec 2009 11:29:37 +0000 Subject: llvmpipe: keep copy of framebuffer state in setup context Avoids crashes when first frame is rendered before window is mapped. Avoids potential issue where fb state is changed before setup context is flushed. --- src/gallium/drivers/llvmpipe/lp_setup.c | 24 ++++++++++++------------ src/gallium/drivers/llvmpipe/lp_setup_context.h | 2 +- src/gallium/drivers/llvmpipe/lp_state_surface.c | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 76e0955237..e361e5df63 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -36,6 +36,7 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" +#include "util/u_surface.h" #include "lp_scene.h" #include "lp_scene_queue.h" #include "lp_debug.h" @@ -61,10 +62,9 @@ lp_setup_get_current_scene(struct setup_context *setup) setup->scene = lp_scene_dequeue(setup->empty_scenes); if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ - if (setup->fb) { - lp_scene_set_framebuffer_size(setup->scene, - setup->fb->width, setup->fb->height); - } + lp_scene_set_framebuffer_size(setup->scene, + setup->fb.width, + setup->fb.height); } return setup->scene; } @@ -134,9 +134,9 @@ lp_setup_rasterize_scene( struct setup_context *setup, struct lp_scene *scene = lp_setup_get_current_scene(setup); lp_rasterize_scene(setup->rast, - scene, - setup->fb, - write_depth); + scene, + &setup->fb, + write_depth); reset_context( setup ); @@ -152,7 +152,7 @@ begin_binning( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (setup->fb->cbufs[0]) { + if (setup->fb.cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) lp_scene_bin_everywhere( scene, lp_rast_clear_color, @@ -163,7 +163,7 @@ begin_binning( struct setup_context *setup ) lp_rast_arg_null() ); } - if (setup->fb->zsbuf) { + if (setup->fb.zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) lp_scene_bin_everywhere( scene, lp_rast_clear_zstencil, @@ -248,9 +248,9 @@ lp_setup_bind_framebuffer( struct setup_context *setup, set_state( setup, SETUP_FLUSHED ); - setup->fb = fb; + util_copy_framebuffer_state(&setup->fb, fb); - lp_scene_set_framebuffer_size(scene, setup->fb->width, setup->fb->height); + lp_scene_set_framebuffer_size(scene, setup->fb.width, setup->fb.height); } @@ -274,7 +274,7 @@ lp_setup_clear( struct setup_context *setup, if (flags & PIPE_CLEAR_DEPTHSTENCIL) { setup->clear.zstencil.clear_zstencil = - util_pack_z_stencil(setup->fb->zsbuf->format, + util_pack_z_stencil(setup->fb.zsbuf->format, depth, stencil); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 180d9eca84..f6604a8034 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -65,7 +65,7 @@ struct setup_context { boolean ccw_is_frontface; unsigned cullmode; - const struct pipe_framebuffer_state *fb; + struct pipe_framebuffer_state fb; struct { unsigned flags; diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index 21565436eb..957e947fe0 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -68,7 +68,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, draw_set_mrd(lp->draw, mrd); } - lp_setup_bind_framebuffer( lp->setup, fb ); + lp_setup_bind_framebuffer( lp->setup, &lp->framebuffer ); lp->dirty |= LP_NEW_FRAMEBUFFER; } -- cgit v1.2.3 From 5ce0380a0f585b9e1fb616b749f7fd18a8afada1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 6 Jan 2010 16:44:43 +0000 Subject: llvmpipe: merge setup and draw vbuf submodules The setup tiling engine is now plugged directly into the draw module as a rendering backend. Removed a couple of layering violations such that the setup code no longer reaches out into the surrounding llvmpipe state or context. --- src/gallium/drivers/llvmpipe/Makefile | 2 +- src/gallium/drivers/llvmpipe/SConscript | 2 +- src/gallium/drivers/llvmpipe/lp_context.c | 18 +- src/gallium/drivers/llvmpipe/lp_context.h | 15 - src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 2 - src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 559 ------------------------ src/gallium/drivers/llvmpipe/lp_prim_vbuf.h | 38 -- src/gallium/drivers/llvmpipe/lp_setup.c | 111 ++--- src/gallium/drivers/llvmpipe/lp_setup.h | 34 +- src/gallium/drivers/llvmpipe/lp_setup_context.h | 29 +- src/gallium/drivers/llvmpipe/lp_setup_vbuf.c | 520 ++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_state_derived.c | 223 +++------- src/gallium/drivers/llvmpipe/lp_state_fs.c | 3 +- 13 files changed, 698 insertions(+), 858 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_prim_vbuf.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_prim_vbuf.h create mode 100644 src/gallium/drivers/llvmpipe/lp_setup_vbuf.c (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 345326e33d..6ec97046e1 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -35,13 +35,13 @@ C_SOURCES = \ lp_fence.c \ lp_flush.c \ lp_jit.c \ - lp_prim_vbuf.c \ lp_rast.c \ lp_rast_tri.c \ lp_setup.c \ lp_setup_line.c \ lp_setup_point.c \ lp_setup_tri.c \ + lp_setup_vbuf.c \ lp_query.c \ lp_screen.c \ lp_state_blend.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index f0b71ef3ee..ae4303bd24 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -46,7 +46,6 @@ llvmpipe = env.ConvenienceLibrary( 'lp_fence.c', 'lp_flush.c', 'lp_jit.c', - 'lp_prim_vbuf.c', 'lp_query.c', 'lp_scene.c', 'lp_scene_queue.c', @@ -55,6 +54,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_setup_line.c', 'lp_setup_point.c', 'lp_setup_tri.c', + 'lp_setup_vbuf.c', 'lp_state_blend.c', 'lp_state_clip.c', 'lp_state_derived.c', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 06aa032540..0457ccc8a9 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -31,14 +31,12 @@ */ #include "draw/draw_context.h" -#include "draw/draw_vbuf.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "lp_clear.h" #include "lp_context.h" #include "lp_flush.h" -#include "lp_prim_vbuf.h" #include "lp_state.h" #include "lp_surface.h" #include "lp_texture.h" @@ -179,23 +177,11 @@ llvmpipe_create( struct pipe_screen *screen ) if (debug_get_bool_option( "LP_NO_RAST", FALSE )) llvmpipe->no_rast = TRUE; - llvmpipe->setup = lp_setup_create( screen ); + llvmpipe->setup = lp_setup_create( screen, + llvmpipe->draw ); if (!llvmpipe->setup) goto fail; - llvmpipe->vbuf_backend = lp_create_vbuf_backend(llvmpipe); - if (!llvmpipe->vbuf_backend) - goto fail; - - llvmpipe->vbuf = draw_vbuf_stage(llvmpipe->draw, llvmpipe->vbuf_backend); - if (!llvmpipe->vbuf) - goto fail; - - draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->vbuf); - draw_set_render(llvmpipe->draw, llvmpipe->vbuf_backend); - - - /* plug in AA line/point stages */ draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe); draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe); diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 17c6939ff5..b796148457 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -93,17 +93,6 @@ struct llvmpipe_context { /** Which vertex shader output slot contains point size */ int psize_slot; - /* The reduced version of the primitive supplied by the state - * tracker. - */ - unsigned reduced_api_prim; - - /* The reduced primitive after unfilled triangles, wide-line - * decomposition, etc, are taken into account. This is the - * primitive actually rasterized. - */ - unsigned reduced_prim; - /** Derived from scissor and surface bounds: */ struct pipe_scissor_state cliprect; @@ -113,10 +102,6 @@ struct llvmpipe_context { /** The primitive drawing context */ struct draw_context *draw; - /** Draw module backend */ - struct vbuf_render *vbuf_backend; - struct draw_stage *vbuf; - unsigned tex_timestamp; boolean no_rast; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index b879b5e755..91fcbc01c6 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -70,8 +70,6 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, struct draw_context *draw = lp->draw; unsigned i; - lp->reduced_api_prim = u_reduced_prim(mode); - if (lp->dirty) llvmpipe_update_derived( lp ); diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c deleted file mode 100644 index 925e6f8b3b..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ /dev/null @@ -1,559 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Interface between 'draw' module's output and the llvmpipe rasterizer/setup - * code. When the 'draw' module has finished filling a vertex buffer, the - * draw_arrays() functions below will be called. Loop over the vertices and - * call the point/line/tri setup functions. - * - * Authors - * Brian Paul - */ - - -#include "lp_context.h" -#include "lp_state.h" -#include "lp_prim_vbuf.h" -#include "lp_setup.h" -#include "draw/draw_context.h" -#include "draw/draw_vbuf.h" -#include "util/u_memory.h" -#include "util/u_prim.h" - - -#define LP_MAX_VBUF_INDEXES 1024 -#define LP_MAX_VBUF_SIZE 4096 - -typedef const float (*cptrf4)[4]; - -/** - * Subclass of vbuf_render. - */ -struct llvmpipe_vbuf_render -{ - struct vbuf_render base; - struct llvmpipe_context *llvmpipe; - struct setup_context *setup; - - uint prim; - uint vertex_size; - uint nr_vertices; - uint vertex_buffer_size; - void *vertex_buffer; -}; - - -/** cast wrapper */ -static struct llvmpipe_vbuf_render * -llvmpipe_vbuf_render(struct vbuf_render *vbr) -{ - return (struct llvmpipe_vbuf_render *) vbr; -} - - - - - - - -static const struct vertex_info * -lp_vbuf_get_vertex_info(struct vbuf_render *vbr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe); -} - - -static boolean -lp_vbuf_allocate_vertices(struct vbuf_render *vbr, - ushort vertex_size, ushort nr_vertices) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - unsigned size = vertex_size * nr_vertices; - - if (cvbr->vertex_buffer_size < size) { - align_free(cvbr->vertex_buffer); - cvbr->vertex_buffer = align_malloc(size, 16); - cvbr->vertex_buffer_size = size; - } - - cvbr->vertex_size = vertex_size; - cvbr->nr_vertices = nr_vertices; - - return cvbr->vertex_buffer != NULL; -} - -static void -lp_vbuf_release_vertices(struct vbuf_render *vbr) -{ - /* keep the old allocation for next time */ -} - -static void * -lp_vbuf_map_vertices(struct vbuf_render *vbr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - return cvbr->vertex_buffer; -} - -static void -lp_vbuf_unmap_vertices(struct vbuf_render *vbr, - ushort min_index, - ushort max_index ) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size ); - /* do nothing */ -} - - -static boolean -lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - - llvmpipe_update_derived( cvbr->llvmpipe ); - - cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim); - cvbr->prim = prim; - return TRUE; - -} - - -static INLINE cptrf4 get_vert( const void *vertex_buffer, - int index, - int stride ) -{ - return (cptrf4)((char *)vertex_buffer + index * stride); -} - - -/** - * draw elements / indexed primitives - */ -static void -lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; - const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); - const void *vertex_buffer = cvbr->vertex_buffer; - struct setup_context *setup_ctx = cvbr->setup; - unsigned i; - - switch (cvbr->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < nr; i++) { - lp_setup_point( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 1; i < nr; i += 2) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < nr; i ++) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - for (i = 1; i < nr; i ++) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - if (nr) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[nr-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i+(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-(i&1)], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i+(i&1)-2], stride), - get_vert(vertex_buffer, indices[i-(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_QUADS: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride)); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. - */ - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); - } - break; - - default: - assert(0); - } -} - - -/** - * This function is hit when the draw module is working in pass-through mode. - * It's up to us to convert the vertex array into point/line/tri prims. - */ -static void -lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; - struct setup_context *setup_ctx = cvbr->setup; - const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); - const void *vertex_buffer = - (void *) get_vert(cvbr->vertex_buffer, start, stride); - unsigned i; - - switch (cvbr->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < nr; i++) { - lp_setup_point( setup_ctx, - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 1; i < nr; i += 2) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < nr; i ++) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - for (i = 1; i < nr; i ++) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - if (nr) { - lp_setup_line( setup_ctx, - get_vert(vertex_buffer, nr-1, stride), - get_vert(vertex_buffer, 0, stride) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i++) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i+(i&1)-1, stride), - get_vert(vertex_buffer, i-(i&1), stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i++) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i+(i&1)-2, stride), - get_vert(vertex_buffer, i-(i&1)-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_QUADS: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. - */ - for (i = 2; i < nr; i += 1) { - lp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride) ); - } - break; - - default: - assert(0); - } -} - - - -static void -lp_vbuf_destroy(struct vbuf_render *vbr) -{ - FREE(vbr); -} - - -/** - * Create the post-transform vertex handler for the given context. - */ -struct vbuf_render * -lp_create_vbuf_backend(struct llvmpipe_context *lp) -{ - struct llvmpipe_vbuf_render *cvbr = CALLOC_STRUCT(llvmpipe_vbuf_render); - - assert(lp->draw); - assert(lp->setup); - - - cvbr->base.max_indices = LP_MAX_VBUF_INDEXES; - cvbr->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE; - - cvbr->base.get_vertex_info = lp_vbuf_get_vertex_info; - cvbr->base.allocate_vertices = lp_vbuf_allocate_vertices; - cvbr->base.map_vertices = lp_vbuf_map_vertices; - cvbr->base.unmap_vertices = lp_vbuf_unmap_vertices; - cvbr->base.set_primitive = lp_vbuf_set_primitive; - cvbr->base.draw = lp_vbuf_draw; - cvbr->base.draw_arrays = lp_vbuf_draw_arrays; - cvbr->base.release_vertices = lp_vbuf_release_vertices; - cvbr->base.destroy = lp_vbuf_destroy; - - cvbr->llvmpipe = lp; - cvbr->setup = lp->setup; - - return &cvbr->base; -} diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h deleted file mode 100644 index 0676e2f42a..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef LP_VBUF_H -#define LP_VBUF_H - - -struct llvmpipe_context; - -extern struct vbuf_render * -lp_create_vbuf_backend(struct llvmpipe_context *llvmpipe); - - -#endif /* LP_VBUF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index e361e5df63..e2b21aed47 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -39,19 +39,22 @@ #include "util/u_surface.h" #include "lp_scene.h" #include "lp_scene_queue.h" -#include "lp_debug.h" -#include "lp_fence.h" -#include "lp_state.h" #include "lp_buffer.h" #include "lp_texture.h" +#include "lp_debug.h" +#include "lp_fence.h" +#include "lp_rast.h" #include "lp_setup_context.h" +#include "draw/draw_context.h" +#include "draw/draw_vbuf.h" + /** XXX temporary value, temporary here */ #define MAX_SCENES 2 -static void set_state( struct setup_context *, unsigned ); +static void set_scene_state( struct setup_context *, unsigned ); struct lp_scene * @@ -76,7 +79,7 @@ first_triangle( struct setup_context *setup, const float (*v1)[4], const float (*v2)[4]) { - set_state( setup, SETUP_ACTIVE ); + set_scene_state( setup, SETUP_ACTIVE ); lp_setup_choose_triangle( setup ); setup->triangle( setup, v0, v1, v2 ); } @@ -86,7 +89,7 @@ first_line( struct setup_context *setup, const float (*v0)[4], const float (*v1)[4]) { - set_state( setup, SETUP_ACTIVE ); + set_scene_state( setup, SETUP_ACTIVE ); lp_setup_choose_line( setup ); setup->line( setup, v0, v1 ); } @@ -95,7 +98,7 @@ static void first_point( struct setup_context *setup, const float (*v0)[4]) { - set_state( setup, SETUP_ACTIVE ); + set_scene_state( setup, SETUP_ACTIVE ); lp_setup_choose_point( setup ); setup->point( setup, v0 ); } @@ -194,7 +197,7 @@ execute_clears( struct setup_context *setup ) static void -set_state( struct setup_context *setup, +set_scene_state( struct setup_context *setup, unsigned new_state ) { unsigned old_state = setup->state; @@ -234,7 +237,7 @@ lp_setup_flush( struct setup_context *setup, { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - set_state( setup, SETUP_FLUSHED ); + set_scene_state( setup, SETUP_FLUSHED ); } @@ -246,7 +249,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - set_state( setup, SETUP_FLUSHED ); + set_scene_state( setup, SETUP_FLUSHED ); util_copy_framebuffer_state(&setup->fb, fb); @@ -302,7 +305,7 @@ lp_setup_clear( struct setup_context *setup, * buffers which the app or state-tracker might issue * separately. */ - set_state( setup, SETUP_CLEARED ); + set_scene_state( setup, SETUP_CLEARED ); setup->clear.flags |= flags; } @@ -321,7 +324,7 @@ lp_setup_fence( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank); - set_state( setup, SETUP_ACTIVE ); + set_scene_state( setup, SETUP_ACTIVE ); /* insert the fence into all command bins */ lp_scene_bin_everywhere( scene, @@ -358,13 +361,13 @@ lp_setup_set_fs_inputs( struct setup_context *setup, } void -lp_setup_set_fs( struct setup_context *setup, - struct lp_fragment_shader *fs ) +lp_setup_set_fs_function( struct setup_context *setup, + lp_jit_frag_func jit_function ) { - LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) fs); + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function); /* FIXME: reference count */ - setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL; + setup->fs.current.jit_function = jit_function; setup->dirty |= LP_SETUP_NEW_FS; } @@ -406,6 +409,25 @@ lp_setup_set_blend_color( struct setup_context *setup, } } + +void +lp_setup_set_flatshade_first( struct setup_context *setup, + boolean flatshade_first ) +{ + setup->flatshade_first = flatshade_first; +} + + +void +lp_setup_set_vertex_info( struct setup_context *setup, + struct vertex_info *vertex_info ) +{ + /* XXX: just silently holding onto the pointer: + */ + setup->vertex_info = vertex_info; +} + + void lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture) @@ -452,8 +474,8 @@ lp_setup_is_texture_referenced( struct setup_context *setup, } -static INLINE void -lp_setup_update_shader_state( struct setup_context *setup ) +void +lp_setup_update_state( struct setup_context *setup ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); @@ -548,36 +570,6 @@ lp_setup_update_shader_state( struct setup_context *setup ) } -/* Stubs for lines & points for now: - */ -void -lp_setup_point(struct setup_context *setup, - const float (*v0)[4]) -{ - lp_setup_update_shader_state(setup); - setup->point( setup, v0 ); -} - -void -lp_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) -{ - lp_setup_update_shader_state(setup); - setup->line( setup, v0, v1 ); -} - -void -lp_setup_tri(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4]) -{ - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - - lp_setup_update_shader_state(setup); - setup->triangle( setup, v0, v1, v2 ); -} void @@ -602,11 +594,13 @@ lp_setup_destroy( struct setup_context *setup ) /** - * Create a new primitive tiling engine. Currently also creates a - * rasterizer to use with it. + * Create a new primitive tiling engine. Plug it into the backend of + * the draw module. Currently also creates a rasterizer to use with + * it. */ struct setup_context * -lp_setup_create( struct pipe_screen *screen ) +lp_setup_create( struct pipe_screen *screen, + struct draw_context *draw ) { unsigned i; struct setup_context *setup = CALLOC_STRUCT(setup_context); @@ -614,6 +608,8 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup) return NULL; + lp_setup_init_vbuf(setup); + setup->empty_scenes = lp_scene_queue_create(); if (!setup->empty_scenes) goto fail; @@ -622,6 +618,13 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup->rast) goto fail; + setup->vbuf = draw_vbuf_stage(draw, &setup->base); + if (!setup->vbuf) + goto fail; + + draw_set_rasterize_stage(draw, setup->vbuf); + draw_set_render(draw, &setup->base); + /* create some empty scenes */ for (i = 0; i < MAX_SCENES; i++) { struct lp_scene *scene = lp_scene_create(); @@ -637,6 +640,12 @@ lp_setup_create( struct pipe_screen *screen ) return setup; fail: + if (setup->rast) + lp_rast_destroy( setup->rast ); + + if (setup->vbuf) + ; + if (setup->empty_scenes) lp_scene_queue_destroy(setup->empty_scenes); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 5c606e86af..a6120fcbe4 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -28,6 +28,10 @@ #define LP_SETUP_H #include "pipe/p_compiler.h" +#include "lp_jit.h" + +struct draw_context; +struct vertex_info; enum lp_interp { LP_INTERP_CONSTANT, @@ -58,7 +62,8 @@ struct lp_fragment_shader; struct lp_jit_context; struct setup_context * -lp_setup_create( struct pipe_screen *screen ); +lp_setup_create( struct pipe_screen *screen, + struct draw_context *draw ); void lp_setup_clear(struct setup_context *setup, @@ -71,22 +76,6 @@ struct pipe_fence_handle * lp_setup_fence( struct setup_context *setup ); -void -lp_setup_tri(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4]); - -void -lp_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]); - -void -lp_setup_point( struct setup_context *setup, - const float (*v0)[4] ); - - void lp_setup_flush( struct setup_context *setup, unsigned flags ); @@ -107,8 +96,8 @@ lp_setup_set_fs_inputs( struct setup_context *setup, unsigned nr ); void -lp_setup_set_fs( struct setup_context *setup, - struct lp_fragment_shader *fs ); +lp_setup_set_fs_function( struct setup_context *setup, + lp_jit_frag_func jit_function ); void lp_setup_set_fs_constants(struct setup_context *setup, @@ -131,6 +120,13 @@ boolean lp_setup_is_texture_referenced( struct setup_context *setup, const struct pipe_texture *texture ); +void +lp_setup_set_flatshade_first( struct setup_context *setup, + boolean flatshade_first ); + +void +lp_setup_set_vertex_info( struct setup_context *setup, + struct vertex_info *info ); void lp_setup_destroy( struct setup_context *setup ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index f6604a8034..d2278a46e6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -40,6 +40,7 @@ #include "lp_tile_soa.h" /* for TILE_SIZE */ #include "lp_scene.h" +#include "draw/draw_vbuf.h" #define LP_SETUP_NEW_FS 0x01 #define LP_SETUP_NEW_CONSTANTS 0x02 @@ -53,15 +54,31 @@ struct lp_scene_queue; * Point/line/triangle setup context. * Note: "stored" below indicates data which is stored in the bins, * not arbitrary malloc'd memory. + * + * + * Subclass of vbuf_render, plugged directly into the draw module as + * the rendering backend. */ -struct setup_context { - +struct setup_context +{ + struct vbuf_render base; + + struct vertex_info *vertex_info; + uint prim; + uint vertex_size; + uint nr_vertices; + uint vertex_buffer_size; + void *vertex_buffer; + + /* Final pipeline stage for draw module. Draw module should + * create/install this itself now. + */ + struct draw_stage *vbuf; struct lp_rasterizer *rast; - - struct lp_scene *scene; /**< current scene */ struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */ + boolean flatshade_first; boolean ccw_is_frontface; unsigned cullmode; @@ -120,4 +137,8 @@ void lp_setup_choose_point( struct setup_context *setup ); struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup); +void lp_setup_init_vbuf(struct setup_context *setup); + +void lp_setup_update_state( struct setup_context *setup ); + #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c new file mode 100644 index 0000000000..5cd4f354fd --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -0,0 +1,520 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Interface between 'draw' module's output and the llvmpipe rasterizer/setup + * code. When the 'draw' module has finished filling a vertex buffer, the + * draw_arrays() functions below will be called. Loop over the vertices and + * call the point/line/tri setup functions. + * + * Authors + * Brian Paul + */ + + +#include "lp_setup_context.h" +#include "draw/draw_context.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "util/u_memory.h" +#include "util/u_prim.h" + + +#define LP_MAX_VBUF_INDEXES 1024 +#define LP_MAX_VBUF_SIZE 4096 + + + +/** cast wrapper */ +static struct setup_context * +setup_context(struct vbuf_render *vbr) +{ + return (struct setup_context *) vbr; +} + + + +static const struct vertex_info * +lp_vbuf_get_vertex_info(struct vbuf_render *vbr) +{ + struct setup_context *setup = setup_context(vbr); + return setup->vertex_info; +} + + +static boolean +lp_vbuf_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) +{ + struct setup_context *setup = setup_context(vbr); + unsigned size = vertex_size * nr_vertices; + + if (setup->vertex_buffer_size < size) { + align_free(setup->vertex_buffer); + setup->vertex_buffer = align_malloc(size, 16); + setup->vertex_buffer_size = size; + } + + setup->vertex_size = vertex_size; + setup->nr_vertices = nr_vertices; + + return setup->vertex_buffer != NULL; +} + +static void +lp_vbuf_release_vertices(struct vbuf_render *vbr) +{ + /* keep the old allocation for next time */ +} + +static void * +lp_vbuf_map_vertices(struct vbuf_render *vbr) +{ + struct setup_context *setup = setup_context(vbr); + return setup->vertex_buffer; +} + +static void +lp_vbuf_unmap_vertices(struct vbuf_render *vbr, + ushort min_index, + ushort max_index ) +{ + struct setup_context *setup = setup_context(vbr); + assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size ); + /* do nothing */ +} + + +static boolean +lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) +{ + setup_context(vbr)->prim = prim; + return TRUE; +} + +typedef const float (*const_float4_ptr)[4]; + +static INLINE const_float4_ptr get_vert( const void *vertex_buffer, + int index, + int stride ) +{ + return (const_float4_ptr)((char *)vertex_buffer + index * stride); +} + +/** + * draw elements / indexed primitives + */ +static void +lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) +{ + struct setup_context *setup = setup_context(vbr); + const unsigned stride = setup->vertex_info->size * sizeof(float); + const void *vertex_buffer = setup->vertex_buffer; + unsigned i; + + lp_setup_update_state(setup); + + switch (setup->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup->point( setup, + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + if (nr) { + setup->line( setup, + get_vert(vertex_buffer, indices[nr-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + } + else { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i+(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-(i&1)], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i+(i&1)-2], stride), + get_vert(vertex_buffer, indices[i-(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride)); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + default: + assert(0); + } +} + + +/** + * This function is hit when the draw module is working in pass-through mode. + * It's up to us to convert the vertex array into point/line/tri prims. + */ +static void +lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) +{ + struct setup_context *setup = setup_context(vbr); + const unsigned stride = setup->vertex_info->size * sizeof(float); + const void *vertex_buffer = + (void *) get_vert(setup->vertex_buffer, start, stride); + unsigned i; + + lp_setup_update_state(setup); + + switch (setup->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup->point( setup, + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + if (nr) { + setup->line( setup, + get_vert(vertex_buffer, nr-1, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride) ); + } + } + else { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (setup->flatshade_first) { + for (i = 2; i < nr; i++) { + setup->triangle( setup, + get_vert(vertex_buffer, i+(i&1)-1, stride), + get_vert(vertex_buffer, i-(i&1), stride), + get_vert(vertex_buffer, i-2, stride) ); + } + } + else { + for (i = 2; i < nr; i++) { + setup->triangle( setup, + get_vert(vertex_buffer, i+(i&1)-2, stride), + get_vert(vertex_buffer, i-(i&1)-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup->triangle( setup, + + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + default: + assert(0); + } +} + + + +static void +lp_vbuf_destroy(struct vbuf_render *vbr) +{ + lp_setup_destroy(setup_context(vbr)); +} + + +/** + * Create the post-transform vertex handler for the given context. + */ +void +lp_setup_init_vbuf(struct setup_context *setup) +{ + setup->base.max_indices = LP_MAX_VBUF_INDEXES; + setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE; + + setup->base.get_vertex_info = lp_vbuf_get_vertex_info; + setup->base.allocate_vertices = lp_vbuf_allocate_vertices; + setup->base.map_vertices = lp_vbuf_map_vertices; + setup->base.unmap_vertices = lp_vbuf_unmap_vertices; + setup->base.set_primitive = lp_vbuf_set_primitive; + setup->base.draw = lp_vbuf_draw; + setup->base.draw_arrays = lp_vbuf_draw_arrays; + setup->base.release_vertices = lp_vbuf_release_vertices; + setup->base.destroy = lp_vbuf_destroy; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index a18efcc0e0..ab827045ed 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -37,17 +37,6 @@ #include "lp_state.h" -/** - * Mark the current vertex layout as "invalid". - * We'll validate the vertex layout later, when we start to actually - * render a point or line or tri. - */ -static void -invalidate_vertex_layout(struct llvmpipe_context *llvmpipe) -{ - llvmpipe->vertex_info.num_attribs = 0; -} - /** * The vertex info describes how to convert the post-transformed vertices @@ -57,150 +46,95 @@ invalidate_vertex_layout(struct llvmpipe_context *llvmpipe) * This function validates the vertex layout and returns a pointer to a * vertex_info object. */ -struct vertex_info * -llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe) +static void +compute_vertex_info(struct llvmpipe_context *llvmpipe) { - struct vertex_info *vinfo = &llvmpipe->vertex_info; - - if (vinfo->num_attribs == 0) { - /* compute vertex layout now */ - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const enum interp_mode colorInterp - = llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; - struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf; - const uint num = draw_num_vs_outputs(llvmpipe->draw); - uint i; - - /* Tell draw_vbuf to simply emit the whole post-xform vertex - * as-is. No longer any need to try and emit draw vertex_header - * info. - */ - vinfo_vbuf->num_attribs = 0; - for (i = 0; i < num; i++) { - draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); - } - draw_compute_vertex_size(vinfo_vbuf); + const struct lp_fragment_shader *lpfs = llvmpipe->fs; + struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf; + const uint num = draw_num_vs_outputs(llvmpipe->draw); + uint i; + + /* Tell draw_vbuf to simply emit the whole post-xform vertex as-is. + * + * Not really sure if this is the best approach. + */ + vinfo_vbuf->num_attribs = 0; + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); + } + draw_compute_vertex_size(vinfo_vbuf); - /* - * Loop over fragment shader inputs, searching for the matching output - * from the vertex shader. - */ - vinfo->num_attribs = 0; - for (i = 0; i < lpfs->info.num_inputs; i++) { - int src; - enum interp_mode interp; - switch (lpfs->info.input_interpolate[i]) { - case TGSI_INTERPOLATE_CONSTANT: - interp = INTERP_CONSTANT; - break; - case TGSI_INTERPOLATE_LINEAR: - interp = INTERP_LINEAR; - break; - case TGSI_INTERPOLATE_PERSPECTIVE: - interp = INTERP_PERSPECTIVE; - break; - default: - assert(0); - interp = INTERP_LINEAR; - } + lp_setup_set_vertex_info(llvmpipe->setup, vinfo_vbuf); - switch (lpfs->info.input_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - src = draw_find_vs_output(llvmpipe->draw, - TGSI_SEMANTIC_POSITION, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); - break; +/* + llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, + TGSI_SEMANTIC_PSIZE, 0); +*/ - case TGSI_SEMANTIC_COLOR: - src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR, - lpfs->info.input_semantic_index[i]); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - break; + /* Now match FS inputs against emitted vertex data. It's also + * entirely possible to just have a fixed layout for FS input, + * determined by the fragment shader itself, and adjust the draw + * outputs to match that. + */ + { + struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; - case TGSI_SEMANTIC_FOG: - src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src); - break; + for (i = 0; i < lpfs->info.num_inputs; i++) { - case TGSI_SEMANTIC_GENERIC: + /* This can be precomputed, except for flatshade: + */ + switch (lpfs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_FACE: - /* this includes texcoords and varying vars */ - src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC, - lpfs->info.input_semantic_index[i]); - draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src); + inputs[i].interp = LP_INTERP_FACING; + break; + case TGSI_SEMANTIC_POSITION: + inputs[i].interp = LP_INTERP_POSITION; + break; + case TGSI_SEMANTIC_COLOR: + /* Colors are linearly interpolated in the fragment shader + * even when flatshading is active. This just tells the + * setup module to use coefficients with ddx==0 and + * ddy==0. + */ + if (llvmpipe->rasterizer->flatshade) + inputs[i].interp = LP_INTERP_CONSTANT; + else + inputs[i].interp = LP_INTERP_LINEAR; break; default: - assert(0); - } - } - - llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, - TGSI_SEMANTIC_PSIZE, 0); - if (llvmpipe->psize_slot > 0) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, - llvmpipe->psize_slot); - } - - draw_compute_vertex_size(vinfo); - - { - struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; - - for (i = 0; i < lpfs->info.num_inputs; i++) { - switch (vinfo->attrib[i].interp_mode) { - case INTERP_CONSTANT: + switch (lpfs->info.input_interpolate[i]) { + case TGSI_INTERPOLATE_CONSTANT: inputs[i].interp = LP_INTERP_CONSTANT; break; - case INTERP_LINEAR: + case TGSI_INTERPOLATE_LINEAR: inputs[i].interp = LP_INTERP_LINEAR; break; - case INTERP_PERSPECTIVE: + case TGSI_INTERPOLATE_PERSPECTIVE: inputs[i].interp = LP_INTERP_PERSPECTIVE; break; - case INTERP_POS: - inputs[i].interp = LP_INTERP_POSITION; - break; default: assert(0); + break; } - - if (lpfs->info.input_semantic_name[i] == TGSI_SEMANTIC_FACE) - inputs[i].interp = LP_INTERP_FACING; - - inputs[i].src_index = vinfo->attrib[i].src_index; } - lp_setup_set_fs_inputs(llvmpipe->setup, inputs, lpfs->info.num_inputs); + /* Search for each input in current vs output: + */ + inputs[i].src_index = + draw_find_vs_output(llvmpipe->draw, + lpfs->info.input_semantic_name[i], + lpfs->info.input_semantic_index[i]); } - } - return vinfo; + lp_setup_set_fs_inputs(llvmpipe->setup, + inputs, + lpfs->info.num_inputs); + } } -/** - * Called from vbuf module. - * - * Note that there's actually two different vertex layouts in llvmpipe. - * - * The normal one is computed in llvmpipe_get_vertex_info() above and is - * used by the point/line/tri "setup" code. - * - * The other one (this one) is only used by the vbuf module (which is - * not normally used by default but used in testing). For the vbuf module, - * we basically want to pass-through the draw module's vertex layout as-is. - * When the llvmpipe vbuf code begins drawing, the normal vertex layout - * will come into play again. - */ -struct vertex_info * -llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe) -{ - (void) llvmpipe_get_vertex_info(llvmpipe); - return &llvmpipe->vertex_info_vbuf; -} - /** * Recompute cliprect from scissor bounds, scissor enable and surface size. @@ -273,7 +207,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) if (llvmpipe->dirty & (LP_NEW_RASTERIZER | LP_NEW_FS | LP_NEW_VS)) - invalidate_vertex_layout( llvmpipe ); + compute_vertex_info( llvmpipe ); if (llvmpipe->dirty & (LP_NEW_SCISSOR | LP_NEW_RASTERIZER | @@ -287,36 +221,23 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) LP_NEW_TEXTURE)) llvmpipe_update_fs( llvmpipe ); - if (llvmpipe->dirty & (LP_NEW_BLEND | - LP_NEW_DEPTH_STENCIL_ALPHA | - LP_NEW_SAMPLER | - LP_NEW_TEXTURE)) - llvmpipe_update_fs( llvmpipe ); - if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) - lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); + lp_setup_set_blend_color(llvmpipe->setup, + &llvmpipe->blend_color); if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) - lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); + lp_setup_set_alpha_ref_value(llvmpipe->setup, + llvmpipe->depth_stencil->alpha.ref_value); if (llvmpipe->dirty & LP_NEW_CONSTANTS) - lp_setup_set_fs_constants(llvmpipe->setup, llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer); + lp_setup_set_fs_constants(llvmpipe->setup, + llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer); if (llvmpipe->dirty & LP_NEW_TEXTURE) - lp_setup_set_sampler_textures(llvmpipe->setup, llvmpipe->num_textures, llvmpipe->texture); + lp_setup_set_sampler_textures(llvmpipe->setup, + llvmpipe->num_textures, + llvmpipe->texture); llvmpipe->dirty = 0; } - -#if 0 -void llvmpipe_prepare(struct lp_setup_context *setup) -{ - struct llvmpipe_context *lp = setup->llvmpipe; - - if (lp->dirty) { - llvmpipe_update_derived(lp); - } - -} -#endif diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 7ed727dbbc..3ad58415e3 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -891,5 +891,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) shader->current = variant; - lp_setup_set_fs(lp->setup, shader); + lp_setup_set_fs_function(lp->setup, + shader->current->jit_function); } -- cgit v1.2.3 From b08583da468ee186b43ea678f8d33fb7df3ab372 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 6 Jan 2010 17:13:37 +0000 Subject: llvmpipe: fix double free --- src/gallium/drivers/llvmpipe/lp_context.c | 5 ++--- src/gallium/drivers/llvmpipe/lp_setup.c | 3 ++- src/gallium/drivers/llvmpipe/lp_setup.h | 2 -- src/gallium/drivers/llvmpipe/lp_setup_context.h | 2 ++ 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 0457ccc8a9..696a9d5f6a 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -53,12 +53,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); uint i; + /* This will also destroy llvmpipe->setup: + */ if (llvmpipe->draw) draw_destroy( llvmpipe->draw ); - if (llvmpipe->setup) - lp_setup_destroy( llvmpipe->setup ); - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { pipe_surface_reference(&llvmpipe->framebuffer.cbufs[i], NULL); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index e2b21aed47..1eb944a0de 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -571,7 +571,8 @@ lp_setup_update_state( struct setup_context *setup ) - +/* Only caller is lp_setup_vbuf_destroy() + */ void lp_setup_destroy( struct setup_context *setup ) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index a6120fcbe4..bf12cb8527 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -128,7 +128,5 @@ void lp_setup_set_vertex_info( struct setup_context *setup, struct vertex_info *info ); -void -lp_setup_destroy( struct setup_context *setup ); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index d2278a46e6..a1808fcd4c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -141,4 +141,6 @@ void lp_setup_init_vbuf(struct setup_context *setup); void lp_setup_update_state( struct setup_context *setup ); +void lp_setup_destroy( struct setup_context *setup ); + #endif -- cgit v1.2.3 From c1a04416023e24621e4992caf593e8dfe8d7a2fc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 10 Jan 2010 17:22:09 +0000 Subject: llvmpipe: initial mrt support Non-mrt apps work, and the code looks correct, but not many mrt test apps handy atm... --- src/gallium/drivers/llvmpipe/lp_flush.c | 7 +- src/gallium/drivers/llvmpipe/lp_jit.h | 2 +- src/gallium/drivers/llvmpipe/lp_rast.c | 215 +++++++++++++++++----------- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 6 +- src/gallium/drivers/llvmpipe/lp_setup.c | 18 +-- src/gallium/drivers/llvmpipe/lp_state.h | 6 + src/gallium/drivers/llvmpipe/lp_state_fs.c | 114 +++++++++------ 7 files changed, 225 insertions(+), 143 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 9405150c4f..16fb00092e 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -77,8 +77,11 @@ llvmpipe_flush( struct pipe_context *pipe, if(flags & PIPE_FLUSH_FRAME) { static unsigned frame_no = 1; static char filename[256]; - util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no); - debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[0]); + unsigned i; + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs) { + util_snprintf(filename, sizeof(filename), "cbuf%u_%u.bmp", i, frame_no); + debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[i]); + } util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no); debug_dump_surface_bmp(filename, llvmpipe->framebuffer.zsbuf); ++frame_no; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 1a6e939aa2..3b316914b0 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -108,7 +108,7 @@ typedef void const void *a0, const void *dadx, const void *dady, - void *color, + uint8_t **color, void *depth, const int32_t c1, const int32_t c2, diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6535e69308..38c27b90e3 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -53,6 +53,7 @@ lp_rast_begin( struct lp_rasterizer *rast, { struct pipe_screen *screen = rast->screen; struct pipe_surface *cbuf, *zsbuf; + int i; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -64,24 +65,27 @@ lp_rast_begin( struct lp_rasterizer *rast, rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 || fb->height % TILE_SIZE != 0); - /* XXX support multiple color buffers here */ - cbuf = rast->state.fb.cbufs[0]; - if (cbuf) { - rast->cbuf_transfer = screen->get_tex_transfer(rast->screen, - cbuf->texture, - cbuf->face, - cbuf->level, - cbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, - fb->width, fb->height); - if (!rast->cbuf_transfer) - return FALSE; - - rast->cbuf_map = screen->transfer_map(rast->screen, - rast->cbuf_transfer); - if (!rast->cbuf_map) - return FALSE; + + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + cbuf = rast->state.fb.cbufs[i]; + if (cbuf) { + rast->cbuf_transfer[i] = screen->get_tex_transfer(rast->screen, + cbuf->texture, + cbuf->face, + cbuf->level, + cbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, + cbuf->width, + cbuf->height); + if (!rast->cbuf_transfer[i]) + goto fail; + + rast->cbuf_map[i] = screen->transfer_map(rast->screen, + rast->cbuf_transfer[i]); + if (!rast->cbuf_map[i]) + goto fail; + } } zsbuf = rast->state.fb.zsbuf; @@ -93,17 +97,23 @@ lp_rast_begin( struct lp_rasterizer *rast, zsbuf->zslice, PIPE_TRANSFER_READ_WRITE, 0, 0, - fb->width, fb->height); + zsbuf->width, + zsbuf->height); if (!rast->zsbuf_transfer) - return FALSE; + goto fail; rast->zsbuf_map = screen->transfer_map(rast->screen, rast->zsbuf_transfer); if (!rast->zsbuf_map) - return FALSE; + goto fail; } return TRUE; + +fail: + /* Unmap and release transfers? + */ + return FALSE; } @@ -115,22 +125,26 @@ static void lp_rast_end( struct lp_rasterizer *rast ) { struct pipe_screen *screen = rast->screen; + unsigned i; - if (rast->cbuf_map) - screen->transfer_unmap(screen, rast->cbuf_transfer); + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + if (rast->cbuf_map[i]) + screen->transfer_unmap(screen, rast->cbuf_transfer[i]); + + if (rast->cbuf_transfer[i]) + screen->tex_transfer_destroy(rast->cbuf_transfer[i]); + + rast->cbuf_transfer[i] = NULL; + rast->cbuf_map[i] = NULL; + } if (rast->zsbuf_map) screen->transfer_unmap(screen, rast->zsbuf_transfer); - if (rast->cbuf_transfer) - screen->tex_transfer_destroy(rast->cbuf_transfer); - if (rast->zsbuf_transfer) screen->tex_transfer_destroy(rast->zsbuf_transfer); - rast->cbuf_transfer = NULL; rast->zsbuf_transfer = NULL; - rast->cbuf_map = NULL; rast->zsbuf_map = NULL; } @@ -161,8 +175,9 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { const uint8_t *clear_color = arg.clear_color; - uint8_t *color_tile = rast->tasks[thread_index].tile.color; - + uint8_t **color_tile = rast->tasks[thread_index].tile.color; + unsigned i; + LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, clear_color[0], clear_color[1], @@ -172,14 +187,17 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && clear_color[2] == clear_color[3]) { - memset(color_tile, clear_color[0], TILE_SIZE * TILE_SIZE * 4); + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4); + } } else { unsigned x, y, chan; - for (y = 0; y < TILE_SIZE; y++) - for (x = 0; x < TILE_SIZE; x++) - for (chan = 0; chan < 4; ++chan) - TILE_PIXEL(color_tile, x, y, chan) = clear_color[chan]; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + for (y = 0; y < TILE_SIZE; y++) + for (x = 0; x < TILE_SIZE; x++) + for (chan = 0; chan < 4; ++chan) + TILE_PIXEL(color_tile[i], x, y, chan) = clear_color[chan]; } } @@ -214,28 +232,40 @@ void lp_rast_load_color( struct lp_rasterizer *rast, struct lp_rasterizer_task *task = &rast->tasks[thread_index]; const unsigned x = task->x; const unsigned y = task->y; - int w = TILE_SIZE; - int h = TILE_SIZE; + unsigned i; LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y); - if (x + w > rast->state.fb.width) - w -= x + w - rast->state.fb.width; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + struct pipe_transfer *transfer = rast->cbuf_transfer[i]; + int w = TILE_SIZE; + int h = TILE_SIZE; - if (y + h > rast->state.fb.height) - h -= y + h - rast->state.fb.height; + if (x >= transfer->width) + continue; - assert(w >= 0); - assert(h >= 0); - assert(w <= TILE_SIZE); - assert(h <= TILE_SIZE); - - lp_tile_read_4ub(rast->cbuf_transfer->texture->format, - rast->tasks[thread_index].tile.color, - rast->cbuf_map, - rast->cbuf_transfer->stride, - x, y, - w, h); + if (y >= transfer->height) + continue; + /* XXX: require tile-size aligned render target dimensions: + */ + if (x + w > transfer->width) + w -= x + w - transfer->width; + + if (y + h > transfer->height) + h -= y + h - transfer->height; + + assert(w >= 0); + assert(h >= 0); + assert(w <= TILE_SIZE); + assert(h <= TILE_SIZE); + + lp_tile_read_4ub(transfer->texture->format, + rast->tasks[thread_index].tile.color[i], + rast->cbuf_map[i], + transfer->stride, + x, y, + w, h); + } } @@ -313,8 +343,9 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, { const struct lp_rast_state *state = rast->tasks[thread_index].current_state; struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; - void *color; + uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; + unsigned i; unsigned ix, iy; int block_offset; @@ -336,14 +367,17 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, block_offset = ((iy/4)*(16*16) + (ix/4)*16); /* color buffer */ - color = tile->color + 4 * block_offset; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; /* depth buffer */ depth = tile->depth + block_offset; + + #ifdef DEBUG - assert(lp_check_alignment(depth, 16)); - assert(lp_check_alignment(color, 16)); + assert(lp_check_alignment(tile->depth, 16)); + assert(lp_check_alignment(tile->color[0], 16)); assert(lp_check_alignment(state->jit_context.blend_color, 16)); assert(lp_check_alignment(inputs->step[0], 16)); @@ -360,8 +394,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, color, depth, c1, c2, c3, - inputs->step[0], inputs->step[1], inputs->step[2] - ); + inputs->step[0], inputs->step[1], inputs->step[2]); } @@ -377,29 +410,42 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, { const unsigned x = rast->tasks[thread_index].x; const unsigned y = rast->tasks[thread_index].y; - int w = TILE_SIZE; - int h = TILE_SIZE; - - if (x + w > rast->state.fb.width) - w -= x + w - rast->state.fb.width; + unsigned i; - if (y + h > rast->state.fb.height) - h -= y + h - rast->state.fb.height; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + struct pipe_transfer *transfer = rast->cbuf_transfer[i]; + int w = TILE_SIZE; + int h = TILE_SIZE; - assert(w >= 0); - assert(h >= 0); - assert(w <= TILE_SIZE); - assert(h <= TILE_SIZE); + if (x >= transfer->width) + continue; - LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, - thread_index, x, y, w, h); + if (y >= transfer->height) + continue; - lp_tile_write_4ub(rast->cbuf_transfer->texture->format, - rast->tasks[thread_index].tile.color, - rast->cbuf_map, - rast->cbuf_transfer->stride, - x, y, - w, h); + /* XXX: require tile-size aligned render target dimensions: + */ + if (x + w > transfer->width) + w -= x + w - transfer->width; + + if (y + h > transfer->height) + h -= y + h - transfer->height; + + assert(w >= 0); + assert(h >= 0); + assert(w <= TILE_SIZE); + assert(h <= TILE_SIZE); + + LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, + thread_index, x, y, w, h); + + lp_tile_write_4ub(transfer->texture->format, + rast->tasks[thread_index].tile.color[i], + rast->cbuf_map[i], + transfer->stride, + x, y, + w, h); + } } @@ -600,7 +646,7 @@ lp_rasterize_scene( struct lp_rasterizer *rast, /* no threading */ lp_rast_begin( rast, fb, - fb->cbufs[0]!= NULL, + fb->nr_cbufs != 0, /* always write color if cbufs present */ fb->zsbuf != NULL && write_depth ); lp_scene_bin_iter_begin( scene ); @@ -667,7 +713,7 @@ thread_func( void *init_data ) write_depth = rast->curr_scene->write_depth; lp_rast_begin( rast, fb, - fb->cbufs[0] != NULL, + fb->nr_cbufs != 0, fb->zsbuf != NULL && write_depth ); } @@ -738,7 +784,7 @@ struct lp_rasterizer * lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) { struct lp_rasterizer *rast; - unsigned i; + unsigned i, cbuf; rast = CALLOC_STRUCT(lp_rasterizer); if(!rast) @@ -750,7 +796,9 @@ lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) rast->full_scenes = lp_scene_queue_create(); for (i = 0; i < Elements(rast->tasks); i++) { - rast->tasks[i].tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); + for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) + rast->tasks[i].tile.color[cbuf] = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); + rast->tasks[i].tile.depth = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); rast->tasks[i].rast = rast; rast->tasks[i].thread_index = i; @@ -769,13 +817,14 @@ lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) */ void lp_rast_destroy( struct lp_rasterizer *rast ) { - unsigned i; + unsigned i, cbuf; util_unreference_framebuffer_state(&rast->state.fb); for (i = 0; i < Elements(rast->tasks); i++) { align_free(rast->tasks[i].tile.depth); - align_free(rast->tasks[i].tile.color); + for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) + align_free(rast->tasks[i].tile.color[cbuf]); } /* for synchronizing rasterization threads */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index cd72d7e69d..5afdeab049 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -46,7 +46,7 @@ struct lp_rasterizer; */ struct lp_rast_tile { - uint8_t *color; + uint8_t *color[PIPE_MAX_COLOR_BUFS]; uint32_t *depth; }; @@ -87,9 +87,9 @@ struct lp_rasterizer /* Framebuffer stuff */ struct pipe_screen *screen; - struct pipe_transfer *cbuf_transfer; + struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS]; struct pipe_transfer *zsbuf_transfer; - void *cbuf_map; + void *cbuf_map[PIPE_MAX_COLOR_BUFS]; void *zsbuf_map; struct { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 5cdcf4ecc9..74f3054864 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -155,26 +155,26 @@ begin_binning( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (setup->fb.cbufs[0]) { + if (setup->fb.nr_cbufs) { if (setup->clear.flags & PIPE_CLEAR_COLOR) lp_scene_bin_everywhere( scene, - lp_rast_clear_color, - setup->clear.color ); + lp_rast_clear_color, + setup->clear.color ); else lp_scene_bin_everywhere( scene, - lp_rast_load_color, - lp_rast_arg_null() ); + lp_rast_load_color, + lp_rast_arg_null() ); } if (setup->fb.zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) lp_scene_bin_everywhere( scene, - lp_rast_clear_zstencil, - setup->clear.zstencil ); + lp_rast_clear_zstencil, + setup->clear.zstencil ); else lp_scene_bin_everywhere( scene, - lp_rast_load_zstencil, - lp_rast_arg_null() ); + lp_rast_load_zstencil, + lp_rast_arg_null() ); } LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__); diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 25d1353674..cb240cb6e5 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -67,10 +67,16 @@ struct lp_fragment_shader; struct lp_fragment_shader_variant_key { enum pipe_format zsbuf_format; + unsigned nr_cbufs; + struct pipe_depth_state depth; struct pipe_alpha_state alpha; struct pipe_blend_state blend; + struct { + ubyte colormask; + } cbuf_blend[PIPE_MAX_COLOR_BUFS]; + struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS]; }; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 293535387a..01912d6ea2 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -327,7 +327,7 @@ generate_fs(struct llvmpipe_context *lp, const struct lp_build_interp_soa_context *interp, struct lp_build_sampler_soa *sampler, LLVMValueRef *pmask, - LLVMValueRef *color, + LLVMValueRef (*color)[4], LLVMValueRef depth_ptr, LLVMValueRef c0, LLVMValueRef c1, @@ -348,6 +348,7 @@ generate_fs(struct llvmpipe_context *lp, boolean early_depth_test; unsigned attrib; unsigned chan; + unsigned cbuf; assert(i < 4); @@ -364,9 +365,11 @@ generate_fs(struct llvmpipe_context *lp, lp_build_flow_scope_begin(flow); /* Declare the color and z variables */ - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - color[chan] = LLVMGetUndef(vec_type); - lp_build_flow_scope_declare(flow, &color[chan]); + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { + for(chan = 0; chan < NUM_CHANNELS; ++chan) { + color[cbuf][chan] = LLVMGetUndef(vec_type); + lp_build_flow_scope_declare(flow, &color[cbuf][chan]); + } } lp_build_flow_scope_declare(flow, &z); @@ -407,6 +410,7 @@ generate_fs(struct llvmpipe_context *lp, /* Alpha test */ /* XXX: should the alpha reference value be passed separately? */ + /* XXX: should only test the final assignment to alpha */ if(cbuf == 0 && chan == 3) { LLVMValueRef alpha = outputs[attrib][chan]; LLVMValueRef alpha_ref_value; @@ -416,9 +420,7 @@ generate_fs(struct llvmpipe_context *lp, &mask, alpha, alpha_ref_value); } - if(cbuf == 0) - color[chan] = outputs[attrib][chan]; - + color[cbuf][chan] = outputs[attrib][chan]; break; } @@ -539,7 +541,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef a0_ptr; LLVMValueRef dadx_ptr; LLVMValueRef dady_ptr; - LLVMValueRef color_ptr; + LLVMValueRef color_ptr_ptr; LLVMValueRef depth_ptr; LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr; LLVMBasicBlockRef block; @@ -549,12 +551,13 @@ generate_fragment(struct llvmpipe_context *lp, struct lp_build_sampler_soa *sampler; struct lp_build_interp_soa_context interp; LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH]; - LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; + LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; LLVMValueRef blend_mask; LLVMValueRef blend_in_color[NUM_CHANNELS]; unsigned num_fs; unsigned i; unsigned chan; + unsigned cbuf; if (LP_DEBUG & DEBUG_JIT) { tgsi_dump(shader->base.tokens, 0); @@ -651,7 +654,7 @@ generate_fragment(struct llvmpipe_context *lp, arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */ arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */ arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */ - arg_types[6] = LLVMPointerType(blend_vec_type, 0); /* color */ + arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */ arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ arg_types[8] = LLVMInt32Type(); /* c0 */ arg_types[9] = LLVMInt32Type(); /* c1 */ @@ -667,6 +670,10 @@ generate_fragment(struct llvmpipe_context *lp, variant->function = LLVMAddFunction(screen->module, "shader", func_type); LLVMSetFunctionCallConv(variant->function, LLVMCCallConv); + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? + */ for(i = 0; i < Elements(arg_types); ++i) if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute); @@ -677,7 +684,7 @@ generate_fragment(struct llvmpipe_context *lp, a0_ptr = LLVMGetParam(variant->function, 3); dadx_ptr = LLVMGetParam(variant->function, 4); dady_ptr = LLVMGetParam(variant->function, 5); - color_ptr = LLVMGetParam(variant->function, 6); + color_ptr_ptr = LLVMGetParam(variant->function, 6); depth_ptr = LLVMGetParam(variant->function, 7); c0 = LLVMGetParam(variant->function, 8); c1 = LLVMGetParam(variant->function, 9); @@ -692,7 +699,7 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(a0_ptr, "a0"); lp_build_name(dadx_ptr, "dadx"); lp_build_name(dady_ptr, "dady"); - lp_build_name(color_ptr, "color"); + lp_build_name(color_ptr_ptr, "color_ptr"); lp_build_name(depth_ptr, "depth"); lp_build_name(c0, "c0"); lp_build_name(c1, "c1"); @@ -721,8 +728,9 @@ generate_fragment(struct llvmpipe_context *lp, /* loop over quads in the block */ for(i = 0; i < num_fs; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - LLVMValueRef out_color[NUM_CHANNELS]; + LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS]; LLVMValueRef depth_ptr_i; + int cbuf; if(i != 0) lp_build_interp_soa_update(&interp, i); @@ -742,40 +750,50 @@ generate_fragment(struct llvmpipe_context *lp, c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); - for(chan = 0; chan < NUM_CHANNELS; ++chan) - fs_out_color[chan][i] = out_color[chan]; + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) + for(chan = 0; chan < NUM_CHANNELS; ++chan) + fs_out_color[cbuf][chan][i] = out_color[cbuf][chan]; } sampler->destroy(sampler); - /* - * Convert the fs's output color and mask to fit to the blending type. + /* Loop over color outputs / color buffers to do blending. */ + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { + LLVMValueRef color_ptr; + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0); - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - lp_build_conv(builder, fs_type, blend_type, - fs_out_color[chan], num_fs, - &blend_in_color[chan], 1); - lp_build_name(blend_in_color[chan], "color.%c", "rgba"[chan]); + /* + * Convert the fs's output color and mask to fit to the blending type. + */ + for(chan = 0; chan < NUM_CHANNELS; ++chan) { + lp_build_conv(builder, fs_type, blend_type, + fs_out_color[cbuf][chan], num_fs, + &blend_in_color[chan], 1); + lp_build_name(blend_in_color[chan], "color%d.%c", cbuf, "rgba"[chan]); + } + lp_build_conv_mask(builder, fs_type, blend_type, + fs_mask, num_fs, + &blend_mask, 1); + + color_ptr = LLVMBuildLoad(builder, + LLVMBuildGEP(builder, color_ptr_ptr, &index, 1, ""), + ""); + lp_build_name(color_ptr, "color_ptr%d", cbuf); + + /* + * Blending. + */ + generate_blend(&key->blend, + builder, + blend_type, + context_ptr, + blend_mask, + blend_in_color, + color_ptr); } - lp_build_conv_mask(builder, fs_type, blend_type, - fs_mask, num_fs, - &blend_mask, 1); - - /* - * Blending. - */ - - generate_blend(&key->blend, - builder, - blend_type, - context_ptr, - blend_mask, - blend_in_color, - color_ptr); - LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -940,21 +958,27 @@ make_variant_key(struct llvmpipe_context *lp, key->alpha.func = lp->depth_stencil->alpha.func; /* alpha.ref_value is passed in jit_context */ - if(lp->framebuffer.cbufs[0]) { + if (lp->framebuffer.nr_cbufs) { + memcpy(&key->blend, lp->blend, sizeof key->blend); + } + + key->nr_cbufs = lp->framebuffer.nr_cbufs; + for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { const struct util_format_description *format_desc; unsigned chan; - memcpy(&key->blend, lp->blend, sizeof key->blend); - - format_desc = util_format_description(lp->framebuffer.cbufs[0]->format); + format_desc = util_format_description(lp->framebuffer.cbufs[i]->format); assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB || format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB); - /* mask out color channels not present in the color buffer */ + /* mask out color channels not present in the color buffer. + * Should be simple to incorporate per-cbuf writemasks: + */ for(chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; - if(swizzle > 4) - key->blend.colormask &= ~(1 << chan); + + if(swizzle <= UTIL_FORMAT_SWIZZLE_W) + key->cbuf_blend[i].colormask |= (1 << chan); } } -- cgit v1.2.3 From da45f49cc63fff06513dc28d9616084fc81798d4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 13 Jan 2010 14:41:02 +0000 Subject: llvmpipe: quick hack to short-circuit empty bins --- src/gallium/drivers/llvmpipe/lp_rast.c | 23 ++++++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_setup.c | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 38c27b90e3..4c13d4d80b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -576,6 +576,26 @@ rasterize_bin( struct lp_rasterizer *rast, lp_rast_end_tile( rast, thread_index ); } +static boolean +is_empty_bin( struct lp_rasterizer *rast, + const struct cmd_bin *bin ) +{ + const struct cmd_block *head = bin->commands.head; + int i; + + if (head->next != NULL || + head->count > PIPE_MAX_COLOR_BUFS + 1) + return FALSE; + + for (i = 0; i < head->count; i++) + if (head->cmd[i] != lp_rast_load_color && + head->cmd[i] != lp_rast_load_zstencil) + return FALSE; + + return TRUE; +} + + /** * Rasterize/execute all bins within a scene. @@ -606,7 +626,8 @@ rasterize_scene( struct lp_rasterizer *rast, assert(scene); while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { - rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); + if (!is_empty_bin( rast, bin )) + rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); } } #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 74f3054864..38ea0c663f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -153,7 +153,9 @@ begin_binning( struct setup_context *setup ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__, + (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load", + (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load"); if (setup->fb.nr_cbufs) { if (setup->clear.flags & PIPE_CLEAR_COLOR) -- cgit v1.2.3 From a1acbff299c444913418e65da473745cd901a2db Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 13 Jan 2010 21:51:47 +0000 Subject: llvmpipe: Reset the bin when shading a whole tile with an opaque shader. --- src/gallium/drivers/llvmpipe/lp_rast.h | 2 ++ src/gallium/drivers/llvmpipe/lp_scene.c | 33 +++++++++++++++++------------ src/gallium/drivers/llvmpipe/lp_scene.h | 4 ++++ src/gallium/drivers/llvmpipe/lp_setup.c | 4 +++- src/gallium/drivers/llvmpipe/lp_setup.h | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 6 ++++++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 12 ++++++++++- 7 files changed, 48 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 46e22f69a6..d926adb6b2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -68,6 +68,8 @@ struct lp_rast_state { * the tile color/z/stencil data somehow: */ lp_jit_frag_func jit_function; + + boolean opaque; }; diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 45d5446267..967d666bb4 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -88,6 +88,25 @@ lp_scene_is_empty(struct lp_scene *scene ) } +void +lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y) +{ + struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + struct cmd_block_list *list = &bin->commands; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->count = 0; +} + + /** * Set scene to empty state. */ @@ -100,19 +119,7 @@ lp_scene_reset(struct lp_scene *scene ) */ for (i = 0; i < scene->tiles_x; i++) { for (j = 0; j < scene->tiles_y; j++) { - struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); - struct cmd_block_list *list = &bin->commands; - struct cmd_block *block; - struct cmd_block *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->count = 0; + lp_scene_bin_reset(scene, i, j); } } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index b59b687002..4b6527d67c 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -215,6 +215,10 @@ lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y) } +/** Remove all commands from a bin */ +void +lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y); + /* Add a command to bin[x][y]. */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 38ea0c663f..61b968c49f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -364,12 +364,14 @@ lp_setup_set_fs_inputs( struct setup_context *setup, void lp_setup_set_fs_function( struct setup_context *setup, - lp_jit_frag_func jit_function ) + lp_jit_frag_func jit_function, + boolean opaque ) { LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function); /* FIXME: reference count */ setup->fs.current.jit_function = jit_function; + setup->fs.current.opaque = opaque; setup->dirty |= LP_SETUP_NEW_FS; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index bf12cb8527..bac7d73e8d 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -97,7 +97,8 @@ lp_setup_set_fs_inputs( struct setup_context *setup, void lp_setup_set_fs_function( struct setup_context *setup, - lp_jit_frag_func jit_function ); + lp_jit_frag_func jit_function, + boolean opaque ); void lp_setup_set_fs_constants(struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 575265b0f5..0f5b25b725 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -459,6 +459,12 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ + if(setup->fs.current.opaque) { + lp_scene_bin_reset( scene, x, y ); + lp_scene_bin_command( scene, x, y, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); + } lp_scene_bin_command( scene, x, y, lp_rast_shade_tile, lp_rast_arg_inputs(&tri->inputs) ); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index c6f5801876..1ed9a2f5bf 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1005,6 +1005,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant; + boolean opaque; make_variant_key(lp, shader, &key); @@ -1021,6 +1022,15 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) shader->current = variant; + /* TODO: put this in the variant */ + opaque = !key.blend.logicop_enable && + !key.blend.blend_enable && + !key.alpha.enabled && + !key.depth.enabled && + !shader->info.uses_kill + ? TRUE : FALSE; + lp_setup_set_fs_function(lp->setup, - shader->current->jit_function); + shader->current->jit_function, + opaque); } -- cgit v1.2.3 From a27b12171d84c6e731af08f48a657c377f8549ba Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 13:54:46 -0700 Subject: llvmpipe: add scene texture referencing code --- src/gallium/drivers/llvmpipe/lp_setup.c | 29 +++++++++++++++++++++-------- src/gallium/drivers/llvmpipe/lp_setup.h | 2 +- 2 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 61b968c49f..bac2db92ba 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -432,25 +432,22 @@ lp_setup_set_vertex_info( struct setup_context *setup, } +/** + * Called during state validation when LP_NEW_TEXTURE is set. + */ void lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture) { - struct pipe_texture *dummy; unsigned i; LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - assert(num <= PIPE_MAX_SAMPLERS); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_texture *tex = i < num ? texture[i] : NULL; - /* FIXME: hold on to the reference */ - dummy = NULL; - pipe_texture_reference(&dummy, tex); - if(tex) { struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); struct lp_jit_texture *jit_tex; @@ -463,21 +460,37 @@ lp_setup_set_sampler_textures( struct setup_context *setup, else /* FIXME: map the rendertarget */ assert(0); + + /* the scene references this texture */ + { + struct lp_scene *scene = lp_setup_get_current_scene(setup); + lp_scene_texture_reference(scene, tex); + } } } setup->dirty |= LP_SETUP_NEW_FS; } + +/** + * Is the given texture referenced in the setup module's current scene? + */ boolean -lp_setup_is_texture_referenced( struct setup_context *setup, +lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ) { - /* FIXME */ + const struct lp_scene *scene = setup->scene; + if (scene && lp_scene_is_textured_referenced(scene, texture)) { + return PIPE_REFERENCED_FOR_READ; + } return PIPE_UNREFERENCED; } +/** + * Called by vbuf code when we're about to draw something. + */ void lp_setup_update_state( struct setup_context *setup ) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index bac7d73e8d..429abeba43 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -118,7 +118,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture); boolean -lp_setup_is_texture_referenced( struct setup_context *setup, +lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ); void -- cgit v1.2.3 From d59fe448967addb3025d7df90888ff950e03a343 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 14:51:26 -0700 Subject: llvmpipe: check for texture usage in all scenes --- src/gallium/drivers/llvmpipe/lp_setup.c | 20 ++++++++++---------- src/gallium/drivers/llvmpipe/lp_setup_context.h | 6 ++++++ 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index bac2db92ba..8193b107d9 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -50,10 +50,6 @@ #include "draw/draw_vbuf.h" -/** XXX temporary value, temporary here */ -#define MAX_SCENES 2 - - static void set_scene_state( struct setup_context *, unsigned ); @@ -474,15 +470,19 @@ lp_setup_set_sampler_textures( struct setup_context *setup, /** - * Is the given texture referenced in the setup module's current scene? + * Is the given texture referenced by any scene? + * Note: we have to check all scenes including any scenes currently + * being rendered and the current scene being built. */ boolean lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ) { - const struct lp_scene *scene = setup->scene; - if (scene && lp_scene_is_textured_referenced(scene, texture)) { - return PIPE_REFERENCED_FOR_READ; + unsigned i; + for (i = 0; i < Elements(setup->scenes); i++) { + if (lp_scene_is_textured_referenced(setup->scenes[i], texture)) { + return PIPE_REFERENCED_FOR_READ; + } } return PIPE_UNREFERENCED; } @@ -645,8 +645,8 @@ lp_setup_create( struct pipe_screen *screen, /* create some empty scenes */ for (i = 0; i < MAX_SCENES; i++) { - struct lp_scene *scene = lp_scene_create(); - lp_scene_enqueue(setup->empty_scenes, scene); + setup->scenes[i] = lp_scene_create(); + lp_scene_enqueue(setup->empty_scenes, setup->scenes[i]); } setup->triangle = first_triangle; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 66654ec5e7..e6f6f0e0bb 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -50,6 +50,11 @@ struct lp_scene_queue; +/** Max number of scenes */ +#define MAX_SCENES 2 + + + /** * Point/line/triangle setup context. * Note: "stored" below indicates data which is stored in the bins, @@ -75,6 +80,7 @@ struct setup_context */ struct draw_stage *vbuf; struct lp_rasterizer *rast; + struct lp_scene *scenes[MAX_SCENES]; /**< all the scenes */ struct lp_scene *scene; /**< current scene being built */ struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */ -- cgit v1.2.3 From db58192cfb63cbb7b1d84e7ae7429799ce888164 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 15:01:35 -0700 Subject: llvmpipe: re-get scene pointer after flushing --- src/gallium/drivers/llvmpipe/lp_setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 8193b107d9..4f77d04ca5 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -249,6 +249,9 @@ lp_setup_bind_framebuffer( struct setup_context *setup, set_scene_state( setup, SETUP_FLUSHED ); + /* re-get scene pointer, may have a new scene after flushing */ + scene = lp_setup_get_current_scene(setup); + util_copy_framebuffer_state(&setup->fb, fb); lp_scene_set_framebuffer_size(scene, setup->fb.width, setup->fb.height); -- cgit v1.2.3 From 0b279c5382da021a71cdc8ed3afa09983817539c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 15:03:42 -0700 Subject: llvmpipe: indentation fixes --- src/gallium/drivers/llvmpipe/lp_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 4f77d04ca5..11b1b5f319 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -292,13 +292,13 @@ lp_setup_clear( struct setup_context *setup, */ if (flags & PIPE_CLEAR_COLOR) lp_scene_bin_everywhere( scene, - lp_rast_clear_color, - setup->clear.color ); + lp_rast_clear_color, + setup->clear.color ); if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) lp_scene_bin_everywhere( scene, - lp_rast_clear_zstencil, - setup->clear.zstencil ); + lp_rast_clear_zstencil, + setup->clear.zstencil ); } else { /* Put ourselves into the 'pre-clear' state, specifically to try -- cgit v1.2.3 From 12872774461a84f0a7c272aff5aac5e30a78a7c2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 15:30:42 -0700 Subject: llvmpipe: also check render target textures in lp_setup_is_texture_referenced() --- src/gallium/drivers/llvmpipe/lp_setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 11b1b5f319..ce006bf618 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -487,6 +487,15 @@ lp_setup_is_texture_referenced( const struct setup_context *setup, return PIPE_REFERENCED_FOR_READ; } } + + /* check the render targets */ + for (i = 0; i < setup->fb.nr_cbufs; i++) { + if (setup->fb.cbufs[i]->texture == texture) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + } + if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + return PIPE_UNREFERENCED; } -- cgit v1.2.3 From 018b78ad649e88cc6d8b6b10aef1502075508515 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 15:32:55 -0700 Subject: llvmpipe: check render targets before other textures --- src/gallium/drivers/llvmpipe/lp_setup.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ce006bf618..649e97992b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -482,19 +482,22 @@ lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ) { unsigned i; - for (i = 0; i < Elements(setup->scenes); i++) { - if (lp_scene_is_textured_referenced(setup->scenes[i], texture)) { - return PIPE_REFERENCED_FOR_READ; - } - } /* check the render targets */ for (i = 0; i < setup->fb.nr_cbufs; i++) { if (setup->fb.cbufs[i]->texture == texture) return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; } - if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) + if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) { return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + } + + /* check textures referenced by the scene */ + for (i = 0; i < Elements(setup->scenes); i++) { + if (lp_scene_is_textured_referenced(setup->scenes[i], texture)) { + return PIPE_REFERENCED_FOR_READ; + } + } return PIPE_UNREFERENCED; } -- cgit v1.2.3 From 4461442849bfdb817334b38567136f7f9dabdf59 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 14 Jan 2010 19:15:00 -0700 Subject: llvmpipe: implement scissor testing The scissor test is implemented as another per-quad operation in the JIT code. The four scissor box params are passed via the lp_jit_context. In the JIT code we compare the quad's x/y coords against the clip bounds and create a new in/out mask that's AND'd with the main quad mask. Note: we should also do scissor testing in the triangle setup code to improve efficiency. That's not done yet. --- src/gallium/drivers/llvmpipe/lp_jit.c | 21 +++++++--- src/gallium/drivers/llvmpipe/lp_jit.h | 19 ++++++++- src/gallium/drivers/llvmpipe/lp_setup.c | 34 ++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup.h | 4 ++ src/gallium/drivers/llvmpipe/lp_setup_context.h | 6 +++ src/gallium/drivers/llvmpipe/lp_state.h | 1 + src/gallium/drivers/llvmpipe/lp_state_derived.c | 4 ++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 52 +++++++++++++++++++++++++ 8 files changed, 134 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 4ef0783f3e..429cb973c2 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -79,13 +79,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) /* struct lp_jit_context */ { - LLVMTypeRef elem_types[4]; + LLVMTypeRef elem_types[8]; LLVMTypeRef context_type; elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */ - elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ - elem_types[2] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */ - elem_types[3] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ + elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ elem_types[2] = LLVMFloatType(); /* scissor_xmin */ + elem_types[3] = LLVMFloatType(); /* scissor_ymin */ + elem_types[4] = LLVMFloatType(); /* scissor_xmax */ + elem_types[5] = LLVMFloatType(); /* scissor_ymax */ + elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */ + elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ context_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -93,8 +96,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) screen->target, context_type, 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, screen->target, context_type, 1); - LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin, screen->target, context_type, 2); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin, + screen->target, context_type, 3); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax, + screen->target, context_type, 4); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax, + screen->target, context_type, 5); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, + screen->target, context_type, 6); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures, screen->target, context_type, LP_JIT_CONTEXT_TEXTURES_INDEX); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 3b316914b0..9cbe1bd3b1 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -79,6 +79,9 @@ struct lp_jit_context float alpha_ref_value; + /** floats, not ints */ + float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax; + /* FIXME: store (also?) in floats */ uint8_t *blend_color; @@ -92,10 +95,22 @@ struct lp_jit_context #define lp_jit_context_alpha_ref_value(_builder, _ptr) \ lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value") +#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin") + +#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin") + +#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax") + +#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax") + #define lp_jit_context_blend_color(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 2, "blend_color") + lp_build_struct_get(_builder, _ptr, 6, "blend_color") -#define LP_JIT_CONTEXT_TEXTURES_INDEX 3 +#define LP_JIT_CONTEXT_TEXTURES_INDEX 7 #define lp_jit_context_textures(_builder, _ptr) \ lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures") diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 649e97992b..284337e825 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -413,6 +413,21 @@ lp_setup_set_blend_color( struct setup_context *setup, } +void +lp_setup_set_scissor( struct setup_context *setup, + const struct pipe_scissor_state *scissor ) +{ + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + + assert(scissor); + + if (memcmp(&setup->scissor.current, scissor, sizeof(*scissor)) != 0) { + setup->scissor.current = *scissor; /* struct copy */ + setup->dirty |= LP_SETUP_NEW_SCISSOR; + } +} + + void lp_setup_set_flatshade_first( struct setup_context *setup, boolean flatshade_first ) @@ -534,6 +549,25 @@ lp_setup_update_state( struct setup_context *setup ) setup->dirty |= LP_SETUP_NEW_FS; } + if (setup->dirty & LP_SETUP_NEW_SCISSOR) { + float *stored; + + stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16); + + stored[0] = (float) setup->scissor.current.minx; + stored[1] = (float) setup->scissor.current.miny; + stored[2] = (float) setup->scissor.current.maxx; + stored[3] = (float) setup->scissor.current.maxy; + + setup->scissor.stored = stored; + + setup->fs.current.jit_context.scissor_xmin = stored[0]; + setup->fs.current.jit_context.scissor_ymin = stored[1]; + setup->fs.current.jit_context.scissor_xmax = stored[2]; + setup->fs.current.jit_context.scissor_ymax = stored[3]; + + setup->dirty |= LP_SETUP_NEW_FS; + } if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { struct pipe_buffer *buffer = setup->constants.current; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 429abeba43..c7ef3d394a 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -113,6 +113,10 @@ void lp_setup_set_blend_color( struct setup_context *setup, const struct pipe_blend_color *blend_color ); +void +lp_setup_set_scissor( struct setup_context *setup, + const struct pipe_scissor_state *scissor ); + void lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index e6f6f0e0bb..fc0aef1376 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -45,6 +45,7 @@ #define LP_SETUP_NEW_FS 0x01 #define LP_SETUP_NEW_CONSTANTS 0x02 #define LP_SETUP_NEW_BLEND_COLOR 0x04 +#define LP_SETUP_NEW_SCISSOR 0x08 struct lp_scene_queue; @@ -122,6 +123,11 @@ struct setup_context uint8_t *stored; } blend_color; + struct { + struct pipe_scissor_state current; + const void *stored; + } scissor; + unsigned dirty; /**< bitmask of LP_SETUP_NEW_x bits */ void (*point)( struct setup_context *, diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 4c6747bb2b..ddb152c074 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -72,6 +72,7 @@ struct lp_fragment_shader_variant_key enum pipe_format zsbuf_format; unsigned nr_cbufs:8; unsigned flatshade:1; + unsigned scissor:1; struct { ubyte colormask; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 2c349fdb1d..28af477914 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -160,6 +160,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_BLEND | + LP_NEW_SCISSOR | LP_NEW_DEPTH_STENCIL_ALPHA | LP_NEW_RASTERIZER | LP_NEW_SAMPLER | @@ -170,6 +171,9 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color); + if (llvmpipe->dirty & LP_NEW_SCISSOR) + lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); + if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 26a2d6cc23..d12d3f6091 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -304,6 +304,51 @@ generate_tri_edge_mask(LLVMBuilderRef builder, } +static LLVMValueRef +generate_scissor_test(LLVMBuilderRef builder, + LLVMValueRef context_ptr, + const struct lp_build_interp_soa_context *interp, + struct lp_type type) +{ + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef xpos = interp->pos[0], ypos = interp->pos[1]; + LLVMValueRef xmin, ymin, xmax, ymax; + LLVMValueRef m0, m1, m2, m3, m; + + /* xpos, ypos contain the window coords for the four pixels in the quad */ + assert(xpos); + assert(ypos); + + /* get the current scissor bounds, convert to vectors */ + xmin = lp_jit_context_scissor_xmin_value(builder, context_ptr); + xmin = lp_build_broadcast(builder, vec_type, xmin); + + ymin = lp_jit_context_scissor_ymin_value(builder, context_ptr); + ymin = lp_build_broadcast(builder, vec_type, ymin); + + xmax = lp_jit_context_scissor_xmax_value(builder, context_ptr); + xmax = lp_build_broadcast(builder, vec_type, xmax); + + ymax = lp_jit_context_scissor_ymax_value(builder, context_ptr); + ymax = lp_build_broadcast(builder, vec_type, ymax); + + /* compare the fragment's position coordinates against the scissor bounds */ + m0 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, xpos, xmin); + m1 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, ypos, ymin); + m2 = lp_build_compare(builder, type, PIPE_FUNC_LESS, xpos, xmax); + m3 = lp_build_compare(builder, type, PIPE_FUNC_LESS, ypos, ymax); + + /* AND all the masks together */ + m = LLVMBuildAnd(builder, m0, m1, ""); + m = LLVMBuildAnd(builder, m, m2, ""); + m = LLVMBuildAnd(builder, m, m3, ""); + + lp_build_name(m, "scissormask"); + + return m; +} + + /** * Generate the fragment shader, depth/stencil test, and alpha tests. * \param i which quad in the tile, in range [0,3] @@ -372,6 +417,11 @@ generate_fs(struct llvmpipe_context *lp, /* 'mask' will control execution based on quad's pixel alive/killed state */ lp_build_mask_begin(&mask, flow, type, *pmask); + if (key->scissor) { + LLVMValueRef smask = + generate_scissor_test(builder, context_ptr, interp, type); + lp_build_mask_update(&mask, smask); + } early_depth_test = key->depth.enabled && @@ -968,6 +1018,7 @@ make_variant_key(struct llvmpipe_context *lp, /* alpha.ref_value is passed in jit_context */ key->flatshade = lp->rasterizer->flatshade; + key->scissor = lp->rasterizer->scissor; if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); @@ -1033,6 +1084,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) key.blend.colormask == 0xf && !key.alpha.enabled && !key.depth.enabled && + !key.scissor && !shader->info.uses_kill ? TRUE : FALSE; -- cgit v1.2.3 From 2797f2bf57562c95a601a67edca3089641215cc4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 15 Jan 2010 11:21:16 -0700 Subject: llvmpipe: generate two shader varients, one omits triangle in/out testing When we know that a 4x4 pixel block is entirely inside of a triangle use the jit function which omits the in/out test code. Results in a few percent speedup in many tests. --- src/gallium/drivers/llvmpipe/lp_rast.c | 52 +++++++++++++++---------- src/gallium/drivers/llvmpipe/lp_rast.h | 6 ++- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 43 +++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast_tri.c | 11 ++---- src/gallium/drivers/llvmpipe/lp_setup.c | 12 +++--- src/gallium/drivers/llvmpipe/lp_setup.h | 7 ++-- src/gallium/drivers/llvmpipe/lp_state.h | 4 +- src/gallium/drivers/llvmpipe/lp_state_fs.c | 59 ++++++++++++++++++++++------- 8 files changed, 142 insertions(+), 52 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 75562bf62d..d03ba1752d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -344,9 +344,6 @@ void lp_rast_set_state( struct lp_rasterizer *rast, -/* Within a tile: - */ - /** * Run the shader on all blocks in a tile. This is used when a tile is * completely contained inside a triangle. @@ -356,8 +353,8 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg ) { - /* Set c1,c2,c3 to large values so the in/out test always passes */ - const int32_t c1 = INT_MIN, c2 = INT_MIN, c3 = INT_MIN; + const struct lp_rast_state *state = rast->tasks[thread_index].current_state; + struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const unsigned tile_x = rast->tasks[thread_index].x; const unsigned tile_y = rast->tasks[thread_index].y; @@ -365,16 +362,35 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); - /* Use the existing preference for 4x4 (four quads) shading: - */ - for (y = 0; y < TILE_SIZE; y += 4) - for (x = 0; x < TILE_SIZE; x += 4) - lp_rast_shade_quads( rast, - thread_index, - inputs, - tile_x + x, - tile_y + y, - c1, c2, c3); + /* render the whole 64x64 tile in 4x4 chunks */ + for (y = 0; y < TILE_SIZE; y += 4){ + for (x = 0; x < TILE_SIZE; x += 4) { + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + uint32_t *depth; + unsigned block_offset, i; + + /* offset of the 16x16 pixel block within the tile */ + block_offset = ((y / 4) * (16 * 16) + (x / 4) * 16); + + /* color buffer */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; + + /* depth buffer */ + depth = tile->depth + block_offset; + + /* run shader */ + state->jit_function[0]( &state->jit_context, + tile_x + x, tile_y + y, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); + } + } } @@ -411,7 +427,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, iy = y % TILE_SIZE; /* offset of the 16x16 pixel block within the tile */ - block_offset = ((iy/4)*(16*16) + (ix/4)*16); + block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16); /* color buffer */ for (i = 0; i < rast->state.fb.nr_cbufs; i++) @@ -433,7 +449,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, #endif /* run shader */ - state->jit_function( &state->jit_context, + state->jit_function[1]( &state->jit_context, x, y, inputs->a0, inputs->dadx, @@ -445,8 +461,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, } -/* End of tile: - */ /** diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index d926adb6b2..2a97fe4c67 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -66,8 +66,10 @@ struct lp_rast_state { /* The shader itself. Probably we also need to pass a pointer to * the tile color/z/stencil data somehow: - */ - lp_jit_frag_func jit_function; + * jit_function[0] skips the triangle in/out test code + * jit_function[1] does triangle in/out testing + */ + lp_jit_frag_func jit_function[2]; boolean opaque; }; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 5afdeab049..607968e345 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -30,6 +30,7 @@ #include "pipe/p_thread.h" #include "lp_rast.h" +#include "lp_tile_soa.h" #define MAX_THREADS 8 /* XXX probably temporary here */ @@ -126,4 +127,46 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned x, unsigned y, int32_t c1, int32_t c2, int32_t c3); + +/** + * Shade all pixels in a 4x4 block. The fragment code omits the + * triangle in/out tests. + * \param x, y location of 4x4 block in window coords + */ +static INLINE void +lp_rast_shade_quads_all( struct lp_rasterizer *rast, + unsigned thread_index, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y ) +{ + const struct lp_rast_state *state = rast->tasks[thread_index].current_state; + struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; + const unsigned ix = x % TILE_SIZE, iy = y % TILE_SIZE; + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + void *depth; + unsigned block_offset, i; + + /* offset of the containing 16x16 pixel block within the tile */ + block_offset = (iy / 4) * (16 * 16) + (ix / 4) * 16; + + /* color buffer */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; + + /* depth buffer */ + depth = tile->depth + block_offset; + + /* run shader */ + state->jit_function[0]( &state->jit_context, + x, y, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); +} + + #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index bc7397f50c..9c3f699ec7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -89,13 +89,10 @@ block_full_4( struct lp_rasterizer_task *rast_task, const struct lp_rast_triangle *tri, int x, int y ) { - /* Set c1,c2,c3 to large values so the in/out test always passes */ - const int32_t c1 = INT_MIN, c2 = INT_MIN, c3 = INT_MIN; - lp_rast_shade_quads(rast_task->rast, - rast_task->thread_index, - &tri->inputs, - x, y, - c1, c2, c3); + lp_rast_shade_quads_all(rast_task->rast, + rast_task->thread_index, + &tri->inputs, + x, y); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 284337e825..355c051837 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -362,14 +362,16 @@ lp_setup_set_fs_inputs( struct setup_context *setup, } void -lp_setup_set_fs_function( struct setup_context *setup, - lp_jit_frag_func jit_function, - boolean opaque ) +lp_setup_set_fs_functions( struct setup_context *setup, + lp_jit_frag_func jit_function0, + lp_jit_frag_func jit_function1, + boolean opaque ) { - LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function); + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function0); /* FIXME: reference count */ - setup->fs.current.jit_function = jit_function; + setup->fs.current.jit_function[0] = jit_function0; + setup->fs.current.jit_function[1] = jit_function1; setup->fs.current.opaque = opaque; setup->dirty |= LP_SETUP_NEW_FS; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index c7ef3d394a..407f752777 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -96,9 +96,10 @@ lp_setup_set_fs_inputs( struct setup_context *setup, unsigned nr ); void -lp_setup_set_fs_function( struct setup_context *setup, - lp_jit_frag_func jit_function, - boolean opaque ); +lp_setup_set_fs_functions( struct setup_context *setup, + lp_jit_frag_func jit_function0, + lp_jit_frag_func jit_function1, + boolean opaque ); void lp_setup_set_fs_constants(struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index ddb152c074..224b6e523c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -88,9 +88,9 @@ struct lp_fragment_shader_variant struct lp_fragment_shader_variant_key key; - LLVMValueRef function; + LLVMValueRef function[2]; - lp_jit_frag_func jit_function; + lp_jit_frag_func jit_function[2]; struct lp_fragment_shader_variant *next; }; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index f15fca293b..a8f4a4ed46 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -349,9 +349,26 @@ generate_scissor_test(LLVMBuilderRef builder, } +static LLVMValueRef +build_int32_vec_const(int value) +{ + struct lp_type i32_type; + + memset(&i32_type, 0, sizeof i32_type); + i32_type.floating = FALSE; /* values are integers */ + i32_type.sign = TRUE; /* values are signed */ + i32_type.norm = FALSE; /* values are not normalized */ + i32_type.width = 32; /* 32-bit int values */ + i32_type.length = 4; /* 4 elements per vector */ + return lp_build_int_const_scalar(i32_type, value); +} + + + /** * Generate the fragment shader, depth/stencil test, and alpha tests. * \param i which quad in the tile, in range [0,3] + * \param do_tri_test if 1, do triangle edge in/out testing */ static void generate_fs(struct llvmpipe_context *lp, @@ -366,6 +383,7 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef *pmask, LLVMValueRef (*color)[4], LLVMValueRef depth_ptr, + unsigned do_tri_test, LLVMValueRef c0, LLVMValueRef c1, LLVMValueRef c2, @@ -411,8 +429,13 @@ generate_fs(struct llvmpipe_context *lp, lp_build_flow_scope_declare(flow, &z); /* do triangle edge testing */ - generate_tri_edge_mask(builder, i, pmask, - c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); + if (do_tri_test) { + generate_tri_edge_mask(builder, i, pmask, + c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); + } + else { + *pmask = build_int32_vec_const(~0); + } /* 'mask' will control execution based on quad's pixel alive/killed state */ lp_build_mask_begin(&mask, flow, type, *pmask); @@ -563,7 +586,8 @@ generate_blend(const struct pipe_blend_state *blend, static void generate_fragment(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, - struct lp_fragment_shader_variant *variant) + struct lp_fragment_shader_variant *variant, + unsigned do_tri_test) { struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen); const struct lp_fragment_shader_variant_key *key = &variant->key; @@ -656,7 +680,7 @@ generate_fragment(struct llvmpipe_context *lp, function = LLVMAddFunction(screen->module, "shader", func_type); LLVMSetFunctionCallConv(function, LLVMCCallConv); - variant->function = function; + variant->function[do_tri_test] = function; /* XXX: need to propagate noalias down into color param now we are @@ -738,6 +762,7 @@ generate_fragment(struct llvmpipe_context *lp, &fs_mask[i], /* output */ out_color, depth_ptr_i, + do_tri_test, c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); @@ -812,10 +837,10 @@ generate_fragment(struct llvmpipe_context *lp, /* * Translate the LLVM IR into machine code. */ - variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function); + variant->jit_function[do_tri_test] = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function); if (LP_DEBUG & DEBUG_ASM) - lp_disassemble(variant->jit_function); + lp_disassemble(variant->jit_function[do_tri_test]); } @@ -887,7 +912,8 @@ generate_variant(struct llvmpipe_context *lp, variant->shader = shader; memcpy(&variant->key, key, sizeof *key); - generate_fragment(lp, shader, variant); + generate_fragment(lp, shader, variant, 0); + generate_fragment(lp, shader, variant, 1); /* insert new variant into linked list */ variant->next = shader->variants; @@ -947,11 +973,15 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) variant = shader->variants; while(variant) { struct lp_fragment_shader_variant *next = variant->next; + unsigned i; - if(variant->function) { - if(variant->jit_function) - LLVMFreeMachineCodeForFunction(screen->engine, variant->function); - LLVMDeleteFunction(variant->function); + for (i = 0; i < Elements(variant->function); i++) { + if (variant->function[i]) { + if (variant->jit_function[i]) + LLVMFreeMachineCodeForFunction(screen->engine, + variant->function[i]); + LLVMDeleteFunction(variant->function[i]); + } } FREE(variant); @@ -1093,7 +1123,8 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) !shader->info.uses_kill ? TRUE : FALSE; - lp_setup_set_fs_function(lp->setup, - shader->current->jit_function, - opaque); + lp_setup_set_fs_functions(lp->setup, + shader->current->jit_function[0], + shader->current->jit_function[1], + opaque); } -- cgit v1.2.3 From fdfe06ad804ea13e6e436d66c1bcafe0bde2f545 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 15 Jan 2010 12:06:00 -0700 Subject: llvmpipe: implement scissor test in triangle setup --- src/gallium/drivers/llvmpipe/lp_setup.c | 4 +++- src/gallium/drivers/llvmpipe/lp_setup.h | 3 ++- src/gallium/drivers/llvmpipe/lp_setup_context.h | 1 + src/gallium/drivers/llvmpipe/lp_setup_tri.c | 7 +++++++ src/gallium/drivers/llvmpipe/lp_state_rasterizer.c | 3 ++- 5 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 355c051837..f52dce65d7 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -339,13 +339,15 @@ lp_setup_fence( struct setup_context *setup ) void lp_setup_set_triangle_state( struct setup_context *setup, unsigned cull_mode, - boolean ccw_is_frontface) + boolean ccw_is_frontface, + boolean scissor ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); setup->ccw_is_frontface = ccw_is_frontface; setup->cullmode = cull_mode; setup->triangle = first_triangle; + setup->scissor_test = scissor; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 407f752777..5081da29d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -88,7 +88,8 @@ lp_setup_bind_framebuffer( struct setup_context *setup, void lp_setup_set_triangle_state( struct setup_context *setup, unsigned cullmode, - boolean front_is_ccw ); + boolean front_is_ccw, + boolean scissor ); void lp_setup_set_fs_inputs( struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index fc0aef1376..a5fc34e54a 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -87,6 +87,7 @@ struct setup_context boolean flatshade_first; boolean ccw_is_frontface; + boolean scissor_test; unsigned cullmode; struct pipe_framebuffer_state fb; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index ae354b3870..018d254c76 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -293,6 +293,13 @@ do_triangle_ccw(struct setup_context *setup, miny = (MIN3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER; maxy = (MAX3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER; + if (setup->scissor_test) { + minx = MAX2(minx, setup->scissor.current.minx); + maxx = MIN2(maxx, setup->scissor.current.maxx); + miny = MAX2(miny, setup->scissor.current.miny); + maxy = MIN2(maxy, setup->scissor.current.maxy); + } + if (miny == maxy || minx == maxx) { lp_scene_putback_data( scene, sizeof *tri ); diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index 7d4c310aae..feb012816c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -61,7 +61,8 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, if (llvmpipe->rasterizer) { lp_setup_set_triangle_state( llvmpipe->setup, llvmpipe->rasterizer->cull_mode, - llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW ); + llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, + llvmpipe->rasterizer->scissor); } llvmpipe->dirty |= LP_NEW_RASTERIZER; -- cgit v1.2.3 From 591401ff05f878ff1607a1a34db1319103025d8f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 16 Jan 2010 21:12:10 +0000 Subject: llvmpipe: use new u_ringbuffer for scene queue --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- src/gallium/drivers/llvmpipe/lp_scene_queue.c | 114 ++++++++------------------ src/gallium/drivers/llvmpipe/lp_scene_queue.h | 8 +- src/gallium/drivers/llvmpipe/lp_setup.c | 11 ++- 4 files changed, 46 insertions(+), 89 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d03ba1752d..2e2ebee45d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -844,7 +844,7 @@ thread_func( void *init_data ) const struct pipe_framebuffer_state *fb; boolean write_depth; - rast->curr_scene = lp_scene_dequeue( rast->full_scenes ); + rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE ); lp_scene_bin_iter_begin( rast->curr_scene ); diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c index 8d65a6a6fa..43d74e4d89 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -32,8 +32,7 @@ * which are produced by the "rast" code when it finishes rendering a scene. */ - -#include "pipe/p_thread.h" +#include "util/u_ringbuffer.h" #include "util/u_memory.h" #include "lp_scene_queue.h" @@ -41,20 +40,17 @@ #define MAX_SCENE_QUEUE 4 +struct scene_packet { + struct util_packet header; + struct lp_scene *scene; +}; /** * A queue of scenes */ struct lp_scene_queue { - /** XXX might use a linked list here somedone, but the list will - * probably always be pretty short. - */ - struct lp_scene *scenes[MAX_SCENE_QUEUE]; - unsigned count; - - pipe_condvar count_change; - pipe_mutex mutex; + struct util_ringbuffer *ring; }; @@ -64,11 +60,19 @@ struct lp_scene_queue * lp_scene_queue_create(void) { struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue); - if (queue) { - pipe_condvar_init(queue->count_change); - pipe_mutex_init(queue->mutex); - } + if (queue == NULL) + return NULL; + + queue->ring = util_ringbuffer_create( MAX_SCENE_QUEUE * + sizeof( struct scene_packet ) / 4); + if (queue->ring == NULL) + goto fail; + return queue; + +fail: + FREE(queue); + return NULL; } @@ -76,41 +80,26 @@ lp_scene_queue_create(void) void lp_scene_queue_destroy(struct lp_scene_queue *queue) { - pipe_condvar_destroy(queue->count_change); - pipe_mutex_destroy(queue->mutex); + util_ringbuffer_destroy(queue->ring); + FREE(queue); } /** Remove first lp_scene from head of queue */ struct lp_scene * -lp_scene_dequeue(struct lp_scene_queue *queue) +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait) { - struct lp_scene *scene; - unsigned i; - - pipe_mutex_lock(queue->mutex); - while (queue->count == 0) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - - assert(queue->count >= 1); - - /* get head */ - scene = queue->scenes[0]; - - /* shift entries */ - for (i = 0; i < queue->count - 1; i++) { - queue->scenes[i] = queue->scenes[i + 1]; - } + struct scene_packet packet; + enum pipe_error ret; - queue->count--; + ret = util_ringbuffer_dequeue(queue->ring, + &packet.header, + sizeof packet / 4, + wait ); + if (ret != PIPE_OK) + return NULL; - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); - - return scene; + return packet.scene; } @@ -118,47 +107,16 @@ lp_scene_dequeue(struct lp_scene_queue *queue) void lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene) { - pipe_mutex_lock(queue->mutex); - - assert(queue->count < MAX_SCENE_QUEUE); + struct scene_packet packet; - /* debug: check that scene is not already in the queue */ - if (0) { - unsigned i; - for (i = 0; i < queue->count; i++) { - assert(queue->scenes[i] != scene); - } - } + packet.header.dwords = sizeof packet / 4; + packet.header.data24 = 0; + packet.scene = scene; - /* add to end */ - queue->scenes[queue->count++] = scene; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); + util_ringbuffer_enqueue(queue->ring, &packet.header); } -/** Return number of entries in the queue */ -unsigned -lp_scene_queue_count(struct lp_scene_queue *queue) -{ - unsigned count; - pipe_mutex_lock(queue->mutex); - count = queue->count; - pipe_mutex_unlock(queue->mutex); - return count; -} -/** Wait until the queue has exactly 'count' entries */ -void -lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned count) -{ - pipe_mutex_lock(queue->mutex); - while (queue->count != count) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - pipe_mutex_unlock(queue->mutex); -} + diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h index 1bd475fa50..fd7c65a2c8 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene_queue.h +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h @@ -40,16 +40,12 @@ void lp_scene_queue_destroy(struct lp_scene_queue *queue); struct lp_scene * -lp_scene_dequeue(struct lp_scene_queue *queue); +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait); void -lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *bins); +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene); -unsigned -lp_scene_queue_count(struct lp_scene_queue *queue); -void -lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned size); #endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index f52dce65d7..d4a4724ad1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -57,8 +57,11 @@ struct lp_scene * lp_setup_get_current_scene(struct setup_context *setup) { if (!setup->scene) { - /* wait for a free/empty bin */ - setup->scene = lp_scene_dequeue(setup->empty_scenes); + + /* wait for a free/empty scene + */ + setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE); + if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ lp_scene_set_framebuffer_size(setup->scene, @@ -651,8 +654,8 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ - while (lp_scene_queue_count(setup->empty_scenes) > 0) { - struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes); + while (1) { + struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE); if (!scene) break; lp_scene_destroy(scene); -- cgit v1.2.3 From cd9d9e2436a0815f6ed3a61d2cdf8fad53278506 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 21 Jan 2010 14:59:01 -0700 Subject: llvmpipe: added simple perf/statistics counting facility Currently counting number of tris, how many tiles of each size are fully covered, partially covered or empty, etc. Set LP_DEBUG=counters to enable. Results are printed upon context destruction. --- src/gallium/drivers/llvmpipe/Makefile | 1 + src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_context.c | 5 ++ src/gallium/drivers/llvmpipe/lp_debug.h | 1 + src/gallium/drivers/llvmpipe/lp_perf.c | 86 +++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_perf.h | 74 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast_tri.c | 6 ++ src/gallium/drivers/llvmpipe/lp_screen.c | 1 + src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- src/gallium/drivers/llvmpipe/lp_setup.h | 2 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 16 ++++-- 11 files changed, 189 insertions(+), 6 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_perf.c create mode 100644 src/gallium/drivers/llvmpipe/lp_perf.h (limited to 'src/gallium/drivers/llvmpipe/lp_setup.c') diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 666aa7293e..899af6acf8 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -36,6 +36,7 @@ C_SOURCES = \ lp_fence.c \ lp_flush.c \ lp_jit.c \ + lp_perf.c \ lp_query.c \ lp_rast.c \ lp_rast_tri.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index c4e7a4a22f..d7a396292c 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -52,6 +52,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_fence.c', 'lp_flush.c', 'lp_jit.c', + 'lp_perf.c', 'lp_query.c', 'lp_rast.c', 'lp_rast_tri.c', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index c5b00f8e23..51de6f93ca 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -38,6 +38,7 @@ #include "lp_clear.h" #include "lp_context.h" #include "lp_flush.h" +#include "lp_perf.h" #include "lp_state.h" #include "lp_surface.h" #include "lp_texture.h" @@ -54,6 +55,8 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); uint i; + lp_print_counters(); + /* This will also destroy llvmpipe->setup: */ if (llvmpipe->draw) @@ -195,6 +198,8 @@ llvmpipe_create( struct pipe_screen *screen ) lp_init_surface_functions(llvmpipe); + lp_reset_counters(); + return &llvmpipe->pipe; fail: diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h index 7128e8eb4b..7e04bd471e 100644 --- a/src/gallium/drivers/llvmpipe/lp_debug.h +++ b/src/gallium/drivers/llvmpipe/lp_debug.h @@ -47,6 +47,7 @@ st_print_current(void); #define DEBUG_JIT 0x100 #define DEBUG_SHOW_TILES 0x200 #define DEBUG_SHOW_SUBTILES 0x400 +#define DEBUG_COUNTERS 0x800 #ifdef DEBUG diff --git a/src/gallium/drivers/llvmpipe/lp_perf.c b/src/gallium/drivers/llvmpipe/lp_perf.c new file mode 100644 index 0000000000..2628d51069 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.c @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_debug.h" +#include "lp_debug.h" +#include "lp_perf.h" + + + +struct lp_counters lp_count; + + +void +lp_reset_counters(void) +{ + memset(&lp_count, 0, sizeof(lp_count)); +} + + +void +lp_print_counters(void) +{ + if (LP_DEBUG & DEBUG_COUNTERS) { + unsigned total_64, total_16, total_4; + float p1, p2, p3; + + debug_printf("llvmpipe: nr_triangles: %9u\n", lp_count.nr_tris); + debug_printf("llvmpipe: nr_culled_triangles: %9u\n", lp_count.nr_culled_tris); + + total_64 = (lp_count.nr_empty_64 + + lp_count.nr_fully_covered_64 + + lp_count.nr_partially_covered_64); + + p1 = 100.0 * (float) lp_count.nr_empty_64 / (float) total_64; + p2 = 100.0 * (float) lp_count.nr_fully_covered_64 / (float) total_64; + p3 = 100.0 * (float) lp_count.nr_partially_covered_64 / (float) total_64; + + debug_printf("llvmpipe: nr_empty_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_64, p1, total_64); + debug_printf("llvmpipe: nr_fully_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_64, p2, total_64); + debug_printf("llvmpipe: nr_partially_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_64, p3, total_64); + + total_16 = (lp_count.nr_empty_16 + + lp_count.nr_fully_covered_16 + + lp_count.nr_partially_covered_16); + + p1 = 100.0 * (float) lp_count.nr_empty_16 / (float) total_16; + p2 = 100.0 * (float) lp_count.nr_fully_covered_16 / (float) total_16; + p3 = 100.0 * (float) lp_count.nr_partially_covered_16 / (float) total_16; + + debug_printf("llvmpipe: nr_empty_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_16, p1, total_16); + debug_printf("llvmpipe: nr_fully_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_16, p2, total_16); + debug_printf("llvmpipe: nr_partially_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_16, p3, total_16); + + total_4 = (lp_count.nr_empty_4 + lp_count.nr_non_empty_4); + + p1 = 100.0 * (float) lp_count.nr_empty_4 / (float) total_4; + p2 = 100.0 * (float) lp_count.nr_non_empty_4 / (float) total_4; + + debug_printf("llvmpipe: nr_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_4, p1, total_4); + debug_printf("llvmpipe: nr_non_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_non_empty_4, p2, total_4); + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_perf.h b/src/gallium/drivers/llvmpipe/lp_perf.h new file mode 100644 index 0000000000..9886088c38 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Performance / statistic counters, etc. + */ + + +#ifndef LP_PERF_H +#define LP_PERF_H + + +/** + * Various counters + */ +struct lp_counters +{ + unsigned nr_tris; + unsigned nr_culled_tris; + unsigned nr_empty_64; + unsigned nr_fully_covered_64; + unsigned nr_partially_covered_64; + unsigned nr_empty_16; + unsigned nr_fully_covered_16; + unsigned nr_partially_covered_16; + unsigned nr_empty_4; + unsigned nr_non_empty_4; +}; + + +extern struct lp_counters lp_count; + + +/** Increment the named counter (only for debug builds) */ +#ifdef DEBUG +#define LP_COUNT(counter) lp_count.counter++ +#else +#define LP_COUNT(counter) +#endif + + +extern void +lp_reset_counters(void); + + +extern void +lp_print_counters(void); + + +#endif /* LP_PERF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index b3d1e7dee4..e9d15727a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -32,6 +32,7 @@ #include #include "util/u_math.h" #include "lp_debug.h" +#include "lp_perf.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" @@ -167,6 +168,7 @@ do_block_16( struct lp_rasterizer_task *rast_task, cx2 + eo2 < 0 || cx3 + eo3 < 0) { /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_4); } else { int px = x + pos_table4[i][0]; @@ -174,6 +176,7 @@ do_block_16( struct lp_rasterizer_task *rast_task, /* Don't bother testing if the 4x4 block is entirely in/out of * the triangle. It's a little faster to do it in the jit code. */ + LP_COUNT(nr_non_empty_4); do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); } } @@ -223,6 +226,7 @@ lp_rast_triangle( struct lp_rasterizer *rast, cx2 + eo2 < 0 || cx3 + eo3 < 0) { /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_16); } else { int px = x + pos_table16[i][0]; @@ -232,10 +236,12 @@ lp_rast_triangle( struct lp_rasterizer *rast, cx2 + ei2 > 0 && cx3 + ei3 > 0) { /* the block is completely inside the triangle */ + LP_COUNT(nr_fully_covered_16); block_full_16(rast_task, tri, px, py); } else { /* the block is partially in/out of the triangle */ + LP_COUNT(nr_partially_covered_16); do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); } } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 72f2e8ebf8..9dd4ea7ef6 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -54,6 +54,7 @@ static const struct debug_named_value lp_debug_flags[] = { { "jit", DEBUG_JIT }, { "show_tiles", DEBUG_SHOW_TILES }, { "show_subtiles", DEBUG_SHOW_SUBTILES }, + { "counters", DEBUG_COUNTERS }, {NULL, 0} }; #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index d4a4724ad1..f8fc912fa1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -499,7 +499,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, * Note: we have to check all scenes including any scenes currently * being rendered and the current scene being built. */ -boolean +unsigned lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 5081da29d1..0e155a7dc3 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -123,7 +123,7 @@ void lp_setup_set_sampler_textures( struct setup_context *setup, unsigned num, struct pipe_texture **texture); -boolean +unsigned lp_setup_is_texture_referenced( const struct setup_context *setup, const struct pipe_texture *texture ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 0d89bef606..76ecab7644 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -29,10 +29,11 @@ * Binning code for triangles */ -#include "lp_setup_context.h" -#include "lp_rast.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "lp_perf.h" +#include "lp_setup_context.h" +#include "lp_rast.h" #define NUM_CHANNELS 4 @@ -278,12 +279,15 @@ do_triangle_ccw(struct setup_context *setup, area = (tri->dx12 * tri->dy31 - tri->dx31 * tri->dy12); + LP_COUNT(nr_tris); + /* Cull non-ccw and zero-sized triangles. * * XXX: subject to overflow?? */ if (area <= 0.0f) { lp_scene_putback_data( scene, sizeof *tri ); + LP_COUNT(nr_culled_tris); return; } @@ -303,6 +307,7 @@ do_triangle_ccw(struct setup_context *setup, if (miny == maxy || minx == maxx) { lp_scene_putback_data( scene, sizeof *tri ); + LP_COUNT(nr_culled_tris); return; } @@ -459,6 +464,7 @@ do_triangle_ccw(struct setup_context *setup, cx3 + eo3 < 0) { /* do nothing */ + LP_COUNT(nr_empty_64); if (in) break; /* exiting triangle, all done with this row */ } @@ -466,8 +472,9 @@ do_triangle_ccw(struct setup_context *setup, cx2 + ei2 > 0 && cx3 + ei3 > 0) { - in = TRUE; /* triangle covers the whole tile- shade whole tile */ + LP_COUNT(nr_fully_covered_64); + in = TRUE; if(setup->fs.current.opaque) { lp_scene_bin_reset( scene, x, y ); lp_scene_bin_command( scene, x, y, @@ -480,8 +487,9 @@ do_triangle_ccw(struct setup_context *setup, } else { + /* rasterizer/shade partial tile */ + LP_COUNT(nr_partially_covered_64); in = TRUE; - /* shade partial tile */ lp_scene_bin_command( scene, x, y, lp_rast_triangle, lp_rast_arg_triangle(tri) ); -- cgit v1.2.3