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_rast.c | 119 +++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/gallium/drivers/llvmpipe/lp_rast.c (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') 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); +} + -- cgit v1.2.3 From a6676d896ed18426ed3d7e6340347974c1694ca2 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 12:44:30 +0100 Subject: llvmpipe: Add the rast -> jit shader glue. Ugly code. Will eventually be reduced to a very thin inlined function. --- src/gallium/drivers/llvmpipe/lp_rast.c | 58 +++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 5 +-- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 18 ++++++--- 3 files changed, 73 insertions(+), 8 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 4771f821b3..58ef108123 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -98,6 +98,64 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, } } + +void lp_rast_shade_quads( const struct lp_rast_state *state, + struct lp_rast_tile *tile, + 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 *color; + uint8_t *depth; + uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; + unsigned chan_index; + unsigned q; + + /* 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 */ + color = &TILE_PIXEL(tile->color, x, y, 0); + + /* depth buffer */ + assert((x % 2) == 0); + assert((y % 2) == 0); + depth = (uint8_t)*tile->depth + y*TILE_SIZE*4 + 2*x*4; + + /* 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(state->jc.blend_color, 16)); + + /* run shader */ + state->jit_function( &state->jc, + x, y, + quad->coef->a0, + quad->coef->dadx, + quad->coef->dady, + &mask[0][0], + color, + depth); + +} + + /* End of tile: */ void lp_rast_store_color( struct lp_rasterizer *rast ) diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 8f4bd52c9e..e417be935b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -17,9 +17,8 @@ struct lp_rast_state { /* 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 ); + lp_jit_frag_func shader; + }; /* Coefficients necessary to run the shader at a given location: diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 538ec22551..7eced38d67 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -3,16 +3,24 @@ #include "lp_rast.h" + +/* We can choose whatever layout for the internal tile storage we + * prefer: + */ +struct lp_rast_tile +{ + uint8_t *color; + + uint8_t *depth; +}; + + 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; + struct lp_rast_tile tile; unsigned x; -- 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_rast.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 921584181eb2f3b2849d150295dfce1dae25dd11 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 17:26:13 +0100 Subject: llvmpipe: Fix up lp_rast_shade_quads. --- src/gallium/drivers/llvmpipe/lp_jit.h | 4 ++-- src/gallium/drivers/llvmpipe/lp_rast.c | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 58f716ede2..643e85be20 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -108,13 +108,13 @@ struct lp_jit_context typedef void -(*lp_jit_frag_func)(struct lp_jit_context *context, +(*lp_jit_frag_func)(const struct lp_jit_context *context, uint32_t x, uint32_t y, const void *a0, const void *dadx, const void *dady, - uint32_t *mask, + const uint32_t *mask, void *color, void *depth); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index df48ccce81..e3d1cd56e0 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -30,6 +30,9 @@ #include "lp_state.h" #include "lp_quad.h" #include "lp_rast.h" +#include "lp_rast_priv.h" +#include "lp_tile_soa.h" +#include "lp_bld_debug.h" struct lp_rasterizer *lp_rast_create( void ) @@ -137,7 +140,6 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, 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; @@ -167,7 +169,7 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, /* depth buffer */ assert((x % 2) == 0); assert((y % 2) == 0); - depth = (uint8_t)*tile->depth + y*TILE_SIZE*4 + 2*x*4; + depth = (uint8_t *)tile->depth + y*TILE_SIZE*4 + 2*x*4; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(mask, 16)); @@ -177,14 +179,14 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, assert(lp_check_alignment(state->jc.blend_color, 16)); /* run shader */ - state->jit_function( &state->jc, - x, y, - quad->coef->a0, - quad->coef->dadx, - quad->coef->dady, - &mask[0][0], - color, - depth); + state->shader( &state->jc, + x, y, + quad->coef->a0, + quad->coef->dadx, + quad->coef->dady, + &mask[0][0], + color, + depth); } -- cgit v1.2.3 From d0c918b87a9fb0e86d6b3efedf3ef505e04c527f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 Oct 2009 17:20:40 +0100 Subject: llvmpipe: remove some old sampler support structs --- src/gallium/drivers/llvmpipe/lp_context.c | 40 +++++-------------------- src/gallium/drivers/llvmpipe/lp_context.h | 12 ++------ src/gallium/drivers/llvmpipe/lp_jit.c | 2 +- src/gallium/drivers/llvmpipe/lp_jit.h | 2 +- src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 11 +++---- src/gallium/drivers/llvmpipe/lp_rast.c | 44 +++++++++++++--------------- src/gallium/drivers/llvmpipe/lp_setup.h | 13 +++++--- src/gallium/drivers/llvmpipe/lp_tex_sample.h | 28 ------------------ 8 files changed, 45 insertions(+), 107 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index f087b65321..7f7b04412c 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -44,6 +44,7 @@ #include "lp_texture.h" #include "lp_winsys.h" #include "lp_query.h" +#include "lp_setup.h" @@ -85,20 +86,8 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe, unsigned face, unsigned level) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - unsigned i; - if (lp_setup_is_active(llvmpipe->setup)) { - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { - if(llvmpipe->framebuffer.cbufs[i] && - llvmpipe->framebuffer.cbufs[i]->texture == texture) - return PIPE_REFERENCED_FOR_WRITE; - } - if(llvmpipe->framebuffer.zsbuf && - llvmpipe->framebuffer.zsbuf->texture == texture) - return PIPE_REFERENCED_FOR_WRITE; - } - - return PIPE_UNREFERENCED; + return lp_setup_is_texture_referenced(llvmpipe->setup, texture); } static unsigned int @@ -112,7 +101,6 @@ struct pipe_context * llvmpipe_create( struct pipe_screen *screen ) { struct llvmpipe_context *llvmpipe; - uint i; llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16); if (!llvmpipe) @@ -178,20 +166,6 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe_init_query_funcs( llvmpipe ); llvmpipe_init_texture_funcs( llvmpipe ); - /* vertex shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples; - llvmpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX; - llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i]; - } - - /* fragment shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples; - llvmpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT; - llvmpipe->tgsi.frag_samplers_list[i] = &llvmpipe->tgsi.frag_samplers[i]; - } - /* * Create drawing context and plug our rendering stage into it. */ @@ -199,14 +173,16 @@ llvmpipe_create( struct pipe_screen *screen ) if (!llvmpipe->draw) goto fail; - draw_texture_samplers(llvmpipe->draw, - PIPE_MAX_SAMPLERS, - (struct tgsi_sampler **) - llvmpipe->tgsi.vert_samplers_list); + /* FIXME: vertex sampler state + */ if (debug_get_bool_option( "LP_NO_RAST", FALSE )) llvmpipe->no_rast = TRUE; + llvmpipe->setup = lp_setup_create(); + if (!llvmpipe->setup) + goto fail; + llvmpipe->vbuf_backend = lp_create_vbuf_backend(llvmpipe); if (!llvmpipe->vbuf_backend) goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 17e8897546..852f7a1d05 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -45,7 +45,7 @@ struct draw_stage; struct lp_fragment_shader; struct lp_vertex_shader; struct lp_blend_state; -struct lp_setup_context; +struct setup_context; struct llvmpipe_context { struct pipe_context pipe; /**< base class */ @@ -110,16 +110,8 @@ struct llvmpipe_context { /** Derived from scissor and surface bounds: */ struct pipe_scissor_state cliprect; - /** TGSI exec things */ - struct { - struct lp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS]; - struct lp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS]; - struct lp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS]; - struct lp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS]; - } tgsi; - /** The tiling engine */ - struct lp_setup_context *setup; + struct setup_context *setup; /** The primitive drawing context */ struct draw_context *draw; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 1126bf90b9..a03eb874ac 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -91,7 +91,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants, screen->target, context_type, 0); - LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers, + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, dummy, screen->target, context_type, 1); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, screen->target, context_type, 2); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 643e85be20..207dfbfde1 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -78,7 +78,7 @@ struct lp_jit_context { const float *constants; - struct tgsi_sampler **samplers; + void *dummy; /* remove me */ float alpha_ref_value; diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c index 6c51d40a8f..925e6f8b3b 100644 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c @@ -136,9 +136,8 @@ static boolean 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_update_state( setup_ctx->llvmpipe ); + llvmpipe_update_derived( cvbr->llvmpipe ); cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim); cvbr->prim = prim; @@ -524,9 +523,7 @@ lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) static void lp_vbuf_destroy(struct vbuf_render *vbr) { - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - lp_setup_destroy_context(cvbr->setup); - FREE(cvbr); + FREE(vbr); } @@ -539,6 +536,7 @@ 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; @@ -555,8 +553,7 @@ lp_create_vbuf_backend(struct llvmpipe_context *lp) cvbr->base.destroy = lp_vbuf_destroy; cvbr->llvmpipe = lp; - - cvbr->setup = lp_setup_create_context(cvbr->llvmpipe); + cvbr->setup = lp->setup; return &cvbr->base; } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index e3d1cd56e0..498879e4cf 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -40,7 +40,7 @@ struct lp_rasterizer *lp_rast_create( void ) return CALLOC_STRUCT(lp_rasterizer); } -void lp_rast_bind_surfaces( struct lp_rasterizer *, +void lp_rast_bind_surfaces( struct lp_rasterizer *rast, struct pipe_surface *color, struct pipe_surface *zstencil, const float *clear_color, @@ -49,11 +49,9 @@ void lp_rast_bind_surfaces( struct lp_rasterizer *, { 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 *, @@ -64,9 +62,10 @@ void lp_rast_start_tile( struct lp_rasterizer *, rast->y = y; } -void lp_rast_clear_color( struct lp_rasterizer *rast ) +void lp_rast_clear_color( struct lp_rasterizer *rast, + const union lp_rast_cmd_arg *arg ) { - const unsigned clear_color = rast->state.clear_color; + const unsigned clear_color = arg->clear.clear_color; unsigned i, j; for (i = 0; i < TILESIZE; i++) @@ -74,9 +73,10 @@ void lp_rast_clear_color( struct lp_rasterizer *rast ) rast->tile[i][j] = clear_color; } -void lp_rast_clear_depth( struct lp_rasterizer *rast ) +void lp_rast_clear_zstencil( struct lp_rasterizer *rast, + const union lp_rast_cmd_arg *arg) { - const unsigned clear_depth = rast->state.clear_depth; + const unsigned clear_color = arg->clear.clear_zstencil; unsigned i, j; for (i = 0; i < TILESIZE; i++) @@ -84,19 +84,15 @@ void lp_rast_clear_depth( struct lp_rasterizer *rast ) 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 ) +void lp_rast_load_color( struct lp_rasterizer *rast, + 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 ) +void lp_rast_load_zstencil( struct lp_rasterizer *rast, + const union lp_rast_cmd_arg *arg ) { /* call u_tile func to load depth (and stencil?) from surface */ } @@ -104,15 +100,15 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast ) /* Within a tile: */ void lp_rast_set_state( struct lp_rasterizer *rast, - const struct lp_rast_state *state ) + const union lp_rast_cmd_arg *arg ) { - rast->shader_state = state; - lp->quad.first->begin( lp->quad.first ); + rast->shader_state = arg->state; } void lp_rast_shade_tile( struct lp_rasterizer *rast, + const union lp_rast_cmd_arg *arg ) const struct lp_rast_shader_inputs *inputs ) { /* Set up the silly quad coef pointers @@ -193,14 +189,14 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, /* End of tile: */ -void lp_rast_store_color( struct lp_rasterizer *rast ) +void lp_rast_end_tile( struct lp_rasterizer *rast, + boolean write_depth ) { /* 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 */ + if (write_depth) { + /* call u_tile func to store depth/stencil to surface */ + } } /* Shutdown: diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 6d741f7271..5151a174f2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -50,10 +50,10 @@ lp_setup_clear(struct setup_context *setup, unsigned flags); 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]); void lp_setup_line(struct setup_context *setup, @@ -74,6 +74,11 @@ lp_setup_set_fs_inputs( struct setup_context *setup, const enum lp_interp *interp, unsigned nr ); +boolean +lp_setup_is_texture_referenced( struct setup_context *setup, + const struct pipe_texture *texture ); + + void lp_setup_destroy( struct setup_context *setup ); diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h index 526ea100db..dfc9c0e6f0 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h @@ -37,34 +37,6 @@ struct lp_sampler_static_state; -/** - * Subclass of tgsi_sampler - */ -struct lp_shader_sampler -{ - struct tgsi_sampler base; /**< base class */ - - unsigned processor; - - /* For lp_get_samples_2d_linear_POT: - */ - unsigned xpot; - unsigned ypot; - unsigned level; - - const struct pipe_texture *texture; - const struct pipe_sampler_state *sampler; -}; - - - -static INLINE struct lp_shader_sampler * -lp_shader_sampler(const struct tgsi_sampler *sampler) -{ - return (struct lp_shader_sampler *) sampler; -} - - extern void lp_get_samples(struct tgsi_sampler *tgsi_sampler, -- cgit v1.2.3 From 37b86aa55c6bb520997c00dbf1a2b38d4aed38eb Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 17:59:44 +0100 Subject: llvmpipe: Implement some of the rasterizer functions. --- src/gallium/drivers/llvmpipe/lp_rast.c | 88 +++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 498879e4cf..2217debc02 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -37,7 +37,16 @@ struct lp_rasterizer *lp_rast_create( void ) { - return CALLOC_STRUCT(lp_rasterizer); + struct lp_rasterizer *rast; + + rast = CALLOC_STRUCT(lp_rasterizer); + if(!rast) + return NULL; + + rast->tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); + rast->tile.depth = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); + + return rast; } void lp_rast_bind_surfaces( struct lp_rasterizer *rast, @@ -54,7 +63,7 @@ void lp_rast_bind_surfaces( struct lp_rasterizer *rast, /* Begining of each tile: */ -void lp_rast_start_tile( struct lp_rasterizer *, +void lp_rast_start_tile( struct lp_rasterizer *rast, unsigned x, unsigned y ) { @@ -68,9 +77,17 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, const unsigned clear_color = arg->clear.clear_color; unsigned i, j; - for (i = 0; i < TILESIZE; i++) - for (j = 0; j < TILESIZE; j++) - rast->tile[i][j] = clear_color; + if (clear_color[0] == clear_color[1] && + clear_color[1] == clear_color[2] && + clear_color[2] == clear_color[3]) { + memset(rast->tile.color, clear_color[0], TILE_SIZE * TILE_SIZE * 4); + } + else { + for (y = 0; y < TILE_SIZE; y++) + for (x = 0; x < TILE_SIZE; x++) + for (chan = 0; chan < 4; ++chan) + TILE_PIXEL(rast->tile.color, x, y, chan) = clear_color[chan]; + } } void lp_rast_clear_zstencil( struct lp_rasterizer *rast, @@ -79,9 +96,9 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, const unsigned clear_color = arg->clear.clear_zstencil; unsigned i, j; - for (i = 0; i < TILESIZE; i++) - for (j = 0; j < TILESIZE; j++) - rast->tile[i][j] = clear_depth; + for (i = 0; i < TILE_SIZE; i++) + for (j = 0; j < TILE_SIZE; j++) + rast->tile.depth[i][j] = clear_depth; } @@ -108,9 +125,11 @@ void lp_rast_set_state( struct lp_rasterizer *rast, void lp_rast_shade_tile( struct lp_rasterizer *rast, - const union lp_rast_cmd_arg *arg ) + const union lp_rast_cmd_arg *arg, const struct lp_rast_shader_inputs *inputs ) { + unsigned i; + /* Set up the silly quad coef pointers */ for (i = 0; i < 4; i++) { @@ -120,8 +139,8 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, /* Use the existing preference for 8x2 (four quads) shading: */ - for (i = 0; i < TILESIZE; i += 8) { - for (j = 0; j < TILESIZE; j += 2) { + for (i = 0; i < TILE_SIZE; i += 8) { + for (j = 0; j < TILE_SIZE; j += 2) { rast->shader_state.shade( inputs->jc, rast->x + i, rast->y + j, @@ -189,13 +208,54 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, /* End of tile: */ + + void lp_rast_end_tile( struct lp_rasterizer *rast, boolean write_depth ) { - /* call u_tile func to store colors to surface */ + 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; + + surface = rast->state.color; + if(!surface) + return; + + screen = surface->texture->screen; + + if(x + w > surface->width) + w = surface->width - x; + if(y + h > surface->height) + h = surface->height - x; + + 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(screen, transfer); if (write_depth) { - /* call u_tile func to store depth/stencil to surface */ + /* FIXME: call u_tile func to store depth/stencil to surface */ } } @@ -203,6 +263,8 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, */ void lp_rast_destroy( struct lp_rasterizer *rast ) { + align_free(rast->tile.depth); + align_free(rast->tile.color); FREE(rast); } -- cgit v1.2.3 From ab76b2a8b896edc1e972de108d044b70310b4324 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 19:03:14 +0100 Subject: llvmpipe: Complete more rasterizer methods.. --- src/gallium/drivers/llvmpipe/lp_rast.c | 68 +++++++++++------------------ src/gallium/drivers/llvmpipe/lp_rast.h | 17 +++++--- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 14 ++++-- 3 files changed, 48 insertions(+), 51 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2217debc02..50d2a0a0f3 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -50,14 +50,14 @@ struct lp_rasterizer *lp_rast_create( void ) } void lp_rast_bind_surfaces( struct lp_rasterizer *rast, - struct pipe_surface *color, - struct pipe_surface *zstencil, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf, const float *clear_color, double clear_depth, unsigned clear_stencil) { - pipe_surface_reference(&rast->state.color, color); - pipe_surface_reference(&rast->state.depth, depth); + pipe_surface_reference(&rast->state.cbuf, cbuf); + pipe_surface_reference(&rast->state.zsbuf, zsbuf); } @@ -93,12 +93,12 @@ 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 unsigned clear_color = arg->clear.clear_zstencil; + const unsigned clear_zstencil = arg->clear.clear_zstencil; unsigned i, j; for (i = 0; i < TILE_SIZE; i++) for (j = 0; j < TILE_SIZE; j++) - rast->tile.depth[i][j] = clear_depth; + rast->tile.depth[i*TILE_SIZE + j] = clear_zstencil; } @@ -119,7 +119,7 @@ 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->state; + rast->shader_state = arg->set_state; } @@ -128,36 +128,24 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg *arg, const struct lp_rast_shader_inputs *inputs ) { - unsigned i; - - /* 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; - } + const uint32_t masks[4] = {~0, ~0, ~0, ~0}; + unsigned i, j; /* Use the existing preference for 8x2 (four quads) shading: */ - for (i = 0; i < TILE_SIZE; i += 8) { - for (j = 0; j < TILE_SIZE; j += 2) { - rast->shader_state.shade( inputs->jc, - rast->x + i, - rast->y + j, - rast->quads, 4 ); - } - } + for (i = 0; i < TILE_SIZE; i += 8) + for (j = 0; j < TILE_SIZE; j += 2) + lp_rast_shade_quads( rast, inputs, i, j, &masks); } -void lp_rast_shade_quads( const struct lp_rast_state *state, - struct lp_rast_tile *tile, - struct quad_header **quads, - unsigned nr ) +void lp_rast_shade_quads( struct lp_rasterizer *rast, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y, + const unsigned *masks) { - struct quad_header *quad = quads[0]; - const unsigned x = quad->input.x0; - const unsigned y = quad->input.y0; + const struct lp_rast_state *state = rast->shader_state; + struct lp_rast_tile *tile = &rast->tile; uint8_t *color; uint8_t *depth; uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; @@ -165,18 +153,13 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, unsigned q; /* 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; + mask[q][chan_index] = masks[q] & (1 << chan_index) ? ~0 : 0; /* color buffer */ color = &TILE_PIXEL(tile->color, x, y, 0); @@ -184,7 +167,7 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, /* depth buffer */ assert((x % 2) == 0); assert((y % 2) == 0); - depth = (uint8_t *)tile->depth + y*TILE_SIZE*4 + 2*x*4; + depth = tile->depth + y*TILE_SIZE + 2*x; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(mask, 16)); @@ -196,9 +179,9 @@ void lp_rast_shade_quads( const struct lp_rast_state *state, /* run shader */ state->shader( &state->jc, x, y, - quad->coef->a0, - quad->coef->dadx, - quad->coef->dady, + inputs->a0, + inputs->dadx, + inputs->dady, &mask[0][0], color, depth); @@ -220,8 +203,9 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, const unsigned y = rast->y; unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; + void *map; - surface = rast->state.color; + surface = rast->state.cbuf; if(!surface) return; @@ -252,7 +236,7 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, screen->transfer_unmap(screen, transfer); } - screen->tex_transfer_destroy(screen, transfer); + screen->tex_transfer_destroy(transfer); if (write_depth) { /* 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 f40208bbda..380a1adbd2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -28,6 +28,7 @@ #ifndef LP_RAST_H #define LP_RAST_H +#include "pipe/p_compiler.h" #include "lp_jit.h" /* Initially create and program a single rasterizer directly. Later @@ -91,9 +92,6 @@ struct lp_rast_triangle { float dx12; float dx23; float dx31; - - /* State to run the shader: */ - struct lp_rast_shader_inputs inputs; }; struct clear_tile { @@ -112,8 +110,8 @@ struct load_tile { struct lp_rasterizer *lp_rast_create( void ); void lp_rast_bind_surfaces( struct lp_rasterizer *, - struct pipe_surface *color, - struct pipe_surface *zstencil, + struct pipe_surface *cbuf, + struct pipe_surface *zsbuf, const float *clear_color, double clear_depth, unsigned clear_stencil); @@ -154,7 +152,8 @@ 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 * ); + const union lp_rast_cmd_arg *, + const struct lp_rast_shader_inputs *); void lp_rast_store_color( struct lp_rasterizer *, const union lp_rast_cmd_arg *); @@ -163,6 +162,12 @@ void lp_rast_store_zstencil( struct lp_rasterizer *, const union lp_rast_cmd_arg *); +/* End of tile: + */ + +void lp_rast_end_tile( struct lp_rasterizer *rast, + boolean write_depth ); + /* Shutdown: */ 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 b819519553..29e4c8fd80 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -38,7 +38,7 @@ struct lp_rast_tile { uint8_t *color; - uint8_t *depth; + uint32_t *depth; }; @@ -55,12 +55,20 @@ struct lp_rasterizer { struct { - struct pipe_surface *color; - struct pipe_surface *zstencil; + struct pipe_surface *cbuf; + struct pipe_surface *zsbuf; unsigned clear_color; unsigned clear_depth; char clear_stencil; } state; + + const struct lp_rast_state *shader_state; }; + +void lp_rast_shade_quads( struct lp_rasterizer *rast, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y, + const unsigned *masks); + #endif -- cgit v1.2.3 From 86dba3e4142276d76ecffc0cd238506df5efe9af Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 19:16:47 +0100 Subject: llvmpipe: Final adjustments to rasterizer methods. --- src/gallium/drivers/llvmpipe/lp_rast.c | 22 ++++++++++++---------- src/gallium/drivers/llvmpipe/lp_rast.h | 2 ++ 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 50d2a0a0f3..9d1861d246 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -74,8 +74,7 @@ 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 unsigned clear_color = arg->clear.clear_color; - unsigned i, j; + const uint8_t *clear_color = arg->clear_color; if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && @@ -83,6 +82,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, memset(rast->tile.color, 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) @@ -93,7 +93,7 @@ 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 unsigned clear_zstencil = arg->clear.clear_zstencil; + const unsigned clear_zstencil = arg->clear_zstencil; unsigned i, j; for (i = 0; i < TILE_SIZE; i++) @@ -128,14 +128,14 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg *arg, const struct lp_rast_shader_inputs *inputs ) { - const uint32_t masks[4] = {~0, ~0, ~0, ~0}; - unsigned i, j; + const unsigned masks[4] = {~0, ~0, ~0, ~0}; + unsigned x, y; /* Use the existing preference for 8x2 (four quads) shading: */ - for (i = 0; i < TILE_SIZE; i += 8) - for (j = 0; j < TILE_SIZE; j += 2) - lp_rast_shade_quads( rast, inputs, i, j, &masks); + for (y = 0; y < TILE_SIZE; y += 2) + for (x = 0; x < TILE_SIZE; x += 8) + lp_rast_shade_quads( rast, inputs, x, y, masks); } @@ -146,8 +146,8 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, { const struct lp_rast_state *state = rast->shader_state; struct lp_rast_tile *tile = &rast->tile; - uint8_t *color; - uint8_t *depth; + void *color; + void *depth; uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; unsigned chan_index; unsigned q; @@ -247,6 +247,8 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, */ void lp_rast_destroy( struct lp_rasterizer *rast ) { + pipe_surface_reference(&rast->state.cbuf, NULL); + pipe_surface_reference(&rast->state.zsbuf, NULL); align_free(rast->tile.depth); align_free(rast->tile.color); FREE(rast); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 380a1adbd2..0aa111b472 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -128,6 +128,8 @@ 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]; + unsigned clear_zstencil; }; -- cgit v1.2.3 From 07ee87e6645318a34a395a50f4e8d554d118d24f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 19:18:35 +0100 Subject: llvmpipe: Fix typo. --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 9d1861d246..170684c1b2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -214,7 +214,7 @@ void lp_rast_end_tile( struct lp_rasterizer *rast, if(x + w > surface->width) w = surface->width - x; if(y + h > surface->height) - h = surface->height - x; + h = surface->height - y; transfer = screen->get_tex_transfer(screen, surface->texture, -- cgit v1.2.3 From 21489d2275ff556f6e44008d3f5493ca64619696 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 8 Oct 2009 19:56:01 +0100 Subject: llvmpipe: Remove quad headers. --- src/gallium/drivers/llvmpipe/lp_quad.h | 114 ----------------------------- src/gallium/drivers/llvmpipe/lp_rast.c | 1 - src/gallium/drivers/llvmpipe/lp_rast_tri.c | 1 - src/gallium/drivers/llvmpipe/lp_state_fs.c | 1 - 4 files changed, 117 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_quad.h (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_quad.h b/src/gallium/drivers/llvmpipe/lp_quad.h deleted file mode 100644 index 7eb05de77a..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_quad.h +++ /dev/null @@ -1,114 +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. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#ifndef LP_QUAD_H -#define LP_QUAD_H - -#include "pipe/p_state.h" -#include "tgsi/tgsi_exec.h" - - -#define QUAD_PRIM_POINT 1 -#define QUAD_PRIM_LINE 2 -#define QUAD_PRIM_TRI 3 - - -/* The rasterizer generates 2x2 quads of fragment and feeds them to - * the current fp_machine (see below). - * Remember that Y=0=top with Y increasing down the window. - */ -#define QUAD_TOP_LEFT 0 -#define QUAD_TOP_RIGHT 1 -#define QUAD_BOTTOM_LEFT 2 -#define QUAD_BOTTOM_RIGHT 3 - -#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT) -#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT) -#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT) -#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT) -#define MASK_ALL 0xf - - -/** - * Quad stage inputs (pos, coverage, front/back face, etc) - */ -struct quad_header_input -{ - int x0, y0; /**< quad window pos, always even */ - float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */ - unsigned facing:1; /**< Front (0) or back (1) facing? */ - unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */ -}; - - -/** - * Quad stage inputs/outputs. - */ -struct quad_header_inout -{ - unsigned mask:4; -}; - - -/** - * Quad stage outputs (color & depth). - */ -struct quad_header_output -{ - /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */ - float ALIGN16_ATTRIB color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE]; -}; - - -/** - * Input interpolation coefficients - */ -struct quad_interp_coef -{ - float ALIGN16_ATTRIB a0[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - float ALIGN16_ATTRIB dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - float ALIGN16_ATTRIB dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; -}; - - -/** - * Encodes everything we need to know about a 2x2 pixel block. Uses - * "Channel-Serial" or "SoA" layout. - */ -struct quad_header { - struct quad_header_input input; - struct quad_header_inout inout; - - /* Redundant/duplicated: - */ - const struct quad_interp_coef *coef; -}; - -#endif /* LP_QUAD_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 170684c1b2..110caafffb 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -28,7 +28,6 @@ #include "util/u_memory.h" #include "lp_state.h" -#include "lp_quad.h" #include "lp_rast.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 138d6f55e0..86c785babb 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -30,7 +30,6 @@ */ #include "util/u_math.h" -#include "lp_quad.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index b00be0cc32..2c8b383123 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -84,7 +84,6 @@ #include "lp_screen.h" #include "lp_context.h" #include "lp_state.h" -#include "lp_quad.h" #include "lp_tex_sample.h" -- 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_rast.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 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_rast.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 47510040a68f5f672aee22eac6c01fb4dd60ec67 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 10:37:24 +0100 Subject: llvmpipe: Follow write_color/write_zstencil. --- src/gallium/drivers/llvmpipe/lp_rast.c | 24 ++++++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 6 ------ src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 ++ 3 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6ac44feb4c..9825099c94 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -64,6 +64,7 @@ void lp_rast_bind_color( struct lp_rasterizer *rast, boolean write_color ) { pipe_surface_reference(&rast->state.cbuf, cbuf); + rast->state.write_color = write_color; } void lp_rast_bind_zstencil( struct lp_rasterizer *rast, @@ -71,6 +72,7 @@ void lp_rast_bind_zstencil( struct lp_rasterizer *rast, boolean write_zstencil ) { pipe_surface_reference(&rast->state.zsbuf, zsbuf); + rast->state.write_zstencil = write_zstencil; } @@ -206,7 +208,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, */ -void lp_rast_end_tile( struct lp_rasterizer *rast ) +static void lp_rast_store_color( struct lp_rasterizer *rast ) { struct pipe_surface *surface; struct pipe_screen *screen; @@ -250,11 +252,25 @@ void lp_rast_end_tile( struct lp_rasterizer *rast ) screen->tex_transfer_destroy(transfer); - if (0) { - /* FIXME: call u_tile func to store depth/stencil to surface */ - } } + +static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) +{ + /* FIXME: call u_tile func to store depth/stencil to surface */ +} + + +void lp_rast_end_tile( struct lp_rasterizer *rast ) +{ + if (rast->state.write_color) + lp_rast_store_color(rast); + + if (rast->state.write_zstencil) + lp_rast_store_zstencil(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 26d057beb2..aa50fba5a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -163,12 +163,6 @@ void lp_rast_shade_tile( struct lp_rasterizer *, const union lp_rast_cmd_arg *, const struct lp_rast_shader_inputs *); -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 *); - /* End of tile: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index d7a8b9c257..f5a6699ed4 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -61,6 +61,8 @@ struct lp_rasterizer { struct { struct pipe_surface *cbuf; struct pipe_surface *zsbuf; + boolean write_color; + boolean write_zstencil; unsigned clear_color; unsigned clear_depth; char clear_stencil; -- 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_rast.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 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_rast.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 295aea04895676aae5b67a7016c62bab8e40b996 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 14:07:25 +0100 Subject: llvmpipe: more debug --- src/gallium/drivers/llvmpipe/lp_rast.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index fff292e294..beb149ef18 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -89,7 +89,7 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, unsigned x, unsigned y ) { - RAST_DEBUG("%s\n", __FUNCTION__); + RAST_DEBUG("%s %d,%d\n", __FUNCTION__, x, y); rast->x = x; rast->y = y; @@ -100,7 +100,11 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, { const uint8_t *clear_color = arg.clear_color; - RAST_DEBUG("%s\n", __FUNCTION__); + RAST_DEBUG("%s %x,%x,%x,%x\n", __FUNCTION__, + clear_color[0], + clear_color[1], + clear_color[2], + clear_color[3]); if (clear_color[0] == clear_color[1] && clear_color[1] == clear_color[2] && @@ -238,7 +242,7 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) unsigned h = TILE_SIZE; void *map; - RAST_DEBUG("%s\n", __FUNCTION__); + RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); surface = rast->state.cbuf; if(!surface) -- 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_rast.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 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_rast.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 82ec7f018d20e46e9c43ea467354dcfe4f03bae3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 16:05:26 +0100 Subject: llvmpipe: correct binning maths for iterating over whole tiles --- src/gallium/drivers/llvmpipe/lp_rast.c | 5 +++++ src/gallium/drivers/llvmpipe/lp_setup_tri.c | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index cba50c8049..d4f369d4d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -192,6 +192,7 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { +#if 0 const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const unsigned masks[4] = {~0, ~0, ~0, ~0}; unsigned x, y; @@ -203,6 +204,10 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, for (y = 0; y < TILE_SIZE; y += 2) for (x = 0; x < TILE_SIZE; x += 8) lp_rast_shade_quads( rast, inputs, x, y, masks); +#else + RAST_DEBUG("%s\n", __FUNCTION__); + memset(rast->tile.color, 0x80, TILE_SIZE * TILE_SIZE * 4); +#endif } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 78e53292ec..c437940381 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -357,13 +357,13 @@ do_triangle_ccw(struct setup_context *setup, c2 = tri->c2 + tri->dx23 * miny - tri->dy23 * minx; c3 = tri->c3 + tri->dx31 * miny - tri->dy31 * minx; - /* Convert to tile coordinates: - */ minx /= TILESIZE; - maxx /= TILESIZE; miny /= TILESIZE; + maxx /= TILESIZE; maxy /= TILESIZE; - + + /* Convert to tile coordinates: + */ if (miny == maxy && minx == maxx) { /* Triangle is contained in a single tile: @@ -399,13 +399,13 @@ do_triangle_ccw(struct setup_context *setup, * Trivially accept or reject blocks, else jump to per-pixel * examination above. */ - for (y = miny; y < maxy; y++) + for (y = miny; y <= maxy; y++) { float cx1 = c1; float cx2 = c2; float cx3 = c3; - for (x = minx; x < maxx; x++) + for (x = minx; x <= maxx; x++) { if (cx1 + eo1 < 0 || cx2 + eo2 < 0 || -- cgit v1.2.3 From c2e926b72de21bfac0048f32e1204537446d5ab0 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 16:18:19 +0100 Subject: llvmpipe: Pass framebuffer coords to shader. --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d4f369d4d0..e73331535f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -250,7 +250,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, /* run shader */ state->jit_function( &state->jit_context, - x, y, + rast->x + x, rast->y + y, inputs->a0, inputs->dadx, inputs->dady, -- cgit v1.2.3 From 05131f7502150968d7ee19673676f74d4c2fd22b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 Oct 2009 16:19:00 +0100 Subject: llvmpipe: properly clip tile writes --- src/gallium/drivers/llvmpipe/lp_rast.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index e73331535f..3585011ace 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -269,15 +269,23 @@ 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; - RAST_DEBUG("%s %d,%d\n", __FUNCTION__, x, y); + if (x + w > rast->width) + w -= x + w - rast->width; + + if (y + h > rast->height) + h -= y + h - rast->height; + + RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); lp_tile_write_4ub(rast->cbuf_transfer->format, rast->tile.color, rast->cbuf_map, rast->cbuf_transfer->stride, x, y, - TILESIZE, TILESIZE); + w, h); } -- cgit v1.2.3 From 8c34c86d191fc703670d4e1e1ae4719cb39f8828 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 16:21:25 +0100 Subject: llvmpipe: Undo debug override. --- src/gallium/drivers/llvmpipe/lp_rast.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3585011ace..38c3aea921 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -192,7 +192,6 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { -#if 0 const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const unsigned masks[4] = {~0, ~0, ~0, ~0}; unsigned x, y; @@ -204,10 +203,6 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, for (y = 0; y < TILE_SIZE; y += 2) for (x = 0; x < TILE_SIZE; x += 8) lp_rast_shade_quads( rast, inputs, x, y, masks); -#else - RAST_DEBUG("%s\n", __FUNCTION__); - memset(rast->tile.color, 0x80, TILE_SIZE * TILE_SIZE * 4); -#endif } -- cgit v1.2.3 From 61f3eeb6403e404d297bdcd924c215ed36060945 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 9 Oct 2009 19:16:36 +0100 Subject: llvmpipe: Use framebuffer coords consistently. --- src/gallium/drivers/llvmpipe/lp_rast.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 38c3aea921..2038403c8f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -202,7 +202,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, */ for (y = 0; y < TILE_SIZE; y += 2) for (x = 0; x < TILE_SIZE; x += 8) - lp_rast_shade_quads( rast, inputs, x, y, masks); + lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, masks); } @@ -211,6 +211,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned x, unsigned y, const unsigned *masks) { +#if 1 const struct lp_rast_state *state = inputs->state; struct lp_rast_tile *tile = &rast->tile; void *color; @@ -218,23 +219,27 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; unsigned chan_index; unsigned q; + unsigned ix, iy; /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); + ix = x % TILE_SIZE; + iy = y % TILE_SIZE; + /* mask */ for (q = 0; q < 4; ++q) for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) mask[q][chan_index] = masks[q] & (1 << chan_index) ? ~0 : 0; /* color buffer */ - color = &TILE_PIXEL(tile->color, x, y, 0); + color = &TILE_PIXEL(tile->color, ix, iy, 0); /* depth buffer */ assert((x % 2) == 0); assert((y % 2) == 0); - depth = tile->depth + y*TILE_SIZE + 2*x; + depth = tile->depth + iy*TILE_SIZE + 2*ix; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(mask, 16)); @@ -245,14 +250,30 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, /* run shader */ state->jit_function( &state->jit_context, - rast->x + x, rast->y + y, + x, y, inputs->a0, inputs->dadx, inputs->dady, &mask[0][0], color, depth); +#else + struct lp_rast_tile *tile = &rast->tile; + unsigned chan_index; + unsigned q, ix, iy; + + x %= TILE_SIZE; + y %= TILE_SIZE; + + /* mask */ + for (q = 0; q < 4; ++q) + for(iy = 0; iy < 2; ++iy) + for(ix = 0; ix < 2; ++ix) + if(masks[q] & (1 << (iy*2 + ix))) + for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) + TILE_PIXEL(tile->color, x + q*2 + ix, y + iy, chan_index) = 0xff; +#endif } -- cgit v1.2.3 From b0828b0adc7438ef33f9393f839226ef7dfda0dc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 19 Oct 2009 16:41:27 +0100 Subject: llvmpipe: calculate masks in format desired by shader Also remove branches calculating masks for quads. --- src/gallium/drivers/llvmpipe/lp_rast.c | 21 ++++---- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 +- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 82 ++++++++++++----------------- 3 files changed, 44 insertions(+), 61 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2038403c8f..01f46dcab1 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -193,7 +193,12 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, 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}; + static const uint32_t ALIGN16_ATTRIB masks[4][4] = + { {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0} }; + unsigned x, y; RAST_DEBUG("%s\n", __FUNCTION__); @@ -202,23 +207,20 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, */ for (y = 0; y < TILE_SIZE; y += 2) for (x = 0; x < TILE_SIZE; x += 8) - lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, masks); + lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, &masks[0][0]); } void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - const unsigned *masks) + const uint32_t *masks) { #if 1 const struct lp_rast_state *state = inputs->state; struct lp_rast_tile *tile = &rast->tile; void *color; void *depth; - uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; - unsigned chan_index; - unsigned q; unsigned ix, iy; /* Sanity checks */ @@ -228,11 +230,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, ix = x % TILE_SIZE; iy = y % TILE_SIZE; - /* mask */ - for (q = 0; q < 4; ++q) - for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) - mask[q][chan_index] = masks[q] & (1 << chan_index) ? ~0 : 0; - /* color buffer */ color = &TILE_PIXEL(tile->color, ix, iy, 0); @@ -254,7 +251,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, inputs->a0, inputs->dadx, inputs->dady, - &mask[0][0], + masks, color, depth); #else diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 11e8e78e79..f438faaf36 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -80,6 +80,6 @@ struct lp_rasterizer { void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - const unsigned *masks); + const uint32_t *masks); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 17ebce4c85..5f22aca668 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -37,34 +37,26 @@ #define BLOCKSIZE 4 -/* Convert 8x8 block into four runs of quads and render each in turn. +/* Render a 4x4 unmasked block: */ -#if (BLOCKSIZE == 8) static void block_full( struct lp_rasterizer *rast, const struct lp_rast_triangle *tri, int x, int y ) { - const unsigned masks[4] = {~0, ~0, ~0, ~0}; - int iy; + static const uint32_t ALIGN16_ATTRIB masks[4][4] = + { {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0}, + {~0, ~0, ~0, ~0} }; - for (iy = 0; iy < 8; iy += 2) - lp_rast_shade_quads(rast, &tri->inputs, x, y + iy, masks); + lp_rast_shade_quads(rast, &tri->inputs, x, y, &masks[0][0]); } -#else -static void block_full( struct lp_rasterizer *rast, - const struct lp_rast_triangle *tri, - int x, int y ) -{ - const unsigned masks[4] = {~0, ~0, ~0, ~0}; - lp_rast_shade_quads(rast, &tri->inputs, x, y, masks); -} -#endif -static INLINE unsigned +static INLINE void do_quad( const struct lp_rast_triangle *tri, - int x, int y, - int c1, int c2, int c3 ) + int c1, int c2, int c3, + int32_t *mask ) { const int xstep1 = -tri->dy12 ; const int xstep2 = -tri->dy23 ; @@ -73,30 +65,22 @@ do_quad( const struct lp_rast_triangle *tri, const int ystep1 = tri->dx12 ; const int ystep2 = tri->dx23 ; const int ystep3 = tri->dx31 ; - - unsigned mask = 0; - - if (c1 > 0 && - c2 > 0 && - c3 > 0) - mask |= 1; - - if (c1 + xstep1 > 0 && - c2 + xstep2 > 0 && - c3 + xstep3 > 0) - mask |= 2; - - if (c1 + ystep1 > 0 && - c2 + ystep2 > 0 && - c3 + ystep3 > 0) - mask |= 4; - - if (c1 + ystep1 + xstep1 > 0 && - c2 + ystep2 + xstep2 > 0 && - c3 + ystep3 + xstep3 > 0) - mask |= 8; - - return mask; + + mask[0] = ~(((c1) | + (c2) | + (c3)) >> 31); + + mask[1] = ~(((c1 + xstep1) | + (c2 + xstep2) | + (c3 + xstep3)) >> 31); + + mask[2] = ~(((c1 + ystep1) | + (c2 + ystep2) | + (c3 + ystep3)) >> 31); + + mask[3] = ~(((c1 + ystep1 + xstep1) | + (c2 + ystep2 + xstep2) | + (c3 + ystep3 + xstep3)) >> 31); } /* Evaluate each pixel in a block, generate a mask and possibly render @@ -121,17 +105,17 @@ do_block( struct lp_rasterizer *rast, const int ystep3 = step * tri->dx31; int ix, iy; + uint32_t ALIGN16_ATTRIB mask[4][4]; - unsigned masks[2][2] = {{0, 0}, {0, 0}}; - for (iy = 0; iy < BLOCKSIZE; iy += 2) { + for (iy = 0; iy < 4; iy += 2) { int cx1 = c1; int cx2 = c2; int cx3 = c3; - for (ix = 0; ix < BLOCKSIZE; ix += 2) { + for (ix = 0; ix < 2; ix ++) { - masks[iy >> 1][ix >> 1] = do_quad(tri, x + ix, y + iy, cx1, cx2, cx3); + do_quad(tri, cx1, cx2, cx3, (int32_t *)mask[iy+ix]); cx1 += xstep1; cx2 += xstep2; @@ -143,8 +127,10 @@ do_block( struct lp_rasterizer *rast, c3 += ystep3; } - if(masks[0][0] || masks[0][1] || masks[1][0] || masks[1][1]) - lp_rast_shade_quads(rast, &tri->inputs, x, y, &masks[0][0]); + /* As we do trivial reject already, masks should rarely be all + * zero: + */ + lp_rast_shade_quads(rast, &tri->inputs, x, y, &mask[0][0] ); } -- cgit v1.2.3 From 5b07d4de38b732f99237161d940f40e3ce6e29c3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 19 Oct 2009 17:10:48 +0100 Subject: llvmpipe: remove a leftover 8x2 usage --- src/gallium/drivers/llvmpipe/lp_rast.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 01f46dcab1..85b756e453 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -203,10 +203,10 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, RAST_DEBUG("%s\n", __FUNCTION__); - /* Use the existing preference for 8x2 (four quads) shading: + /* Use the existing preference for 4x4 (four quads) shading: */ - for (y = 0; y < TILE_SIZE; y += 2) - for (x = 0; x < TILE_SIZE; x += 8) + for (y = 0; y < TILE_SIZE; y += 4) + for (x = 0; x < TILE_SIZE; x += 4) lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, &masks[0][0]); } @@ -239,7 +239,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, depth = tile->depth + iy*TILE_SIZE + 2*ix; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ - assert(lp_check_alignment(mask, 16)); + assert(lp_check_alignment(masks, 16)); assert(lp_check_alignment(depth, 16)); assert(lp_check_alignment(color, 16)); -- cgit v1.2.3 From 7670628061c2a6ce0a1a787556b0e33a38fd3049 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 20 Oct 2009 02:46:00 +0100 Subject: llvmpipe: precalculate some offsets --- src/gallium/drivers/llvmpipe/lp_rast.c | 20 ++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 2 + src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 +- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 80 +++++------------------------ src/gallium/drivers/llvmpipe/lp_setup_tri.c | 26 ++++++++++ 5 files changed, 51 insertions(+), 79 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 85b756e453..39fb8cdb6b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -193,12 +193,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { const struct lp_rast_shader_inputs *inputs = arg.shade_tile; - static const uint32_t ALIGN16_ATTRIB masks[4][4] = - { {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0} }; - + const unsigned mask = ~0; unsigned x, y; RAST_DEBUG("%s\n", __FUNCTION__); @@ -207,26 +202,31 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, */ for (y = 0; y < TILE_SIZE; y += 4) for (x = 0; x < TILE_SIZE; x += 4) - lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, &masks[0][0]); + lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, mask); } void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - const uint32_t *masks) + unsigned mask) { #if 1 const struct lp_rast_state *state = inputs->state; struct lp_rast_tile *tile = &rast->tile; void *color; void *depth; - unsigned ix, iy; + uint32_t ALIGN16_ATTRIB masks[16]; + unsigned ix, iy, i; /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); + /* mask */ + for (i = 0; i < 16; ++i) + masks[i] = mask & (1 << i) ? ~0 : 0; + ix = x % TILE_SIZE; iy = y % TILE_SIZE; @@ -251,7 +251,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, inputs->a0, inputs->dadx, inputs->dady, - masks, + &masks[0], color, depth); #else diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 9725007119..318bf73b15 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -111,6 +111,8 @@ struct lp_rast_triangle { int c2; int c3; + int step[3][16]; + /* XXX: this is only used inside lp_setup_tri.c, don't really * need it here: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index f438faaf36..2333729807 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -80,6 +80,6 @@ struct lp_rasterizer { void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - const uint32_t *masks); + unsigned masks); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 5f22aca668..b5a3753a88 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -37,100 +37,44 @@ #define BLOCKSIZE 4 + /* Render a 4x4 unmasked block: */ static void block_full( struct lp_rasterizer *rast, const struct lp_rast_triangle *tri, int x, int y ) { - static const uint32_t ALIGN16_ATTRIB masks[4][4] = - { {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0}, - {~0, ~0, ~0, ~0} }; + unsigned mask = ~0; - lp_rast_shade_quads(rast, &tri->inputs, x, y, &masks[0][0]); + lp_rast_shade_quads(rast, &tri->inputs, x, y, mask); } -static INLINE void -do_quad( const struct lp_rast_triangle *tri, - int c1, int c2, int c3, - int32_t *mask ) -{ - const int xstep1 = -tri->dy12 ; - const int xstep2 = -tri->dy23 ; - const int xstep3 = -tri->dy31 ; - - const int ystep1 = tri->dx12 ; - const int ystep2 = tri->dx23 ; - const int ystep3 = tri->dx31 ; - - mask[0] = ~(((c1) | - (c2) | - (c3)) >> 31); - - mask[1] = ~(((c1 + xstep1) | - (c2 + xstep2) | - (c3 + xstep3)) >> 31); - - mask[2] = ~(((c1 + ystep1) | - (c2 + ystep2) | - (c3 + ystep3)) >> 31); - - mask[3] = ~(((c1 + ystep1 + xstep1) | - (c2 + ystep2 + xstep2) | - (c3 + ystep3 + xstep3)) >> 31); -} /* Evaluate each pixel in a block, generate a mask and possibly render * the quad: */ static void do_block( struct lp_rasterizer *rast, - const struct lp_rast_triangle *tri, + const struct lp_rast_triangle *tri, int x, int y, int c1, int c2, int c3 ) { - const int step = 2 ; - - const int xstep1 = -step * tri->dy12; - const int xstep2 = -step * tri->dy23; - const int xstep3 = -step * tri->dy31; - - const int ystep1 = step * tri->dx12; - const int ystep2 = step * tri->dx23; - const int ystep3 = step * tri->dx31; + int i; + unsigned mask = 0; - int ix, iy; - uint32_t ALIGN16_ATTRIB mask[4][4]; - - - for (iy = 0; iy < 4; iy += 2) { - int cx1 = c1; - int cx2 = c2; - int cx3 = c3; - - for (ix = 0; ix < 2; ix ++) { - - do_quad(tri, cx1, cx2, cx3, (int32_t *)mask[iy+ix]); - - cx1 += xstep1; - cx2 += xstep2; - cx3 += xstep3; - } - - c1 += ystep1; - c2 += ystep2; - c3 += ystep3; - } + for (i = 0; i < 16; i++) + mask |= (~(((c1 + tri->step[0][i]) | + (c2 + tri->step[1][i]) | + (c3 + tri->step[2][i])) >> 31)) & (1 << i); + /* As we do trivial reject already, masks should rarely be all * zero: */ - lp_rast_shade_quads(rast, &tri->inputs, x, y, &mask[0][0] ); + lp_rast_shade_quads(rast, &tri->inputs, x, y, mask ); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 6c9f75e90c..a5a0407a57 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -359,6 +359,32 @@ do_triangle_ccw(struct setup_context *setup, maxx = tri->maxx / TILESIZE; maxy = tri->maxy / TILESIZE; + { + int xstep1 = -tri->dy12; + int xstep2 = -tri->dy23; + int xstep3 = -tri->dy31; + + int ystep1 = tri->dx12; + int ystep2 = tri->dx23; + int ystep3 = tri->dx31; + + int ix, iy; + int qx, qy; + int i = 0; + + for (qy = 0; qy < 4; qy += 2) { + for (qx = 0; qx < 4; qx += 2) { + for (iy = 0; iy < 2; iy++) { + for (ix = 0; ix < 2; ix++, i++) { + tri->step[0][i] = (xstep1 * (qx+ix)) + (ystep1 * (qy+iy)); + tri->step[1][i] = (xstep2 * (qx+ix)) + (ystep2 * (qy+iy)); + tri->step[2][i] = (xstep3 * (qx+ix)) + (ystep3 * (qy+iy)); + } + } + } + } + } + /* Convert to tile coordinates: */ if (miny == maxy && minx == maxx) -- cgit v1.2.3 From 7b116e13a2aa28a699e30c907c1b1ae5e04cab28 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 20 Oct 2009 03:17:17 +0100 Subject: llvmpipe: pass mask as a linear encoding of the 4x4 block --- src/gallium/drivers/llvmpipe/lp_rast.c | 41 ++++++++++++++++++++++++----- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 15 ++++------- 2 files changed, 40 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 39fb8cdb6b..6fd6acc0fa 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -216,16 +216,45 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, struct lp_rast_tile *tile = &rast->tile; void *color; void *depth; - uint32_t ALIGN16_ATTRIB masks[16]; - unsigned ix, iy, i; + uint32_t ALIGN16_ATTRIB masks[2][2][2][2]; + unsigned ix, iy; /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); - /* mask */ - for (i = 0; i < 16; ++i) - masks[i] = mask & (1 << i) ? ~0 : 0; + /* mask: the rasterizer wants to treat pixels in 4x4 blocks, but + * the pixel shader wants to swizzle them into 4 2x2 quads. + * + * Additionally, the pixel shader wants masks as full dword ~0, + * while the rasterizer wants to pack per-pixel bits tightly. + */ +#if 0 + unsigned qx, qy; + for (qy = 0; qy < 2; ++qy) + for (qx = 0; qx < 2; ++qx) + for (iy = 0; iy < 2; ++iy) + for (ix = 0; ix < 2; ++ix) + masks[qy][qx][iy][ix] = mask & (1 << (qy*8+iy*4+qx*2+ix)) ? ~0 : 0; +#else + masks[0][0][0][0] = mask & (1 << (0*8+0*4+0*2+0)) ? ~0 : 0; + masks[0][0][0][1] = mask & (1 << (0*8+0*4+0*2+1)) ? ~0 : 0; + masks[0][0][1][0] = mask & (1 << (0*8+1*4+0*2+0)) ? ~0 : 0; + masks[0][0][1][1] = mask & (1 << (0*8+1*4+0*2+1)) ? ~0 : 0; + masks[0][1][0][0] = mask & (1 << (0*8+0*4+1*2+0)) ? ~0 : 0; + masks[0][1][0][1] = mask & (1 << (0*8+0*4+1*2+1)) ? ~0 : 0; + masks[0][1][1][0] = mask & (1 << (0*8+1*4+1*2+0)) ? ~0 : 0; + masks[0][1][1][1] = mask & (1 << (0*8+1*4+1*2+1)) ? ~0 : 0; + + masks[1][0][0][0] = mask & (1 << (1*8+0*4+0*2+0)) ? ~0 : 0; + masks[1][0][0][1] = mask & (1 << (1*8+0*4+0*2+1)) ? ~0 : 0; + masks[1][0][1][0] = mask & (1 << (1*8+1*4+0*2+0)) ? ~0 : 0; + masks[1][0][1][1] = mask & (1 << (1*8+1*4+0*2+1)) ? ~0 : 0; + masks[1][1][0][0] = mask & (1 << (1*8+0*4+1*2+0)) ? ~0 : 0; + masks[1][1][0][1] = mask & (1 << (1*8+0*4+1*2+1)) ? ~0 : 0; + masks[1][1][1][0] = mask & (1 << (1*8+1*4+1*2+0)) ? ~0 : 0; + masks[1][1][1][1] = mask & (1 << (1*8+1*4+1*2+1)) ? ~0 : 0; +#endif ix = x % TILE_SIZE; iy = y % TILE_SIZE; @@ -251,7 +280,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, inputs->a0, inputs->dadx, inputs->dady, - &masks[0], + &masks[0][0][0][0], color, depth); #else diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index a5a0407a57..cf8643fc63 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -369,18 +369,13 @@ do_triangle_ccw(struct setup_context *setup, int ystep3 = tri->dx31; int ix, iy; - int qx, qy; int i = 0; - for (qy = 0; qy < 4; qy += 2) { - for (qx = 0; qx < 4; qx += 2) { - for (iy = 0; iy < 2; iy++) { - for (ix = 0; ix < 2; ix++, i++) { - tri->step[0][i] = (xstep1 * (qx+ix)) + (ystep1 * (qy+iy)); - tri->step[1][i] = (xstep2 * (qx+ix)) + (ystep2 * (qy+iy)); - tri->step[2][i] = (xstep3 * (qx+ix)) + (ystep3 * (qy+iy)); - } - } + for (iy = 0; iy < 4; iy++) { + for (ix = 0; ix < 4; ix++, i++) { + tri->step[0][i] = xstep1 * ix + ystep1 * iy; + tri->step[1][i] = xstep2 * ix + ystep2 * iy; + tri->step[2][i] = xstep3 * ix + ystep3 * iy; } } } -- 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_rast.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: Thu, 22 Oct 2009 17:21:37 +0100 Subject: llvmpipe: fix the worst of the depth regressions since switch to 4x4 --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6e94e22e5b..32cd5e09f5 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -265,7 +265,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, /* depth buffer */ assert((x % 2) == 0); assert((y % 2) == 0); - depth = tile->depth + iy*TILE_SIZE + 2*ix; + depth = tile->depth + (iy/4)*(16*16) + (ix/4)*16; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(masks, 16)); -- cgit v1.2.3 From 7505510c7b7c33f3c571647c0398da7e1b823806 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 30 Nov 2009 14:02:01 -0700 Subject: llvmpipe: add a bunch of comments --- src/gallium/drivers/llvmpipe/lp_rast.c | 30 ++++++++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_rast.h | 5 +++-- src/gallium/drivers/llvmpipe/lp_setup_context.h | 6 +++++ src/gallium/drivers/llvmpipe/lp_setup_tri.c | 26 ++++++++++++--------- 4 files changed, 54 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 32cd5e09f5..09495f6288 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -51,6 +51,10 @@ 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, struct pipe_surface *cbuf, struct pipe_surface *zsbuf, @@ -95,6 +99,10 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, } +/** + * Finish the rasterization phase. + * Unmap framebuffer surfaces. + */ void lp_rast_end( struct lp_rasterizer *rast ) { struct pipe_screen *screen = rast->screen; @@ -120,7 +128,10 @@ void lp_rast_end( struct lp_rasterizer *rast ) -/* Begining of each tile: +/** + * Begining rasterization of a tile. + * \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, @@ -132,6 +143,10 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, rast->y = y; } + +/** + * Clear the rasterizer's current color tile. + */ void lp_rast_clear_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { @@ -157,6 +172,10 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, } } + +/** + * Clear the rasterizer's current z/stencil tile. + */ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg) { @@ -307,6 +326,9 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, */ +/** + * Write the rasterizer's color tile to the framebuffer. + */ static void lp_rast_store_color( struct lp_rasterizer *rast ) { const unsigned x = rast->x; @@ -331,6 +353,9 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) } +/** + * Write the rasterizer's z/stencil tile to the framebuffer. + */ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) { RAST_DEBUG("%s\n", __FUNCTION__); @@ -339,6 +364,9 @@ 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 ) { RAST_DEBUG("%s\n", __FUNCTION__); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 282b9a46d1..a50b73b27f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -79,6 +79,7 @@ struct lp_rast_shader_inputs { * plus inputs to run the shader: */ struct lp_rast_triangle { + /* bounding box of tri (in pixels) */ int minx; int maxx; int miny; @@ -94,12 +95,12 @@ struct lp_rast_triangle { int eo2; int eo3; - /* y deltas for vertex pairs */ + /* y deltas for vertex pairs (in fixed pt) */ int dy12; int dy23; int dy31; - /* x deltas for vertex pairs */ + /* x deltas for vertex pairs (in fixed pt) */ int dx12; int dx23; int dx31; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 938f6ce262..3209e41c01 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 { struct cmd_block_list tile[TILES_X][TILES_Y]; struct data_block_list data; + /* size of framebuffer, in tiles */ unsigned tiles_x; unsigned tiles_y; @@ -154,6 +155,11 @@ 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) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index f2665c11df..cf86255406 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -230,6 +230,11 @@ static inline int subpixel_snap( float a ) #define MIN3(a,b,c) MIN2(MIN2(a,b),c) #define MAX3(a,b,c) MAX2(MAX2(a,b),c) +/** + * 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. + */ static void do_triangle_ccw(struct setup_context *setup, const float (*v1)[4], @@ -237,15 +242,14 @@ do_triangle_ccw(struct setup_context *setup, const float (*v3)[4], boolean frontfacing ) { - + /* x/y positions in fixed point */ + const int x1 = subpixel_snap(v1[0][0]); + const int x2 = subpixel_snap(v2[0][0]); + const int x3 = subpixel_snap(v3[0][0]); const int y1 = subpixel_snap(v1[0][1]); const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - const int x1 = subpixel_snap(v1[0][0]); - const int x2 = subpixel_snap(v2[0][0]); - const int x3 = subpixel_snap(v3[0][0]); - struct lp_rast_triangle *tri = get_data( &setup->data, sizeof *tri ); float area; int minx, maxx, miny, maxy; @@ -270,7 +274,7 @@ do_triangle_ccw(struct setup_context *setup, return; } - // Bounding rectangle + /* Bounding rectangle (in pixels) */ tri->minx = (MIN3(x1, x2, x3) + 0xf) >> FIXED_ORDER; tri->maxx = (MAX3(x1, x2, x3) + 0xf) >> FIXED_ORDER; tri->miny = (MIN3(y1, y2, y3) + 0xf) >> FIXED_ORDER; @@ -372,13 +376,14 @@ do_triangle_ccw(struct setup_context *setup, } } + /* Convert to tile coordinates: + */ minx = tri->minx / TILE_SIZE; miny = tri->miny / TILE_SIZE; maxx = tri->maxx / TILE_SIZE; maxy = tri->maxy / TILE_SIZE; - - /* Convert to tile coordinates: + /* Determine which tile(s) intersect the triangle's bounding box */ if (miny == maxy && minx == maxx) { @@ -442,8 +447,9 @@ do_triangle_ccw(struct setup_context *setup, cx3 + ei3 > 0) { in = 1; - /* shade whole tile */ - bin_command( &setup->tile[x][y], lp_rast_shade_tile, + /* triangle covers the whole tile- shade whole tile */ + bin_command( &setup->tile[x][y], + lp_rast_shade_tile, lp_rast_arg_inputs(&tri->inputs) ); } else -- cgit v1.2.3 From 866e6856d39efe9b1ec739587f420a640ad8618e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 2 Dec 2009 15:13:45 -0700 Subject: llvmpipe: execute shaders on 4x4 blocks instead of 8x2 This matches the convention used by the recursive rasterizer. Also fixed assorted typos, comments, etc. Now tri-z.c, gears.c, etc look basically right but there's still some cracks in triangle rasterization. --- src/gallium/drivers/llvmpipe/lp_bld_interp.c | 135 ++++++++++++++++++--------- src/gallium/drivers/llvmpipe/lp_bld_interp.h | 10 +- src/gallium/drivers/llvmpipe/lp_rast.c | 22 +++-- src/gallium/drivers/llvmpipe/lp_state_fs.c | 12 ++- 4 files changed, 116 insertions(+), 63 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index 338dbca6d1..affeeca6ff 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -45,6 +45,36 @@ #include "lp_bld_interp.h" +/* + * The shader JIT function operates on blocks of quads. + * Each block has 2x2 quads and each quad has 2x2 pixels. + * + * We iterate over the quads in order 0, 1, 2, 3: + * + * ################# + * # | # | # + * #---0---#---1---# + * # | # | # + * ################# + * # | # | # + * #---2---#---3---# + * # | # | # + * ################# + * + * Within each quad, we have four pixels which are represented in SOA + * order: + * + * ######### + * # 0 | 1 # + * #---+---# + * # 2 | 3 # + * ######### + * + * So the green channel (for example) of the four pixels is stored in + * a single vector register: {g0, g1, g2, g3}. + */ + + static void attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix) { @@ -55,6 +85,10 @@ attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix } +/** + * Initialize the bld->a0, dadx, dady fields. This involves fetching + * those values from the arrays which are passed into the JIT function. + */ static void coeffs_init(struct lp_build_interp_soa_context *bld, LLVMValueRef a0_ptr, @@ -91,7 +125,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld, case TGSI_INTERPOLATE_CONSTANT: a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), ""); a0 = lp_build_broadcast_scalar(&bld->base, a0); - attrib_name(a0, attrib, chan, ".dady"); + attrib_name(a0, attrib, chan, ".a0"); break; default: @@ -135,29 +169,12 @@ coeff_multiply(struct lp_build_interp_soa_context *bld, /** - * Multiply the dadx and dady with the xstep and ystep respectively. + * Emit LLVM code to compute the fragment shader input attribute values. + * For example, for a color input, we'll compute red, green, blue and alpha + * values for the four pixels in a quad. + * Recall that we're operating on 4-element vectors so each arithmetic + * operation is operating on the four pixels in a quad. */ -static void -coeffs_update(struct lp_build_interp_soa_context *bld) -{ - unsigned attrib; - unsigned chan; - - for(attrib = 0; attrib < bld->num_attribs; ++attrib) { - unsigned mask = bld->mask[attrib]; - unsigned mode = bld->mode[attrib]; - if (mode != TGSI_INTERPOLATE_CONSTANT) { - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - if(mask & (1 << chan)) { - bld->dadx[attrib][chan] = coeff_multiply(bld, bld->dadx[attrib][chan], bld->xstep); - bld->dady[attrib][chan] = coeff_multiply(bld, bld->dady[attrib][chan], bld->ystep); - } - } - } - } -} - - static void attribs_init(struct lp_build_interp_soa_context *bld) { @@ -180,7 +197,9 @@ attribs_init(struct lp_build_interp_soa_context *bld) res = a0; if (mode != TGSI_INTERPOLATE_CONSTANT) { + /* res = res + x * dadx */ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx)); + /* res = res + y * dady */ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady)); } @@ -204,13 +223,19 @@ attribs_init(struct lp_build_interp_soa_context *bld) } +/** + * Increment the shader input attribute values. + * This is called when we move from one quad to the next. + */ static void -attribs_update(struct lp_build_interp_soa_context *bld) +attribs_update(struct lp_build_interp_soa_context *bld, int quad_index) { LLVMValueRef oow = NULL; unsigned attrib; unsigned chan; + assert(quad_index < 4); + for(attrib = 0; attrib < bld->num_attribs; ++attrib) { unsigned mask = bld->mask[attrib]; unsigned mode = bld->mode[attrib]; @@ -224,13 +249,21 @@ attribs_update(struct lp_build_interp_soa_context *bld) res = bld->attribs_pre[attrib][chan]; - if(bld->xstep) + if (quad_index == 1 || quad_index == 3) { + /* top-right or bottom-right quad */ + /* build res = res + dadx + dadx */ res = lp_build_add(&bld->base, res, dadx); + res = lp_build_add(&bld->base, res, dadx); + } - if(bld->ystep) + if (quad_index == 2 || quad_index == 3) { + /* bottom-left or bottom-right quad */ + /* build res = res + dady + dady */ res = lp_build_add(&bld->base, res, dady); + res = lp_build_add(&bld->base, res, dady); + } - bld->attribs_pre[attrib][chan] = res; + //XXX bld->attribs_pre[attrib][chan] = res; if (mode == TGSI_INTERPOLATE_PERSPECTIVE) { LLVMValueRef w = bld->pos[3]; @@ -268,17 +301,32 @@ pos_init(struct lp_build_interp_soa_context *bld, } +/** + * Update quad position values when moving to the next quad. + */ static void -pos_update(struct lp_build_interp_soa_context *bld) +pos_update(struct lp_build_interp_soa_context *bld, int quad_index) { LLVMValueRef x = bld->attribs[0][0]; LLVMValueRef y = bld->attribs[0][1]; + const int xstep = 2, ystep = 2; - if(bld->xstep) - x = lp_build_add(&bld->base, x, lp_build_const_scalar(bld->base.type, bld->xstep)); + if (quad_index == 1 || quad_index == 3) { + /* top-right or bottom-right quad in block */ + /* build x += xstep */ + x = lp_build_add(&bld->base, x, + lp_build_const_scalar(bld->base.type, xstep)); + } - if(bld->ystep) - y = lp_build_add(&bld->base, y, lp_build_const_scalar(bld->base.type, bld->ystep)); + if (quad_index == 2) { + /* bottom-left quad in block */ + /* build y += ystep */ + y = lp_build_add(&bld->base, y, + lp_build_const_scalar(bld->base.type, ystep)); + /* build x -= xstep */ + x = lp_build_sub(&bld->base, x, + lp_build_const_scalar(bld->base.type, xstep)); + } lp_build_name(x, "pos.x"); lp_build_name(y, "pos.y"); @@ -288,6 +336,9 @@ pos_update(struct lp_build_interp_soa_context *bld) } +/** + * Initialize fragment shader input attribute info. + */ void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, const struct tgsi_token *tokens, @@ -297,9 +348,7 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, LLVMValueRef x0, - LLVMValueRef y0, - int xstep, - int ystep) + LLVMValueRef y0) { struct tgsi_parse_context parse; struct tgsi_full_declaration *decl; @@ -357,21 +406,19 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, pos_init(bld, x0, y0); attribs_init(bld); - - bld->xstep = xstep; - bld->ystep = ystep; - - coeffs_update(bld); } /** - * Advance the position and inputs with the xstep and ystep. + * Advance the position and inputs to the given quad within the block. */ void -lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld) +lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld, + int quad_index) { - pos_update(bld); + assert(quad_index < 4); + + pos_update(bld, quad_index); - attribs_update(bld); + attribs_update(bld, quad_index); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h index 9c57a10879..e2b3bc1bf0 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h @@ -63,9 +63,6 @@ struct lp_build_interp_soa_context LLVMValueRef dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; LLVMValueRef dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - int xstep; - int ystep; - /* Attribute values before perspective divide */ LLVMValueRef attribs_pre[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; @@ -88,12 +85,11 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, LLVMValueRef x0, - LLVMValueRef y0, - int xstep, - int ystep); + LLVMValueRef y0); void -lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld); +lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld, + int quad_index); #endif /* LP_BLD_INTERP_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 09495f6288..f88dd4ae68 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -126,8 +126,6 @@ void lp_rast_end( struct lp_rasterizer *rast ) } - - /** * Begining rasterization of a tile. * \param x window X position of the tile, in pixels @@ -152,7 +150,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, { const uint8_t *clear_color = arg.clear_color; - RAST_DEBUG("%s %x,%x,%x,%x\n", __FUNCTION__, + RAST_DEBUG("%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, clear_color[0], clear_color[1], clear_color[2], @@ -181,7 +179,7 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, { unsigned i, j; - RAST_DEBUG("%s\n", __FUNCTION__); + RAST_DEBUG("%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); for (i = 0; i < TILE_SIZE; i++) for (j = 0; j < TILE_SIZE; j++) @@ -225,6 +223,9 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, } +/** + * Compute shading for a 4x4 block of pixels. + */ void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, @@ -237,6 +238,7 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, void *depth; uint32_t ALIGN16_ATTRIB masks[2][2][2][2]; unsigned ix, iy; + int block_offset; /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); @@ -275,16 +277,20 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, masks[1][1][1][1] = mask & (1 << (1*8+1*4+1*2+1)) ? ~0 : 0; #endif + assert((x % 2) == 0); + assert((y % 2) == 0); + ix = x % TILE_SIZE; iy = y % TILE_SIZE; + /* offset of the 16x16 pixel block within the tile */ + block_offset = ((iy/4)*(16*16) + (ix/4)*16); + /* color buffer */ - color = &TILE_PIXEL(tile->color, ix, iy, 0); + color = tile->color + 4 * block_offset; /* depth buffer */ - assert((x % 2) == 0); - assert((y % 2) == 0); - depth = tile->depth + (iy/4)*(16*16) + (ix/4)*16; + depth = tile->depth + block_offset; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(masks, 16)); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 0541d36580..aa9c006633 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -358,6 +358,9 @@ generate_blend(const struct pipe_blend_state *blend, /** * Generate the runtime callable function for the whole fragment pipeline. + * Note that the function which we generate operates on a block of 16 + * pixels at at time. The block contains 2x2 quads. Each quad contains + * 2x2 pixels. */ static struct lp_fragment_shader_variant * generate_fragment(struct llvmpipe_context *lp, @@ -437,8 +440,8 @@ generate_fragment(struct llvmpipe_context *lp, fs_type.sign = TRUE; /* values are signed */ fs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ fs_type.width = 32; /* 32-bit float */ - fs_type.length = 4; /* 4 element per vector */ - num_fs = 4; + fs_type.length = 4; /* 4 elements per vector */ + num_fs = 4; /* number of quads per block */ memset(&blend_type, 0, sizeof blend_type); blend_type.floating = FALSE; /* values are integers */ @@ -509,18 +512,19 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_interp_soa_init(&interp, shader->base.tokens, builder, fs_type, a0_ptr, dadx_ptr, dady_ptr, - x0, y0, 2, 0); + x0, y0); /* code generated texture sampling */ sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr); + /* 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 depth_ptr_i; if(i != 0) - lp_build_interp_soa_update(&interp); + lp_build_interp_soa_update(&interp, i); fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), ""); depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, ""); -- cgit v1.2.3 From 51663f0506ed2534e57b798cdfaf8a0d376eb7a2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 11:41:45 -0700 Subject: llvmpipe: quick & dirty implementation of lp_rast_store_zstencil() This allows us to do a glReadPixels(GL_DEPTH_COMPONENT) to see what's in the depth buffer to help debugging. --- src/gallium/drivers/llvmpipe/lp_rast.c | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index f88dd4ae68..c8359f45a2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -95,6 +95,23 @@ boolean lp_rast_begin( struct lp_rasterizer *rast, return FALSE; } + if (zsbuf) { + rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen, + zsbuf->texture, + zsbuf->face, + zsbuf->level, + zsbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, width, height); + if (!rast->zsbuf_transfer) + return FALSE; + + rast->zsbuf_map = screen->transfer_map(rast->screen, + rast->zsbuf_transfer); + if (!rast->zsbuf_map) + return FALSE; + } + return TRUE; } @@ -117,7 +134,7 @@ void lp_rast_end( struct lp_rasterizer *rast ) screen->tex_transfer_destroy(rast->cbuf_transfer); if (rast->zsbuf_transfer) - screen->tex_transfer_destroy(rast->cbuf_transfer); + screen->tex_transfer_destroy(rast->zsbuf_transfer); rast->cbuf_transfer = NULL; rast->zsbuf_transfer = NULL; @@ -359,14 +376,44 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) } +static void +lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride, + unsigned x0, unsigned y0, unsigned w, unsigned h) +{ + unsigned x, y; + uint8_t *dst_row = dst + y0*dst_stride; + for (y = 0; y < h; ++y) { + uint32_t *dst_pixel = (uint32_t *)(dst_row + x0*4); + for (x = 0; x < w; ++x) { + *dst_pixel++ = *src++; + } + dst_row += dst_stride; + } +} + /** * Write the rasterizer's z/stencil tile to the framebuffer. */ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) { - RAST_DEBUG("%s\n", __FUNCTION__); + const unsigned x = rast->x; + const unsigned y = rast->y; + unsigned w = TILE_SIZE; + unsigned h = TILE_SIZE; + + if (x + w > rast->width) + w -= x + w - rast->width; + + if (y + h > rast->height) + h -= y + h - rast->height; + + RAST_DEBUG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); - /* FIXME: call u_tile func to store depth/stencil to surface */ + assert(rast->zsbuf_transfer->format == PIPE_FORMAT_Z32_UNORM); + lp_tile_write_z32(rast->tile.depth, + rast->zsbuf_map, + rast->zsbuf_transfer->stride, + x, y, w, h); } -- cgit v1.2.3 From ffd0759973165368ac8ce07d9bcffeb0acf88e6f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2009 14:57:44 -0700 Subject: llvmpipe: comments and a stub for lp_rast_set_state() --- src/gallium/drivers/llvmpipe/lp_rast.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index c8359f45a2..2d319777ee 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -161,6 +161,7 @@ void lp_rast_start_tile( struct lp_rasterizer *rast, /** * Clear the rasterizer's current color tile. + * This is a bin command called during bin processing. */ void lp_rast_clear_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) @@ -190,6 +191,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, /** * Clear the rasterizer's current z/stencil tile. + * This is a bin command called during bin processing. */ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg) @@ -204,6 +206,10 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, } +/** + * Load tile color from the framebuffer surface. + * This is a bin command called during bin processing. + */ void lp_rast_load_color( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg) { @@ -212,6 +218,11 @@ void lp_rast_load_color( struct lp_rasterizer *rast, /* call u_tile func to load colors from surface */ } + +/** + * Load tile z/stencil from the framebuffer surface. + * This is a bin command called during bin processing. + */ void lp_rast_load_zstencil( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { @@ -220,9 +231,25 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, /* call u_tile func to load depth (and stencil?) from surface */ } + +void lp_rast_set_state( struct lp_rasterizer *rast, + const union lp_rast_cmd_arg arg ) +{ + RAST_DEBUG("%s\n", __FUNCTION__); + + /* XXX to do */ +} + + + /* Within a tile: */ +/** + * Run the shader on all blocks in a tile. This is used when a tile is + * completely contained inside a triangle. + * This is a bin command called during bin processing. + */ void lp_rast_shade_tile( struct lp_rasterizer *rast, const union lp_rast_cmd_arg arg ) { @@ -242,6 +269,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, /** * Compute shading for a 4x4 block of pixels. + * This is a bin command called during bin processing. */ void lp_rast_shade_quads( struct lp_rasterizer *rast, const struct lp_rast_shader_inputs *inputs, -- 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_rast.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 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_rast.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 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_rast.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 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_rast.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_rast.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 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_rast.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 cdaea049c95031338040b31ff31944c8a001a1dd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Dec 2009 15:31:50 -0700 Subject: llvmpipe: use bin iteration functions when rasterizing bins --- src/gallium/drivers/llvmpipe/lp_rast.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 642f1b9079..a6192e589d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -505,8 +505,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast, const struct pipe_framebuffer_state *fb, bool write_depth ) { - unsigned i, j; - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); lp_rast_begin( rast, @@ -518,12 +516,28 @@ lp_rasterize_bins( struct lp_rasterizer *rast, fb->height ); /* loop over tile bins, rasterize each */ - 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 ); +#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); + rasterize_bin( rast, bin, i * TILE_SIZE, j * TILE_SIZE ); + } } } +#else + { + struct cmd_bin *bin; + int x, y; + + lp_bin_iter_begin( bins ); + + while ((bin = lp_bin_iter_next(bins, &x, &y))) { + rasterize_bin( rast, bin, x * TILE_SIZE, y * TILE_SIZE); + } + } +#endif lp_rast_end( rast ); -- cgit v1.2.3 From 3a06c113c76355fc9622adfe7565c18d9787e9a8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Dec 2009 17:02:17 -0700 Subject: llvmpipe: repartition lp_rasterizer state for threading Some of the state is per-thread. Put that state in new lp_rasterizer_task struct. --- src/gallium/drivers/llvmpipe/lp_bin.h | 4 +- src/gallium/drivers/llvmpipe/lp_rast.c | 89 +++++++++++++++++++---------- src/gallium/drivers/llvmpipe/lp_rast.h | 7 +++ src/gallium/drivers/llvmpipe/lp_rast_priv.h | 43 +++++++++----- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 62 ++++++++++---------- 5 files changed, 133 insertions(+), 72 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h index 24e599ea66..b07ff64e62 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -56,7 +56,9 @@ /* 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 *, + unsigned thread_index, + const union lp_rast_cmd_arg ); struct cmd_block { lp_rast_cmd cmd[CMD_BLOCK_MAX]; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index a6192e589d..37cc28e938 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -39,14 +39,18 @@ struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) { struct lp_rasterizer *rast; + unsigned i; rast = CALLOC_STRUCT(lp_rasterizer); 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 ); + + 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 ); + } return rast; } @@ -153,12 +157,13 @@ lp_rast_end( struct lp_rasterizer *rast ) */ static void lp_rast_start_tile( struct lp_rasterizer *rast, + unsigned thread_index, unsigned x, unsigned y ) { LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); - rast->x = x; - rast->y = y; + rast->tasks[thread_index].x = x; + rast->tasks[thread_index].y = y; } @@ -167,9 +172,11 @@ lp_rast_start_tile( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_clear_color( struct lp_rasterizer *rast, + unsigned thread_index, 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; LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, clear_color[0], @@ -180,14 +187,14 @@ 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(rast->tile.color, clear_color[0], TILE_SIZE * TILE_SIZE * 4); + memset(color_tile, 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(rast->tile.color, x, y, chan) = clear_color[chan]; + TILE_PIXEL(color_tile, x, y, chan) = clear_color[chan]; } } @@ -197,15 +204,17 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg) { unsigned i, j; + uint32_t *depth_tile = rast->tasks[thread_index].tile.depth; 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++) - rast->tile.depth[i*TILE_SIZE + j] = arg.clear_zstencil; + depth_tile[i*TILE_SIZE + j] = arg.clear_zstencil; } @@ -214,6 +223,7 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_load_color( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg) { LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -227,6 +237,7 @@ void lp_rast_load_color( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_load_zstencil( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg ) { LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -236,6 +247,7 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, void lp_rast_set_state( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg ) { const struct lp_rast_state *state = arg.set_state; @@ -243,7 +255,7 @@ void lp_rast_set_state( struct lp_rasterizer *rast, LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state); /* just set the current state pointer for this rasterizer */ - rast->current_state = state; + rast->tasks[thread_index].current_state = state; } @@ -257,9 +269,12 @@ void lp_rast_set_state( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_shade_tile( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg ) { 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; const unsigned mask = ~0; unsigned x, y; @@ -269,7 +284,12 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, */ for (y = 0; y < TILE_SIZE; y += 4) for (x = 0; x < TILE_SIZE; x += 4) - lp_rast_shade_quads( rast, inputs, rast->x + x, rast->y + y, mask); + lp_rast_shade_quads( rast, + thread_index, + inputs, + tile_x + x, + tile_y + y, + mask); } @@ -278,13 +298,14 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, * This is a bin command called during bin processing. */ void lp_rast_shade_quads( struct lp_rasterizer *rast, + unsigned thread_index, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, unsigned mask) { #if 1 - const struct lp_rast_state *state = rast->current_state; - struct lp_rast_tile *tile = &rast->tile; + const struct lp_rast_state *state = rast->tasks[thread_index].current_state; + struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; void *color; void *depth; uint32_t ALIGN16_ATTRIB masks[2][2][2][2]; @@ -388,10 +409,11 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, /** * Write the rasterizer's color tile to the framebuffer. */ -static void lp_rast_store_color( struct lp_rasterizer *rast ) +static void lp_rast_store_color( struct lp_rasterizer *rast, + unsigned thread_index) { - const unsigned x = rast->x; - const unsigned y = rast->y; + const unsigned x = rast->tasks[thread_index].x; + const unsigned y = rast->tasks[thread_index].y; unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; @@ -404,7 +426,7 @@ static void lp_rast_store_color( struct lp_rasterizer *rast ) 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, + rast->tasks[thread_index].tile.color, rast->cbuf_map, rast->cbuf_transfer->stride, x, y, @@ -430,10 +452,11 @@ lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride, /** * Write the rasterizer's z/stencil tile to the framebuffer. */ -static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) +static void lp_rast_store_zstencil( struct lp_rasterizer *rast, + unsigned thread_index ) { - const unsigned x = rast->x; - const unsigned y = rast->y; + const unsigned x = rast->tasks[thread_index].x; + const unsigned y = rast->tasks[thread_index].y; unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; @@ -446,7 +469,7 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) 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, + lp_tile_write_z32(rast->tasks[thread_index].tile.depth, rast->zsbuf_map, rast->zsbuf_transfer->stride, x, y, w, h); @@ -457,15 +480,16 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast ) * Write the rasterizer's tiles to the framebuffer. */ static void -lp_rast_end_tile( struct lp_rasterizer *rast ) +lp_rast_end_tile( struct lp_rasterizer *rast, + unsigned thread_index ) { LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); if (rast->state.write_color) - lp_rast_store_color(rast); + lp_rast_store_color(rast, thread_index); if (rast->state.write_zstencil) - lp_rast_store_zstencil(rast); + lp_rast_store_zstencil(rast, thread_index); } @@ -476,6 +500,7 @@ lp_rast_end_tile( struct lp_rasterizer *rast ) */ static void rasterize_bin( struct lp_rasterizer *rast, + unsigned thread_index, const struct cmd_bin *bin, int x, int y) { @@ -483,16 +508,16 @@ rasterize_bin( struct lp_rasterizer *rast, struct cmd_block *block; unsigned k; - lp_rast_start_tile( rast, x, y ); + lp_rast_start_tile( rast, thread_index, 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] ); + block->cmd[k]( rast, 0, block->arg[k] ); } } - lp_rast_end_tile( rast ); + lp_rast_end_tile( rast, thread_index ); } @@ -522,7 +547,7 @@ lp_rasterize_bins( struct lp_rasterizer *rast, 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 ); + rasterize_bin( rast, 0, bin, i * TILE_SIZE, j * TILE_SIZE ); } } } @@ -534,7 +559,7 @@ lp_rasterize_bins( struct lp_rasterizer *rast, lp_bin_iter_begin( bins ); while ((bin = lp_bin_iter_next(bins, &x, &y))) { - rasterize_bin( rast, bin, x * TILE_SIZE, y * TILE_SIZE); + rasterize_bin( rast, 0, bin, x * TILE_SIZE, y * TILE_SIZE); } } #endif @@ -550,10 +575,16 @@ lp_rasterize_bins( struct lp_rasterizer *rast, */ void lp_rast_destroy( struct lp_rasterizer *rast ) { + unsigned i; + pipe_surface_reference(&rast->state.cbuf, NULL); pipe_surface_reference(&rast->state.zsbuf, NULL); - align_free(rast->tile.depth); - align_free(rast->tile.color); + + for (i = 0; i < Elements(rast->tasks); i++) { + align_free(rast->tasks[i].tile.depth); + align_free(rast->tasks[i].tile.color); + } + FREE(rast); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index e77c77b776..25e7f8e008 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -193,24 +193,31 @@ lp_rast_arg_null( void ) */ void lp_rast_clear_color( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_clear_zstencil( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_load_color( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_load_zstencil( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_set_state( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_triangle( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); void lp_rast_shade_tile( struct lp_rasterizer *, + unsigned thread_index, const union lp_rast_cmd_arg ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 98111edff7..9e7cbd7912 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -30,6 +30,10 @@ #include "lp_rast.h" + +#define MAX_THREADS 4 /* XXX probably temporary here */ + + struct pipe_transfer; struct pipe_screen; @@ -47,14 +51,34 @@ struct lp_rast_tile /** - * This is the state required while rasterizing a tile. - * The tile size is TILE_SIZE x TILE_SIZE pixels. + * Per-thread rasterization state */ -struct lp_rasterizer +struct lp_rasterizer_task { struct lp_rast_tile tile; /** Tile color/z/stencil memory */ unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */ + + /* Pixel blocks produced during rasterization + */ + unsigned nr_blocks; + struct { + unsigned x; + unsigned y; + unsigned mask; + } blocks[256]; + + const struct lp_rast_state *current_state; +}; + + +/** + * This is the state required while rasterizing tiles. + * Note that this contains per-thread information too. + * The tile size is TILE_SIZE x TILE_SIZE pixels. + */ +struct lp_rasterizer +{ unsigned width, height; /**< Size of framebuffer, in pixels */ boolean clipped_tile; @@ -78,20 +102,13 @@ struct lp_rasterizer char clear_stencil; } state; - /* Pixel blocks produced during rasterization - */ - unsigned nr_blocks; - struct { - unsigned x; - unsigned y; - unsigned mask; - } blocks[256]; - - const struct lp_rast_state *current_state; + /** A task object for each rasterization thread */ + struct lp_rasterizer_task tasks[MAX_THREADS]; }; void lp_rast_shade_quads( struct lp_rasterizer *rast, + unsigned thread_index, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, unsigned masks); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 81a9c1c142..6c96010c52 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -40,15 +40,15 @@ * All pixels are known to be inside the triangle's bounds. */ static void -block_full_4( struct lp_rasterizer *rast, int x, int y ) +block_full_4( struct lp_rasterizer_task *rast_task, int x, int y ) { - const unsigned i = rast->nr_blocks; + const unsigned i = rast_task->nr_blocks; assert(x % 4 == 0); assert(y % 4 == 0); - rast->blocks[i].x = x; - rast->blocks[i].y = y; - rast->blocks[i].mask = ~0; - rast->nr_blocks++; + rast_task->blocks[i].x = x; + rast_task->blocks[i].y = y; + rast_task->blocks[i].mask = ~0; + rast_task->nr_blocks++; } @@ -57,14 +57,14 @@ block_full_4( struct lp_rasterizer *rast, int x, int y ) * All pixels are known to be inside the triangle's bounds. */ static void -block_full_16( struct lp_rasterizer *rast, int x, int y ) +block_full_16( struct lp_rasterizer_task *rast_task, int x, int y ) { unsigned ix, iy; assert(x % 16 == 0); assert(y % 16 == 0); for (iy = 0; iy < 16; iy += 4) for (ix = 0; ix < 16; ix += 4) - block_full_4(rast, x + ix, y + iy); + block_full_4(rast_task, x + ix, y + iy); } @@ -74,7 +74,7 @@ block_full_16( struct lp_rasterizer *rast, int x, int y ) * Generate a mask of in/out flags and add the block to the blocks list. */ static void -do_block_4( struct lp_rasterizer *rast, +do_block_4( struct lp_rasterizer_task *rast_task, const struct lp_rast_triangle *tri, int x, int y, int c1, @@ -97,11 +97,11 @@ do_block_4( struct lp_rasterizer *rast, /* As we do trivial reject already, masks should rarely be all zero: */ if (mask) { - const unsigned i = rast->nr_blocks; - rast->blocks[i].x = x; - rast->blocks[i].y = y; - rast->blocks[i].mask = mask; - rast->nr_blocks++; + const unsigned i = rast_task->nr_blocks; + rast_task->blocks[i].x = x; + rast_task->blocks[i].y = y; + rast_task->blocks[i].mask = mask; + rast_task->nr_blocks++; } } @@ -111,7 +111,7 @@ do_block_4( struct lp_rasterizer *rast, * of the triangle's bounds. */ static void -do_block_16( struct lp_rasterizer *rast, +do_block_16( struct lp_rasterizer_task *rast_task, const struct lp_rast_triangle *tri, int x, int y, int c1, @@ -146,11 +146,11 @@ do_block_16( struct lp_rasterizer *rast, cx2 + ei2 > 0 && cx3 + ei3 > 0) { /* the block is completely inside the triangle */ - block_full_4(rast, x+ix, y+iy); + block_full_4(rast_task, x+ix, y+iy); } else { /* the block is partially in/out of the triangle */ - do_block_4(rast, tri, x+ix, y+iy, cx1, cx2, cx3); + do_block_4(rast_task, tri, x+ix, y+iy, cx1, cx2, cx3); } } } @@ -163,12 +163,14 @@ do_block_16( struct lp_rasterizer *rast, */ void lp_rast_triangle( struct lp_rasterizer *rast, + unsigned thread_index, const union lp_rast_cmd_arg arg ) { + struct lp_rasterizer_task *rast_task = &rast->tasks[thread_index]; const struct lp_rast_triangle *tri = arg.triangle; - int x = rast->x; - int y = rast->y; + int x = rast_task->x; + int y = rast_task->y; int ix, iy; unsigned i = 0; @@ -184,11 +186,11 @@ lp_rast_triangle( struct lp_rasterizer *rast, int eo2 = tri->eo2 * 16; int eo3 = tri->eo3 * 16; - assert(Elements(rast->blocks) == (TILE_SIZE * TILE_SIZE) / (4*4)); + assert(Elements(rast_task->blocks) == (TILE_SIZE * TILE_SIZE) / (4*4)); LP_DBG(DEBUG_RAST, "lp_rast_triangle\n"); - rast->nr_blocks = 0; + rast_task->nr_blocks = 0; /* Walk over the tile to build a list of 4x4 pixel blocks which will * be filled/shaded. We do this at two granularities: 16x16 blocks @@ -209,21 +211,23 @@ lp_rast_triangle( struct lp_rasterizer *rast, cx2 + ei2 > 0 && cx3 + ei3 > 0) { /* the block is completely inside the triangle */ - block_full_16(rast, x+ix, y+iy); + block_full_16(rast_task, x+ix, y+iy); } else { /* the block is partially in/out of the triangle */ - do_block_16(rast, tri, x+ix, y+iy, cx1, cx2, cx3); + do_block_16(rast_task, tri, x+ix, y+iy, cx1, cx2, cx3); } } } - assert(rast->nr_blocks <= Elements(rast->blocks)); + assert(rast_task->nr_blocks <= Elements(rast_task->blocks)); /* Shade the 4x4 pixel blocks */ - for (i = 0; i < rast->nr_blocks; i++) - lp_rast_shade_quads(rast, &tri->inputs, - rast->blocks[i].x, - rast->blocks[i].y, - rast->blocks[i].mask); + for (i = 0; i < rast_task->nr_blocks; i++) + lp_rast_shade_quads(rast, + thread_index, + &tri->inputs, + rast_task->blocks[i].x, + rast_task->blocks[i].y, + rast_task->blocks[i].mask); } -- cgit v1.2.3 From aab1ceceecbd6449eebce7f5f5b356b1a51552e7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Dec 2009 18:01:12 -0700 Subject: llvmpipe: implement threaded rasterization The LP_NUM_THREADS env var controls how many threads are created. The default (and max) is 4, for now. If LP_NUM_THREADS = 0, threading is not used. --- src/gallium/drivers/llvmpipe/lp_rast.c | 195 ++++++++++++++++++++++------ src/gallium/drivers/llvmpipe/lp_rast_priv.h | 18 +++ 2 files changed, 170 insertions(+), 43 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 37cc28e938..99f7108b42 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "util/u_memory.h" +#include "util/u_math.h" #include "lp_debug.h" #include "lp_state.h" @@ -36,25 +37,6 @@ #include "lp_bin.h" -struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) -{ - struct lp_rasterizer *rast; - unsigned i; - - rast = CALLOC_STRUCT(lp_rasterizer); - if(!rast) - return NULL; - - rast->screen = screen; - - 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 ); - } - - return rast; -} - /** * Begin the rasterization phase. @@ -414,16 +396,25 @@ 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; - unsigned w = TILE_SIZE; - unsigned h = TILE_SIZE; + int w = TILE_SIZE; + int h = TILE_SIZE; if (x + w > rast->width) w -= x + w - rast->width; - if (y + h > rast->height) - h -= y + h - rast->height; + if (y + h > rast->height) { + int h2; + h2 = h - (y + h - rast->height); + assert(h2 <= TILE_SIZE); + h = h2; + } + assert(w >= 0); + assert(h >= 0); + assert(w <= TILE_SIZE); + assert(h <= TILE_SIZE); - LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, + thread_index, x, y, w, h); lp_tile_write_4ub(rast->cbuf_transfer->format, rast->tasks[thread_index].tile.color, @@ -513,7 +504,7 @@ rasterize_bin( struct lp_rasterizer *rast, /* 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, 0, block->arg[k] ); + block->cmd[k]( rast, thread_index, block->arg[k] ); } } @@ -524,6 +515,41 @@ rasterize_bin( struct lp_rasterizer *rast, /** * Rasterize/execute all bins. */ +static void +rasterize_bins( struct lp_rasterizer *rast, + unsigned thread_index, + struct lp_bins *bins, + const struct pipe_framebuffer_state *fb, + bool write_depth ) +{ + /* loop over tile 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); + rasterize_bin( rast, thread_index, + bin, i * TILE_SIZE, j * TILE_SIZE ); + } + } + } +#else + { + struct cmd_bin *bin; + int x, y; + + while ((bin = lp_bin_iter_next(bins, &x, &y))) { + rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); + } + } +#endif +} + + +/** + * Called by rasterizer when it has something for us to render. + */ void lp_rasterize_bins( struct lp_rasterizer *rast, struct lp_bins *bins, @@ -539,30 +565,32 @@ lp_rasterize_bins( struct lp_rasterizer *rast, fb->zsbuf != NULL && write_depth, fb->width, fb->height ); - - /* loop over tile 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); - rasterize_bin( rast, 0, bin, i * TILE_SIZE, j * TILE_SIZE ); - } - } + + if (rast->num_threads == 0) { + /* no threading */ + lp_bin_iter_begin( bins ); + rasterize_bins( rast, 0, bins, fb, write_depth ); } -#else - { - struct cmd_bin *bin; - int x, y; + else { + /* threaded rendering! */ + unsigned i; + + rast->bins = bins; + rast->fb = fb; + rast->write_depth = write_depth; lp_bin_iter_begin( bins ); - while ((bin = lp_bin_iter_next(bins, &x, &y))) { - rasterize_bin( rast, 0, bin, x * TILE_SIZE, y * TILE_SIZE); + /* signal the threads that there's work to do */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_signal(&rast->tasks[i].work_ready); + } + + /* wait for work to complete */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_wait(&rast->tasks[i].work_done); } } -#endif lp_rast_end( rast ); @@ -570,6 +598,87 @@ lp_rasterize_bins( struct lp_rasterizer *rast, } +/** + * This is the thread's main entrypoint. + * It's a simple loop: + * 1. wait for work + * 2. do work + * 3. signal that we're done + */ +static void * +thread_func( void *init_data ) +{ + struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; + struct lp_rasterizer *rast = task->rast; + int debug = 0; + + while (1) { + /* wait for work */ + if (debug) + debug_printf("thread %d waiting for work\n", task->thread_index); + pipe_semaphore_wait(&task->work_ready); + + /* do work */ + if (debug) + debug_printf("thread %d doing work\n", task->thread_index); + rasterize_bins(rast, task->thread_index, + rast->bins, rast->fb, rast->write_depth); + + /* signal done with work */ + if (debug) + debug_printf("thread %d done working\n", task->thread_index); + pipe_semaphore_signal(&task->work_done); + } + + return NULL; +} + + +/** + * Initialize semaphores and spawn the threads. + */ +static void +create_rast_threads(struct lp_rasterizer *rast) +{ + unsigned i; + + rast->num_threads = debug_get_num_option("LP_NUM_THREADS", MAX_THREADS); + rast->num_threads = MIN2(rast->num_threads, MAX_THREADS); + + /* NOTE: if num_threads is zero, we won't use any threads */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_init(&rast->tasks[i].work_ready, 0); + pipe_semaphore_init(&rast->tasks[i].work_done, 0); + rast->threads[i] = pipe_thread_create(thread_func, + (void *) &rast->tasks[i]); + } +} + + + +struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen ) +{ + struct lp_rasterizer *rast; + unsigned i; + + rast = CALLOC_STRUCT(lp_rasterizer); + if(!rast) + return NULL; + + rast->screen = screen; + + 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 ); + rast->tasks[i].rast = rast; + rast->tasks[i].thread_index = i; + } + + create_rast_threads(rast); + + return rast; +} + /* Shutdown: */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 9e7cbd7912..62f3c877da 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -28,6 +28,7 @@ #ifndef LP_RAST_PRIV_H #define LP_RAST_PRIV_H +#include "pipe/p_thread.h" #include "lp_rast.h" @@ -36,6 +37,7 @@ struct pipe_transfer; struct pipe_screen; +struct lp_rasterizer; /** @@ -69,6 +71,15 @@ struct lp_rasterizer_task } blocks[256]; const struct lp_rast_state *current_state; + + /** "back" pointer */ + struct lp_rasterizer *rast; + + /** "my" index */ + unsigned thread_index; + + pipe_semaphore work_ready; + pipe_semaphore work_done; }; @@ -104,6 +115,13 @@ struct lp_rasterizer /** A task object for each rasterization thread */ struct lp_rasterizer_task tasks[MAX_THREADS]; + + unsigned num_threads; + pipe_thread threads[MAX_THREADS]; + + struct lp_bins *bins; + const struct pipe_framebuffer_state *fb; + boolean write_depth; }; -- cgit v1.2.3 From 73e13c33fd0a9b8574d00d01d301b9d4f88d4051 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Dec 2009 18:18:37 -0700 Subject: llvmpipe: remove some left-over debug code --- src/gallium/drivers/llvmpipe/lp_rast.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 99f7108b42..01685b79d8 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -402,12 +402,9 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, if (x + w > rast->width) w -= x + w - rast->width; - if (y + h > rast->height) { - int h2; - h2 = h - (y + h - rast->height); - assert(h2 <= TILE_SIZE); - h = h2; - } + if (y + h > rast->height) + h -= y + h - rast->height; + assert(w >= 0); assert(h >= 0); assert(w <= TILE_SIZE); -- cgit v1.2.3 From 7f457acabcbeea6a27b4f375f55e318fff52445f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 8 Dec 2009 08:02:49 +0000 Subject: llvmpipe: Use number of CPUs as default number of threads. Also bump MAX_THREADS to 8. --- src/gallium/drivers/llvmpipe/lp_rast.c | 4 +++- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 01685b79d8..7cd046cc39 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -27,6 +27,7 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_cpu_detect.h" #include "lp_debug.h" #include "lp_state.h" @@ -639,7 +640,8 @@ create_rast_threads(struct lp_rasterizer *rast) { unsigned i; - rast->num_threads = debug_get_num_option("LP_NUM_THREADS", MAX_THREADS); + rast->num_threads = util_cpu_caps.nr_cpus; + rast->num_threads = debug_get_num_option("LP_NUM_THREADS", rast->num_threads); rast->num_threads = MIN2(rast->num_threads, MAX_THREADS); /* NOTE: if num_threads is zero, we won't use any threads */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 62f3c877da..5502419a92 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -32,7 +32,7 @@ #include "lp_rast.h" -#define MAX_THREADS 4 /* XXX probably temporary here */ +#define MAX_THREADS 8 /* XXX probably temporary here */ struct pipe_transfer; -- 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_rast.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_rast.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 96689d451a24753e088f40fb167c3cb26d8045ac Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Dec 2009 16:32:32 -0700 Subject: llvmpipe: added some debug/info code --- src/gallium/drivers/llvmpipe/lp_rast.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3165128f8f..5659ae2ca5 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -40,6 +40,7 @@ + /** * Begin the rasterization phase. * Map the framebuffer surfaces. Initialize the 'rast' state. @@ -555,8 +556,22 @@ lp_rasterize_bins( struct lp_rasterizer *rast, const struct pipe_framebuffer_state *fb, bool write_depth ) { + boolean debug = false; + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + 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(" bin %u, %u size: %u\n", x, y, + lp_bin_cmd_size(bins, x, y)); + } + } + } + lp_rast_begin( rast, fb->cbufs[0], fb->zsbuf, -- cgit v1.2.3 From 9509f73c2147a9e225b5ef69a646e5dd711573f5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Dec 2009 14:56:30 -0700 Subject: llvmpipe: checkpoint: use empty/full bin queues --- src/gallium/drivers/llvmpipe/lp_rast.c | 64 +++++++++++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 8 ++++ 2 files changed, 64 insertions(+), 8 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 5659ae2ca5..0cd95e0ca7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -40,6 +40,46 @@ +/** + * Called by rasterization threads to get the next chunk of work. + * We use a lock to make sure that all the threads get the same bins. + */ +static struct lp_bins * +get_next_full_bin( struct lp_rasterizer *rast ) +{ + pipe_mutex_lock( rast->get_bin_mutex ); + if (!rast->curr_bins) { + /* this will wait until there's something in the queue */ + rast->curr_bins = lp_bins_dequeue( rast->full_bins ); + rast->release_count = 0; + + lp_bin_iter_begin( rast->curr_bins ); + } + pipe_mutex_unlock( rast->get_bin_mutex ); + return rast->curr_bins; +} + + +/** + * Called by rasterization threads after they've finished with + * the current bin. When all threads have called this, we reset + * the bin and put it into the 'empty bins' queue. + */ +static void +release_current_bin( struct lp_rasterizer *rast ) +{ + pipe_mutex_lock( rast->get_bin_mutex ); + rast->release_count++; + if (rast->release_count == rast->num_threads) { + assert(rast->curr_bins); + lp_reset_bins( rast->curr_bins ); + lp_bins_enqueue( rast->empty_bins, rast->curr_bins ); + rast->curr_bins = NULL; + } + pipe_mutex_unlock( rast->get_bin_mutex ); +} + + /** * Begin the rasterization phase. @@ -488,6 +528,7 @@ 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(). + * Called per thread. */ static void rasterize_bin( struct lp_rasterizer *rast, @@ -514,6 +555,7 @@ rasterize_bin( struct lp_rasterizer *rast, /** * Rasterize/execute all bins. + * Called per thread. */ static void rasterize_bins( struct lp_rasterizer *rast, @@ -539,6 +581,7 @@ rasterize_bins( struct lp_rasterizer *rast, struct cmd_bin *bin; int x, y; + assert(bins); while ((bin = lp_bin_iter_next(bins, &x, &y))) { rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); } @@ -593,11 +636,13 @@ lp_rasterize_bins( struct lp_rasterizer *rast, /* threaded rendering! */ unsigned i; - rast->bins = bins; + lp_bins_enqueue( rast->full_bins, bins ); + + /* XXX need to move/fix these */ rast->fb = fb; rast->write_depth = write_depth; - lp_bin_iter_begin( bins ); + /*lp_bin_iter_begin( bins );*/ /* signal the threads that there's work to do */ for (i = 0; i < rast->num_threads; i++) { @@ -608,10 +653,6 @@ 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 ); @@ -632,19 +673,26 @@ thread_func( void *init_data ) { struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; struct lp_rasterizer *rast = task->rast; - int debug = 0; + boolean debug = false; while (1) { + struct lp_bins *bins; + /* wait for work */ if (debug) debug_printf("thread %d waiting for work\n", task->thread_index); pipe_semaphore_wait(&task->work_ready); + bins = get_next_full_bin( rast ); + assert(bins); + /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); rasterize_bins(rast, task->thread_index, - rast->bins, rast->fb, rast->write_depth); + bins, rast->fb, rast->write_depth); + + release_current_bin( rast ); /* signal done with work */ if (debug) diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 4e4f8b36a7..f174aa1505 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -95,10 +95,18 @@ struct lp_rasterizer boolean clipped_tile; boolean check_for_clipped_tiles; + /** 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; + pipe_mutex get_bin_mutex; + /** The bins currently being rasterized by the threads */ + struct lp_bins *curr_bins; + /** Counter to determine when all threads are done with current bin */ + unsigned release_count; + /* Framebuffer stuff */ struct pipe_screen *screen; -- cgit v1.2.3 From 4e67f10331bfd87560e2900e66f3b942902bc65c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 11:16:48 -0700 Subject: llvmpipe: minor comment fix --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 0cd95e0ca7..2c9c13ab22 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -591,7 +591,7 @@ rasterize_bins( struct lp_rasterizer *rast, /** - * Called by rasterizer when it has something for us to render. + * Called by setup module when it has something for us to render. */ void lp_rasterize_bins( struct lp_rasterizer *rast, -- cgit v1.2.3 From 205da96fc64a197b7d1a15010456402030d8893b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 11:25:22 -0700 Subject: llvmpipe: remove unused fb parameter --- src/gallium/drivers/llvmpipe/lp_rast.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2c9c13ab22..7083029e45 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -561,7 +561,6 @@ static void rasterize_bins( struct lp_rasterizer *rast, unsigned thread_index, struct lp_bins *bins, - const struct pipe_framebuffer_state *fb, bool write_depth ) { /* loop over tile bins, rasterize each */ @@ -626,7 +625,7 @@ lp_rasterize_bins( struct lp_rasterizer *rast, if (rast->num_threads == 0) { /* no threading */ lp_bin_iter_begin( bins ); - rasterize_bins( rast, 0, bins, fb, write_depth ); + rasterize_bins( rast, 0, bins, write_depth ); /* reset bins and put into the empty queue */ lp_reset_bins( bins ); @@ -690,7 +689,7 @@ thread_func( void *init_data ) if (debug) debug_printf("thread %d doing work\n", task->thread_index); rasterize_bins(rast, task->thread_index, - bins, rast->fb, rast->write_depth); + bins, rast->write_depth); release_current_bin( rast ); -- cgit v1.2.3 From 156eabbaf996f471458ee2a69078674277b89067 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 11:46:23 -0700 Subject: llvmpipe: improve framebuffer/surface code --- src/gallium/drivers/llvmpipe/lp_rast.c | 70 ++++++++++++++--------------- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 5 +-- 2 files changed, 34 insertions(+), 41 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 7083029e45..97233e1700 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -28,6 +28,7 @@ #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_cpu_detect.h" +#include "util/u_surface.h" #include "lp_bin_queue.h" #include "lp_debug.h" @@ -87,28 +88,25 @@ release_current_bin( struct lp_rasterizer *rast ) */ static 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 ) + const struct pipe_framebuffer_state *fb, + boolean write_color, + boolean write_zstencil ) { struct pipe_screen *screen = rast->screen; + struct pipe_surface *cbuf, *zsbuf; - LP_DBG(DEBUG_RAST, "%s %dx%d\n", __FUNCTION__, width, height); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); - pipe_surface_reference(&rast->state.cbuf, cbuf); - pipe_surface_reference(&rast->state.zsbuf, zsbuf); + util_copy_framebuffer_state(&rast->state.fb, fb); - rast->width = width; - rast->height = height; rast->state.write_zstencil = write_zstencil; rast->state.write_color = write_color; - rast->check_for_clipped_tiles = (width % TILE_SIZE != 0 || - height % TILE_SIZE != 0); + 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, @@ -116,7 +114,8 @@ lp_rast_begin( struct lp_rasterizer *rast, cbuf->level, cbuf->zslice, PIPE_TRANSFER_READ_WRITE, - 0, 0, width, height); + 0, 0, + fb->width, fb->height); if (!rast->cbuf_transfer) return FALSE; @@ -126,14 +125,16 @@ lp_rast_begin( struct lp_rasterizer *rast, return FALSE; } + zsbuf = rast->state.fb.zsbuf; if (zsbuf) { rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen, - zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, width, height); + zsbuf->texture, + zsbuf->face, + zsbuf->level, + zsbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, + fb->width, fb->height); if (!rast->zsbuf_transfer) return FALSE; @@ -442,11 +443,11 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, int w = TILE_SIZE; int h = TILE_SIZE; - if (x + w > rast->width) - w -= x + w - rast->width; + if (x + w > rast->state.fb.width) + w -= x + w - rast->state.fb.width; - if (y + h > rast->height) - h -= y + h - rast->height; + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; assert(w >= 0); assert(h >= 0); @@ -491,11 +492,11 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast, unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; - if (x + w > rast->width) - w -= x + w - rast->width; + if (x + w > rast->state.fb.width) + w -= x + w - rast->state.fb.width; - if (y + h > rast->height) - h -= y + h - rast->height; + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); @@ -614,13 +615,9 @@ lp_rasterize_bins( struct lp_rasterizer *rast, } } - lp_rast_begin( rast, - fb->cbufs[0], - fb->zsbuf, - fb->cbufs[0] != NULL, - fb->zsbuf != NULL && write_depth, - fb->width, - fb->height ); + lp_rast_begin( rast, fb, + fb->cbufs[0]!= NULL, + fb->zsbuf != NULL && write_depth ); if (rast->num_threads == 0) { /* no threading */ @@ -765,8 +762,7 @@ void lp_rast_destroy( struct lp_rasterizer *rast ) { unsigned i; - pipe_surface_reference(&rast->state.cbuf, NULL); - pipe_surface_reference(&rast->state.zsbuf, NULL); + util_unreference_framebuffer_state(&rast->state.fb); for (i = 0; i < Elements(rast->tasks); i++) { align_free(rast->tasks[i].tile.depth); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index f174aa1505..abe791fd00 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -90,8 +90,6 @@ struct lp_rasterizer_task */ struct lp_rasterizer { - unsigned width, height; /**< Size of framebuffer, in pixels */ - boolean clipped_tile; boolean check_for_clipped_tiles; @@ -116,8 +114,7 @@ struct lp_rasterizer void *zsbuf_map; struct { - struct pipe_surface *cbuf; - struct pipe_surface *zsbuf; + struct pipe_framebuffer_state fb; boolean write_color; boolean write_zstencil; unsigned clear_color; -- cgit v1.2.3 From de31b0e60c4b68b73b8983a0ae3e8f3f61d9d583 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 11:56:22 -0700 Subject: llvmpipe: remove unused lp_rasterizer::fb field --- src/gallium/drivers/llvmpipe/lp_rast.c | 1 - src/gallium/drivers/llvmpipe/lp_rast_priv.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 97233e1700..a8212d74e3 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -635,7 +635,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast, lp_bins_enqueue( rast->full_bins, bins ); /* XXX need to move/fix these */ - rast->fb = fb; rast->write_depth = write_depth; /*lp_bin_iter_begin( bins );*/ diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index abe791fd00..4ae54ac8c1 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -129,7 +129,6 @@ struct lp_rasterizer pipe_thread threads[MAX_THREADS]; struct lp_bins *bins; - const struct pipe_framebuffer_state *fb; boolean write_depth; }; -- cgit v1.2.3 From 2bce5c195f94e2cce8f67c6a8066b0ae408487ce Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 14:52:42 -0700 Subject: llvmpipe: checkpoint: more thread/queuing changes Now mapping/unmapping the framebuffer is done by a rasteizer thread rather than the main calling thread. --- src/gallium/drivers/llvmpipe/lp_bin.h | 5 ++ src/gallium/drivers/llvmpipe/lp_rast.c | 130 +++++++++++++++------------- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 24 +++-- 3 files changed, 84 insertions(+), 75 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h index 4394e7bda0..565dd49f68 100644 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ b/src/gallium/drivers/llvmpipe/lp_bin.h @@ -108,6 +108,11 @@ 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 diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index a8212d74e3..2ea3ac6b3b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -40,48 +40,6 @@ #include "lp_bin.h" - -/** - * Called by rasterization threads to get the next chunk of work. - * We use a lock to make sure that all the threads get the same bins. - */ -static struct lp_bins * -get_next_full_bin( struct lp_rasterizer *rast ) -{ - pipe_mutex_lock( rast->get_bin_mutex ); - if (!rast->curr_bins) { - /* this will wait until there's something in the queue */ - rast->curr_bins = lp_bins_dequeue( rast->full_bins ); - rast->release_count = 0; - - lp_bin_iter_begin( rast->curr_bins ); - } - pipe_mutex_unlock( rast->get_bin_mutex ); - return rast->curr_bins; -} - - -/** - * Called by rasterization threads after they've finished with - * the current bin. When all threads have called this, we reset - * the bin and put it into the 'empty bins' queue. - */ -static void -release_current_bin( struct lp_rasterizer *rast ) -{ - pipe_mutex_lock( rast->get_bin_mutex ); - rast->release_count++; - if (rast->release_count == rast->num_threads) { - assert(rast->curr_bins); - lp_reset_bins( rast->curr_bins ); - lp_bins_enqueue( rast->empty_bins, rast->curr_bins ); - rast->curr_bins = NULL; - } - pipe_mutex_unlock( rast->get_bin_mutex ); -} - - - /** * Begin the rasterization phase. * Map the framebuffer surfaces. Initialize the 'rast' state. @@ -525,6 +483,22 @@ lp_rast_end_tile( 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. + */ +static void +release_bins( struct lp_rasterizer *rast, + struct lp_bins *bins ) +{ + util_unreference_framebuffer_state( &bins->fb ); + + lp_reset_bins( bins ); + lp_bins_enqueue( rast->empty_bins, bins ); + rast->curr_bins = NULL; +} + + /** * Rasterize commands for a single bin. * \param x, y position of the bin's tile in the framebuffer @@ -615,18 +589,23 @@ lp_rasterize_bins( struct lp_rasterizer *rast, } } - lp_rast_begin( rast, fb, - fb->cbufs[0]!= NULL, - fb->zsbuf != NULL && write_depth ); + /* save framebuffer state in the bin */ + util_copy_framebuffer_state(&bins->fb, fb); + bins->write_depth = write_depth; if (rast->num_threads == 0) { /* no threading */ + + lp_rast_begin( rast, fb, + fb->cbufs[0]!= NULL, + fb->zsbuf != NULL && write_depth ); + lp_bin_iter_begin( bins ); rasterize_bins( rast, 0, bins, write_depth ); - /* reset bins and put into the empty queue */ - lp_reset_bins( bins ); - lp_bins_enqueue( rast->empty_bins, bins); + release_bins( rast, bins ); + + lp_rast_end( rast ); } else { /* threaded rendering! */ @@ -634,11 +613,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast, lp_bins_enqueue( rast->full_bins, bins ); - /* XXX need to move/fix these */ - rast->write_depth = write_depth; - - /*lp_bin_iter_begin( bins );*/ - /* signal the threads that there's work to do */ for (i = 0; i < rast->num_threads; i++) { pipe_semaphore_signal(&rast->tasks[i].work_ready); @@ -650,8 +624,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast, } } - lp_rast_end( rast ); - LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); } @@ -671,23 +643,53 @@ thread_func( void *init_data ) boolean debug = false; while (1) { - struct lp_bins *bins; - /* wait for work */ if (debug) debug_printf("thread %d waiting for work\n", task->thread_index); pipe_semaphore_wait(&task->work_ready); - bins = get_next_full_bin( rast ); - assert(bins); + if (task->thread_index == 0) { + /* thread[0]: + * - get next set of bins to rasterize + * - map the framebuffer surfaces + */ + const struct pipe_framebuffer_state *fb; + boolean write_depth; + + rast->curr_bins = lp_bins_dequeue( rast->full_bins ); + + lp_bin_iter_begin( rast->curr_bins ); + + fb = &rast->curr_bins->fb; + write_depth = rast->curr_bins->write_depth; + + lp_rast_begin( rast, fb, + fb->cbufs[0] != NULL, + fb->zsbuf != NULL && write_depth ); + } + + /* Wait for all threads to get here so that threads[1+] don't + * get a null rast->curr_bins 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, - bins, rast->write_depth); + rast->curr_bins, rast->curr_bins->write_depth); - release_current_bin( rast ); + /* wait for all threads to finish with this set of bins */ + pipe_barrier_wait( &rast->barrier ); + + if (task->thread_index == 0) { + /* thread[0]: + * - release the bins object + * - unmap the framebuffer surfaces + */ + release_bins( rast, rast->curr_bins ); + lp_rast_end( rast ); + } /* signal done with work */ if (debug) @@ -751,6 +753,9 @@ lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) create_rast_threads(rast); + /* for synchronizing rasterization threads */ + pipe_barrier_init( &rast->barrier, rast->num_threads ); + return rast; } @@ -768,6 +773,9 @@ void lp_rast_destroy( struct lp_rasterizer *rast ) align_free(rast->tasks[i].tile.color); } + /* for synchronizing rasterization threads */ + pipe_barrier_destroy( &rast->barrier ); + FREE(rast); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 4ae54ac8c1..ba14fc3675 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -93,18 +93,6 @@ struct lp_rasterizer boolean clipped_tile; boolean check_for_clipped_tiles; - /** 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; - - pipe_mutex get_bin_mutex; - - /** The bins currently being rasterized by the threads */ - struct lp_bins *curr_bins; - /** Counter to determine when all threads are done with current bin */ - unsigned release_count; - /* Framebuffer stuff */ struct pipe_screen *screen; @@ -122,14 +110,22 @@ 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 bins currently being rasterized by the threads */ + struct lp_bins *curr_bins; + /** A task object for each rasterization thread */ struct lp_rasterizer_task tasks[MAX_THREADS]; unsigned num_threads; pipe_thread threads[MAX_THREADS]; - struct lp_bins *bins; - boolean write_depth; + /** For synchronizing the rasterization threads */ + pipe_barrier barrier; }; -- cgit v1.2.3 From 92dc0f92b0f0fa2f3e4ba832ef2232169ce19ce8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 15:00:28 -0700 Subject: llvmpipe: implement lp_rast_load_color() --- src/gallium/drivers/llvmpipe/lp_rast.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2ea3ac6b3b..9020cf9cec 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -210,9 +210,31 @@ void lp_rast_load_color( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg) { - LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + 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; + + 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; + + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; - /* call u_tile func to load colors from surface */ + assert(w >= 0); + assert(h >= 0); + assert(w <= TILE_SIZE); + assert(h <= TILE_SIZE); + + lp_tile_read_4ub(rast->cbuf_transfer->format, + rast->tasks[thread_index].tile.color, + rast->cbuf_map, + rast->cbuf_transfer->stride, + x, y, + w, h); } -- cgit v1.2.3 From 932374073863379e9da862d6115410889f038154 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 17:45:52 -0700 Subject: llvmpipe: added lp_rast_get_num_threads() --- src/gallium/drivers/llvmpipe/lp_rast.c | 7 +++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 2 ++ 2 files changed, 9 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 9020cf9cec..6b7aa8d729 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -801,3 +801,10 @@ void lp_rast_destroy( struct lp_rasterizer *rast ) FREE(rast); } + +/** Return number of rasterization threads */ +unsigned +lp_rast_get_num_threads( struct lp_rasterizer *rast ) +{ + return rast->num_threads; +} diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 75f7b74404..785be49b70 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -133,6 +133,8 @@ struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen, 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, -- cgit v1.2.3 From 4b70af918dd9040a6987c6a55e76e49f0e3f90bf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Dec 2009 17:57:45 -0700 Subject: llvmpipe: added lp_rast_fence() bin function --- src/gallium/drivers/llvmpipe/lp_rast.c | 25 +++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_rast.h | 14 ++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6b7aa8d729..3e7b3d7ab4 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -32,6 +32,7 @@ #include "lp_bin_queue.h" #include "lp_debug.h" +#include "lp_fence.h" #include "lp_state.h" #include "lp_rast.h" #include "lp_rast_priv.h" @@ -505,6 +506,30 @@ lp_rast_end_tile( struct lp_rasterizer *rast, } +/** + * Signal on a fence. This is called during bin execution/rasterization. + * Called per thread. + */ +void lp_rast_fence( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + struct lp_fence *fence = arg.fence; + + pipe_mutex_lock( fence->mutex ); + + fence->count++; + assert(fence->count <= fence->rank); + + LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__, + fence->count, fence->rank); + + pipe_condvar_signal( fence->signalled ); + + pipe_mutex_unlock( fence->mutex ); +} + + /** * 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. diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 785be49b70..bd8f1ae1c9 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -44,6 +44,7 @@ struct lp_rasterizer; struct lp_bins; struct lp_bins_queue; +struct lp_fence; struct cmd_bin; struct pipe_screen; @@ -148,6 +149,7 @@ union lp_rast_cmd_arg { const struct lp_rast_state *set_state; uint8_t clear_color[4]; unsigned clear_zstencil; + struct lp_fence *fence; }; @@ -177,6 +179,15 @@ lp_rast_arg_state( const struct lp_rast_state *state ) return arg; } +static INLINE const union lp_rast_cmd_arg +lp_rast_arg_fence( struct lp_fence *fence ) +{ + union lp_rast_cmd_arg arg; + arg.fence = fence; + return arg; +} + + static INLINE const union lp_rast_cmd_arg lp_rast_arg_null( void ) { @@ -221,5 +232,8 @@ void lp_rast_shade_tile( struct lp_rasterizer *, unsigned thread_index, const union lp_rast_cmd_arg ); +void lp_rast_fence( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); #endif -- 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_rast.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 cdbcd96fdfe2c4d09e9b34cb083664d6b6e0558b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 15 Dec 2009 15:39:48 -0700 Subject: llvmpipe: tighten up an assertion --- src/gallium/drivers/llvmpipe/lp_rast.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index fd9cd67d85..ec87d907b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -358,8 +358,8 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, masks[1][1][1][1] = mask & (1 << (1*8+1*4+1*2+1)) ? ~0 : 0; #endif - assert((x % 2) == 0); - assert((y % 2) == 0); + assert((x % 4) == 0); + assert((y % 4) == 0); ix = x % TILE_SIZE; iy = y % TILE_SIZE; -- cgit v1.2.3 From ab9438193083b7f9a3180cb9cea45e269131048a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Dec 2009 16:02:59 -0700 Subject: llvmpipe: do final the pixel in/out triangle test in the fragment shader The test to determine which of the pixels in a 2x2 quad is now done in the fragment shader rather than in the calling C code. This is a little faster but there's a few more things to do. Note that the step[] array elements are in a different order now. Rather than being in row-major order for the 4x4 grid, they're in "quad-major" order. The setup of the step arrays is a little more complicated now. So is the course/intermediate tile test code, but some lookup tables help with that. Next steps: - early-cull 2x2 quads which are totally outside the triangle. - skip the in/out test for fully contained quads - make the in/out comparison code tighter/faster. --- src/gallium/drivers/llvmpipe/lp_jit.h | 9 +- src/gallium/drivers/llvmpipe/lp_rast.c | 76 +++------- src/gallium/drivers/llvmpipe/lp_rast.h | 11 +- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 11 +- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 222 +++++++++++++++------------- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 49 +++--- src/gallium/drivers/llvmpipe/lp_state_fs.c | 144 ++++++++++++++++-- 7 files changed, 302 insertions(+), 220 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 7eccb5da85..e8fb7d990f 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -114,9 +114,14 @@ typedef void const void *a0, const void *dadx, const void *dady, - const uint32_t *mask, void *color, - void *depth); + void *depth, + const int32_t c1, + const int32_t c2, + const int32_t c3, + const int32_t *step1, + const int32_t *step2, + const int32_t *step3); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index ec87d907b8..b1bd27d340 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_cpu_detect.h" @@ -279,6 +280,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_MAX/2, c2 = INT_MAX/2, c3 = INT_MAX/2; 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; @@ -296,7 +299,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, inputs, tile_x + x, tile_y + y, - mask); + c1, c2, c3); } @@ -308,58 +311,25 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned thread_index, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - unsigned mask) + int32_t c1, int32_t c2, int32_t c3) { -#if 1 const struct lp_rast_state *state = rast->tasks[thread_index].current_state; struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; void *color; void *depth; - uint32_t ALIGN16_ATTRIB masks[2][2][2][2]; unsigned ix, iy; int block_offset; +#ifdef DEBUG assert(state); /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); - /* mask: the rasterizer wants to treat pixels in 4x4 blocks, but - * the pixel shader wants to swizzle them into 4 2x2 quads. - * - * Additionally, the pixel shader wants masks as full dword ~0, - * while the rasterizer wants to pack per-pixel bits tightly. - */ -#if 0 - unsigned qx, qy; - for (qy = 0; qy < 2; ++qy) - for (qx = 0; qx < 2; ++qx) - for (iy = 0; iy < 2; ++iy) - for (ix = 0; ix < 2; ++ix) - masks[qy][qx][iy][ix] = mask & (1 << (qy*8+iy*4+qx*2+ix)) ? ~0 : 0; -#else - masks[0][0][0][0] = mask & (1 << (0*8+0*4+0*2+0)) ? ~0 : 0; - masks[0][0][0][1] = mask & (1 << (0*8+0*4+0*2+1)) ? ~0 : 0; - masks[0][0][1][0] = mask & (1 << (0*8+1*4+0*2+0)) ? ~0 : 0; - masks[0][0][1][1] = mask & (1 << (0*8+1*4+0*2+1)) ? ~0 : 0; - masks[0][1][0][0] = mask & (1 << (0*8+0*4+1*2+0)) ? ~0 : 0; - masks[0][1][0][1] = mask & (1 << (0*8+0*4+1*2+1)) ? ~0 : 0; - masks[0][1][1][0] = mask & (1 << (0*8+1*4+1*2+0)) ? ~0 : 0; - masks[0][1][1][1] = mask & (1 << (0*8+1*4+1*2+1)) ? ~0 : 0; - - masks[1][0][0][0] = mask & (1 << (1*8+0*4+0*2+0)) ? ~0 : 0; - masks[1][0][0][1] = mask & (1 << (1*8+0*4+0*2+1)) ? ~0 : 0; - masks[1][0][1][0] = mask & (1 << (1*8+1*4+0*2+0)) ? ~0 : 0; - masks[1][0][1][1] = mask & (1 << (1*8+1*4+0*2+1)) ? ~0 : 0; - masks[1][1][0][0] = mask & (1 << (1*8+0*4+1*2+0)) ? ~0 : 0; - masks[1][1][0][1] = mask & (1 << (1*8+0*4+1*2+1)) ? ~0 : 0; - masks[1][1][1][0] = mask & (1 << (1*8+1*4+1*2+0)) ? ~0 : 0; - masks[1][1][1][1] = mask & (1 << (1*8+1*4+1*2+1)) ? ~0 : 0; -#endif - assert((x % 4) == 0); assert((y % 4) == 0); +#endif ix = x % TILE_SIZE; iy = y % TILE_SIZE; @@ -373,39 +343,27 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, /* depth buffer */ depth = tile->depth + block_offset; - /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ - assert(lp_check_alignment(masks, 16)); - +#ifdef DEBUG assert(lp_check_alignment(depth, 16)); assert(lp_check_alignment(color, 16)); assert(lp_check_alignment(state->jit_context.blend_color, 16)); + assert(lp_check_alignment(inputs->step[0], 16)); + assert(lp_check_alignment(inputs->step[1], 16)); + assert(lp_check_alignment(inputs->step[2], 16)); +#endif + /* run shader */ state->jit_function( &state->jit_context, x, y, inputs->a0, inputs->dadx, inputs->dady, - &masks[0][0][0][0], color, - depth); -#else - struct lp_rast_tile *tile = &rast->tile; - unsigned chan_index; - unsigned q, ix, iy; - - x %= TILE_SIZE; - y %= TILE_SIZE; - - /* mask */ - for (q = 0; q < 4; ++q) - for(iy = 0; iy < 2; ++iy) - for(ix = 0; ix < 2; ++ix) - if(masks[q] & (1 << (iy*2 + ix))) - for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) - TILE_PIXEL(tile->color, x + q*2 + ix, y + iy, chan_index) = 0xff; - -#endif + depth, + c1, c2, c3, + inputs->step[0], inputs->step[1], inputs->step[2] + ); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 2dd0193d8d..46e22f69a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -80,6 +80,9 @@ struct lp_rast_shader_inputs { float (*a0)[4]; float (*dadx)[4]; float (*dady)[4]; + + /* edge/step info for 3 edges and 4x4 block of pixels */ + int ALIGN16_ATTRIB step[3][16]; }; @@ -117,14 +120,10 @@ struct lp_rast_triangle { int dx31; /* edge function values at minx,miny ?? */ - int c1; - int c2; - int c3; - - int step[3][16]; + int c1, c2, c3; /* inputs for the shader */ - struct lp_rast_shader_inputs inputs; + struct lp_rast_shader_inputs ALIGN16_ATTRIB inputs; }; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 79a90f6610..cd72d7e69d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -61,15 +61,6 @@ struct lp_rasterizer_task unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */ - /* Pixel blocks produced during rasterization - */ - unsigned nr_blocks; - struct { - unsigned x; - unsigned y; - unsigned mask; - } blocks[256]; - const struct lp_rast_state *current_state; /** "back" pointer */ @@ -133,6 +124,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned thread_index, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, - unsigned masks); + int32_t c1, int32_t c2, int32_t c3); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 6c96010c52..9b1861223a 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -29,6 +29,7 @@ * Rasterization for binned triangles within a tile */ +#include #include "util/u_math.h" #include "lp_debug.h" #include "lp_rast_priv.h" @@ -36,42 +37,89 @@ /** - * Add a 4x4 block of pixels to the block list. - * All pixels are known to be inside the triangle's bounds. + * Map an index in [0,15] to an x,y position, multiplied by 4. + * This is used to get the position of each subtile in a 4x4 + * grid of edge step values. + */ +static const int pos_table4[16][2] = { + { 0, 0 }, + { 4, 0 }, + { 0, 4 }, + { 4, 4 }, + { 8, 0 }, + { 12, 0 }, + { 8, 4 }, + { 12, 4 }, + { 0, 8 }, + { 4, 8 }, + { 0, 12 }, + { 4, 12 }, + { 8, 8 }, + { 12, 8 }, + { 8, 12 }, + { 12, 12 } +}; + + +static const int pos_table16[16][2] = { + { 0, 0 }, + { 16, 0 }, + { 0, 16 }, + { 16, 16 }, + { 32, 0 }, + { 48, 0 }, + { 32, 16 }, + { 48, 16 }, + { 0, 32 }, + { 16, 32 }, + { 0, 48 }, + { 16, 48 }, + { 32, 32 }, + { 48, 32 }, + { 32, 48 }, + { 48, 48 } +}; + + +/** + * Shade all pixels in a 4x4 block. */ static void -block_full_4( struct lp_rasterizer_task *rast_task, int x, int y ) +block_full_4( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y ) { - const unsigned i = rast_task->nr_blocks; - assert(x % 4 == 0); - assert(y % 4 == 0); - rast_task->blocks[i].x = x; - rast_task->blocks[i].y = y; - rast_task->blocks[i].mask = ~0; - rast_task->nr_blocks++; + /* Set c1,c2,c3 to large values so the in/out test always passes */ + const int32_t c1 = INT_MAX/2, c2 = INT_MAX/2, c3 = INT_MAX/2; + lp_rast_shade_quads(rast_task->rast, + rast_task->thread_index, + &tri->inputs, + x, y, + c1, c2, c3); } /** - * Add a 16x16 block of pixels to the block list. - * All pixels are known to be inside the triangle's bounds. + * Shade all pixels in a 16x16 block. */ static void -block_full_16( struct lp_rasterizer_task *rast_task, int x, int y ) +block_full_16( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y ) { unsigned ix, iy; assert(x % 16 == 0); assert(y % 16 == 0); for (iy = 0; iy < 16; iy += 4) for (ix = 0; ix < 16; ix += 4) - block_full_4(rast_task, x + ix, y + iy); + block_full_4(rast_task, tri, x + ix, y + iy); } /** - * Evaluate each pixel in a 4x4 block to determine if it lies within - * the triangle's bounds. - * Generate a mask of in/out flags and add the block to the blocks list. + * Pass the 4x4 pixel block to the shader function. + * Determination of which of the 16 pixels lies inside the triangle + * will be done as part of the fragment shader. */ static void do_block_4( struct lp_rasterizer_task *rast_task, @@ -81,28 +129,11 @@ do_block_4( struct lp_rasterizer_task *rast_task, int c2, int c3 ) { - int i; - unsigned mask = 0; - - assert(x % 4 == 0); - assert(y % 4 == 0); - - for (i = 0; i < 16; i++) { - int any_negative = ((c1 + tri->step[0][i]) | - (c2 + tri->step[1][i]) | - (c3 + tri->step[2][i])) >> 31; - mask |= (~any_negative) & (1 << i); - } - - /* As we do trivial reject already, masks should rarely be all zero: - */ - if (mask) { - const unsigned i = rast_task->nr_blocks; - rast_task->blocks[i].x = x; - rast_task->blocks[i].y = y; - rast_task->blocks[i].mask = mask; - rast_task->nr_blocks++; - } + lp_rast_shade_quads(rast_task->rast, + rast_task->thread_index, + &tri->inputs, + x, y, + c1, c2, c3); } @@ -118,40 +149,42 @@ do_block_16( struct lp_rasterizer_task *rast_task, int c2, int c3 ) { - int ix, iy, i = 0; + const int ei1 = tri->ei1 * 4; + const int ei2 = tri->ei2 * 4; + const int ei3 = tri->ei3 * 4; - int ei1 = tri->ei1 * 4; - int ei2 = tri->ei2 * 4; - int ei3 = tri->ei3 * 4; + const int eo1 = tri->eo1 * 4; + const int eo2 = tri->eo2 * 4; + const int eo3 = tri->eo3 * 4; - int eo1 = tri->eo1 * 4; - int eo2 = tri->eo2 * 4; - int eo3 = tri->eo3 * 4; + int i; assert(x % 16 == 0); assert(y % 16 == 0); - for (iy = 0; iy < 16; iy+=4) { - for (ix = 0; ix < 16; ix+=4, i++) { - int cx1 = c1 + (tri->step[0][i] * 4); - int cx2 = c2 + (tri->step[1][i] * 4); - int cx3 = c3 + (tri->step[2][i] * 4); - - if (cx1 + eo1 < 0 || - cx2 + eo2 < 0 || - cx3 + eo3 < 0) { - /* the block is completely outside the triangle - nop */ - } - else if (cx1 + ei1 > 0 && - cx2 + ei2 > 0 && - cx3 + ei3 > 0) { + for (i = 0; i < 16; i++) { + int cx1 = c1 + (tri->inputs.step[0][i] * 4); + int cx2 = c2 + (tri->inputs.step[1][i] * 4); + int cx3 = c3 + (tri->inputs.step[2][i] * 4); + + if (cx1 + eo1 < 0 || + cx2 + eo2 < 0 || + cx3 + eo3 < 0) { + /* the block is completely outside the triangle - nop */ + } + else { + int px = x + pos_table4[i][0]; + int py = y + pos_table4[i][1]; + if (cx1 + ei1 > 0 && + cx2 + ei2 > 0 && + cx3 + ei3 > 0) { /* the block is completely inside the triangle */ - block_full_4(rast_task, x+ix, y+iy); - } - else { + block_full_4(rast_task, tri, px, py); + } + else { /* the block is partially in/out of the triangle */ - do_block_4(rast_task, tri, x+ix, y+iy, cx1, cx2, cx3); - } + do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); + } } } } @@ -171,8 +204,7 @@ lp_rast_triangle( struct lp_rasterizer *rast, int x = rast_task->x; int y = rast_task->y; - int ix, iy; - unsigned i = 0; + unsigned i; int c1 = tri->c1 + tri->dx12 * y - tri->dy12 * x; int c2 = tri->c2 + tri->dx23 * y - tri->dy23 * x; @@ -186,48 +218,36 @@ lp_rast_triangle( struct lp_rasterizer *rast, int eo2 = tri->eo2 * 16; int eo3 = tri->eo3 * 16; - assert(Elements(rast_task->blocks) == (TILE_SIZE * TILE_SIZE) / (4*4)); - LP_DBG(DEBUG_RAST, "lp_rast_triangle\n"); - rast_task->nr_blocks = 0; - /* Walk over the tile to build a list of 4x4 pixel blocks which will * be filled/shaded. We do this at two granularities: 16x16 blocks * and then 4x4 blocks. */ - for (iy = 0; iy < TILE_SIZE; iy += 16) { - for (ix = 0; ix < TILE_SIZE; ix += 16, i++) { - int cx1 = c1 + (tri->step[0][i] * 16); - int cx2 = c2 + (tri->step[1][i] * 16); - int cx3 = c3 + (tri->step[2][i] * 16); - - if (cx1 + eo1 < 0 || - cx2 + eo2 < 0 || - cx3 + eo3 < 0) { - /* the block is completely outside the triangle - nop */ - } - else if (cx1 + ei1 > 0 && - cx2 + ei2 > 0 && - cx3 + ei3 > 0) { + for (i = 0; i < 16; i++) { + int cx1 = c1 + (tri->inputs.step[0][i] * 16); + int cx2 = c2 + (tri->inputs.step[1][i] * 16); + int cx3 = c3 + (tri->inputs.step[2][i] * 16); + + if (cx1 + eo1 < 0 || + cx2 + eo2 < 0 || + cx3 + eo3 < 0) { + /* the block is completely outside the triangle - nop */ + } + else { + int px = x + pos_table16[i][0]; + int py = y + pos_table16[i][1]; + + if (cx1 + ei1 > 0 && + cx2 + ei2 > 0 && + cx3 + ei3 > 0) { /* the block is completely inside the triangle */ - block_full_16(rast_task, x+ix, y+iy); - } - else { + block_full_16(rast_task, tri, px, py); + } + else { /* the block is partially in/out of the triangle */ - do_block_16(rast_task, tri, x+ix, y+iy, cx1, cx2, cx3); - } + do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); + } } } - - assert(rast_task->nr_blocks <= Elements(rast_task->blocks)); - - /* Shade the 4x4 pixel blocks */ - for (i = 0; i < rast_task->nr_blocks; i++) - lp_rast_shade_quads(rast, - thread_index, - &tri->inputs, - rast_task->blocks[i].x, - rast_task->blocks[i].y, - rast_task->blocks[i].mask); } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index aeaf260af2..e15b987767 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -265,7 +265,7 @@ do_triangle_ccw(struct setup_context *setup, const int y3 = subpixel_snap(v3[0][1]); struct lp_scene *scene = lp_setup_get_current_scene(setup); - struct lp_rast_triangle *tri = lp_scene_alloc( scene, sizeof *tri ); + struct lp_rast_triangle *tri = lp_scene_alloc_aligned( scene, sizeof *tri, 16 ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -354,38 +354,29 @@ do_triangle_ccw(struct setup_context *setup, tri->ei3 = tri->dx31 - tri->dy31 - tri->eo3; { - int xstep1 = -tri->dy12; - int xstep2 = -tri->dy23; - int xstep3 = -tri->dy31; + const int xstep1 = -tri->dy12; + const int xstep2 = -tri->dy23; + const int xstep3 = -tri->dy31; - int ystep1 = tri->dx12; - int ystep2 = tri->dx23; - int ystep3 = tri->dx31; + const int ystep1 = tri->dx12; + const int ystep2 = tri->dx23; + const int ystep3 = tri->dx31; - int ix, iy; + int qx, qy, ix, iy; int i = 0; - int c1 = 0; - int c2 = 0; - int c3 = 0; - - for (iy = 0; iy < 4; iy++) { - int cx1 = c1; - int cx2 = c2; - int cx3 = c3; - - for (ix = 0; ix < 4; ix++, i++) { - tri->step[0][i] = cx1; - tri->step[1][i] = cx2; - tri->step[2][i] = cx3; - cx1 += xstep1; - cx2 += xstep2; - cx3 += xstep3; - } - - c1 += ystep1; - c2 += ystep2; - c3 += ystep3; + for (qy = 0; qy < 2; qy++) { + for (qx = 0; qx < 2; qx++) { + for (iy = 0; iy < 2; iy++) { + for (ix = 0; ix < 2; ix++, i++) { + int x = qx * 2 + ix; + int y = qy * 2 + iy; + tri->inputs.step[0][i] = x * xstep1 + y * ystep1; + tri->inputs.step[1][i] = x * xstep2 + y * ystep2; + tri->inputs.step[2][i] = x * xstep3 + y * ystep3; + } + } + } } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index c0d5a70a55..4af37e365e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -175,8 +175,93 @@ generate_depth(LLVMBuilderRef builder, } +/** + * Generate the code to do inside/outside triangle testing for the + * four pixels in a 2x2 quad. This will set the four elements of the + * quad mask vector to 0 or ~0. + * \param i which quad of the quad group to test, in [0,3] + */ +static void +generate_tri_edge_mask(LLVMBuilderRef builder, + unsigned i, + LLVMValueRef *mask, /* ivec4, out */ + LLVMValueRef c0, /* int32 */ + LLVMValueRef c1, /* int32 */ + LLVMValueRef c2, /* int32 */ + LLVMValueRef step0_ptr, /* ivec4 */ + LLVMValueRef step1_ptr, /* ivec4 */ + LLVMValueRef step2_ptr) /* ivec4 */ +{ + /* + c0_vec = splat(c0) + c1_vec = splat(c1) + c2_vec = splat(c2) + s0_vec = c0_vec + step0_ptr[i] + s1_vec = c1_vec + step1_ptr[i] + s2_vec = c2_vec + step2_ptr[i] + m0_vec = s0_vec > {0,0,0,0} + m1_vec = s1_vec > {0,0,0,0} + m2_vec = s2_vec > {0,0,0,0} + mask = m0_vec & m1_vec & m2_vec + */ + struct lp_type i32_type; + LLVMTypeRef i32vec4_type; + + LLVMValueRef index; + LLVMValueRef c0_vec, c1_vec, c2_vec; + LLVMValueRef step0_vec, step1_vec, step2_vec; + LLVMValueRef m0_vec, m1_vec, m2_vec; + LLVMValueRef s0_vec, s1_vec, s2_vec; + LLVMValueRef m; + + LLVMValueRef zeros; + + assert(i < 4); + + /* int32 vector 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 */ + + i32vec4_type = lp_build_int32_vec4_type(); + + /* int32_vec4 zero = {0,0,0,0} */ + zeros = LLVMConstNull(i32vec4_type); + + c0_vec = lp_build_broadcast(builder, i32vec4_type, c0); + c1_vec = lp_build_broadcast(builder, i32vec4_type, c1); + c2_vec = lp_build_broadcast(builder, i32vec4_type, c2); + + index = LLVMConstInt(LLVMInt32Type(), i, 0); + step0_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step0_ptr, &index, 1, ""), ""); + step1_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step1_ptr, &index, 1, ""), ""); + step2_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step2_ptr, &index, 1, ""), ""); + + /** XXX with a little work, we could remove the add here and just + * compare c0_vec > step0_vec. + */ + s0_vec = LLVMBuildAdd(builder, c0_vec, step0_vec, ""); + s1_vec = LLVMBuildAdd(builder, c1_vec, step1_vec, ""); + s2_vec = LLVMBuildAdd(builder, c2_vec, step2_vec, ""); + m0_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s0_vec, zeros); + m1_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s1_vec, zeros); + m2_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s2_vec, zeros); + + m = LLVMBuildAnd(builder, m0_vec, m1_vec, ""); + m = LLVMBuildAnd(builder, m, m2_vec, ""); + + lp_build_name(m, "m"); + + *mask = m; +} + + /** * Generate the fragment shader, depth/stencil test, and alpha tests. + * \param i which quad in the tile, in range [0,3] */ static void generate_fs(struct llvmpipe_context *lp, @@ -190,7 +275,13 @@ generate_fs(struct llvmpipe_context *lp, struct lp_build_sampler_soa *sampler, LLVMValueRef *pmask, LLVMValueRef *color, - LLVMValueRef depth_ptr) + LLVMValueRef depth_ptr, + LLVMValueRef c0, + LLVMValueRef c1, + LLVMValueRef c2, + LLVMValueRef step0_ptr, + LLVMValueRef step1_ptr, + LLVMValueRef step2_ptr) { const struct tgsi_token *tokens = shader->base.tokens; LLVMTypeRef elem_type; @@ -205,6 +296,8 @@ generate_fs(struct llvmpipe_context *lp, unsigned attrib; unsigned chan; + assert(i < 4); + elem_type = lp_build_elem_type(type); vec_type = lp_build_vec_type(type); int_vec_type = lp_build_int_vec_type(type); @@ -224,8 +317,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); + lp_build_mask_begin(&mask, flow, type, *pmask); + early_depth_test = key->depth.enabled && !key->alpha.enabled && @@ -376,17 +474,18 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; LLVMTypeRef blend_int_vec_type; - LLVMTypeRef arg_types[9]; + LLVMTypeRef arg_types[14]; LLVMTypeRef func_type; + LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type(); LLVMValueRef context_ptr; LLVMValueRef x; LLVMValueRef y; LLVMValueRef a0_ptr; LLVMValueRef dadx_ptr; LLVMValueRef dady_ptr; - LLVMValueRef mask_ptr; LLVMValueRef color_ptr; LLVMValueRef depth_ptr; + LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr; LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef x0; @@ -468,9 +567,17 @@ 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(fs_int_vec_type, 0); /* mask */ - arg_types[7] = LLVMPointerType(blend_vec_type, 0); /* color */ - arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ + arg_types[6] = LLVMPointerType(blend_vec_type, 0); /* color */ + arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ + arg_types[8] = LLVMInt32Type(); /* c0 */ + arg_types[9] = LLVMInt32Type(); /* c1 */ + arg_types[10] = LLVMInt32Type(); /* c2 */ + /* Note: the step arrays are built as int32[16] but we interpret + * them here as int32_vec4[4]. + */ + arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ + arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ + arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -486,9 +593,14 @@ generate_fragment(struct llvmpipe_context *lp, a0_ptr = LLVMGetParam(variant->function, 3); dadx_ptr = LLVMGetParam(variant->function, 4); dady_ptr = LLVMGetParam(variant->function, 5); - mask_ptr = LLVMGetParam(variant->function, 6); - color_ptr = LLVMGetParam(variant->function, 7); - depth_ptr = LLVMGetParam(variant->function, 8); + color_ptr = LLVMGetParam(variant->function, 6); + depth_ptr = LLVMGetParam(variant->function, 7); + c0 = LLVMGetParam(variant->function, 8); + c1 = LLVMGetParam(variant->function, 9); + c2 = LLVMGetParam(variant->function, 10); + step0_ptr = LLVMGetParam(variant->function, 11); + step1_ptr = LLVMGetParam(variant->function, 12); + step2_ptr = LLVMGetParam(variant->function, 13); lp_build_name(context_ptr, "context"); lp_build_name(x, "x"); @@ -496,9 +608,14 @@ 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(mask_ptr, "mask"); lp_build_name(color_ptr, "color"); lp_build_name(depth_ptr, "depth"); + lp_build_name(c0, "c0"); + lp_build_name(c1, "c1"); + lp_build_name(c2, "c2"); + lp_build_name(step0_ptr, "step0"); + lp_build_name(step1_ptr, "step1"); + lp_build_name(step2_ptr, "step2"); /* * Function body @@ -526,7 +643,6 @@ generate_fragment(struct llvmpipe_context *lp, if(i != 0) lp_build_interp_soa_update(&interp, i); - fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), ""); depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, ""); generate_fs(lp, shader, key, @@ -536,9 +652,11 @@ generate_fragment(struct llvmpipe_context *lp, i, &interp, sampler, - &fs_mask[i], + &fs_mask[i], /* output */ out_color, - depth_ptr_i); + depth_ptr_i, + c0, c1, c2, + step0_ptr, step1_ptr, step2_ptr); for(chan = 0; chan < NUM_CHANNELS; ++chan) fs_out_color[chan][i] = out_color[chan]; -- cgit v1.2.3 From b9d33db0a4cb818154b713a27834f66025b14672 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Dec 2009 17:08:13 -0700 Subject: llvmpipe: improve the in/out test a little Instead of: s = c + step m = s > 0 Do: m = step > c (with negated c) --- src/gallium/drivers/llvmpipe/lp_rast.c | 3 +-- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 4 ++-- src/gallium/drivers/llvmpipe/lp_state_fs.c | 24 ++++++------------------ 3 files changed, 9 insertions(+), 22 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index b1bd27d340..015865a6d6 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -281,11 +281,10 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, 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_MAX/2, c2 = INT_MAX/2, c3 = INT_MAX/2; + const int32_t c1 = INT_MIN/2, c2 = INT_MIN/2, c3 = INT_MIN/2; 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; - const unsigned mask = ~0; unsigned x, y; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 9b1861223a..d6e8d6d5ab 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -90,7 +90,7 @@ block_full_4( struct lp_rasterizer_task *rast_task, int x, int y ) { /* Set c1,c2,c3 to large values so the in/out test always passes */ - const int32_t c1 = INT_MAX/2, c2 = INT_MAX/2, c3 = INT_MAX/2; + const int32_t c1 = INT_MIN/2, c2 = INT_MIN/2, c3 = INT_MIN/2; lp_rast_shade_quads(rast_task->rast, rast_task->thread_index, &tri->inputs, @@ -133,7 +133,7 @@ do_block_4( struct lp_rasterizer_task *rast_task, rast_task->thread_index, &tri->inputs, x, y, - c1, c2, c3); + -c1, -c2, -c3); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 4af37e365e..15b175a2c4 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -196,12 +196,9 @@ generate_tri_edge_mask(LLVMBuilderRef builder, c0_vec = splat(c0) c1_vec = splat(c1) c2_vec = splat(c2) - s0_vec = c0_vec + step0_ptr[i] - s1_vec = c1_vec + step1_ptr[i] - s2_vec = c2_vec + step2_ptr[i] - m0_vec = s0_vec > {0,0,0,0} - m1_vec = s1_vec > {0,0,0,0} - m2_vec = s2_vec > {0,0,0,0} + m0_vec = step0_ptr[i] > c0_vec + m1_vec = step1_ptr[i] > c1_vec + m2_vec = step2_ptr[i] > c2_vec mask = m0_vec & m1_vec & m2_vec */ struct lp_type i32_type; @@ -211,7 +208,6 @@ generate_tri_edge_mask(LLVMBuilderRef builder, LLVMValueRef c0_vec, c1_vec, c2_vec; LLVMValueRef step0_vec, step1_vec, step2_vec; LLVMValueRef m0_vec, m1_vec, m2_vec; - LLVMValueRef s0_vec, s1_vec, s2_vec; LLVMValueRef m; LLVMValueRef zeros; @@ -240,21 +236,13 @@ generate_tri_edge_mask(LLVMBuilderRef builder, step1_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step1_ptr, &index, 1, ""), ""); step2_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step2_ptr, &index, 1, ""), ""); - /** XXX with a little work, we could remove the add here and just - * compare c0_vec > step0_vec. - */ - s0_vec = LLVMBuildAdd(builder, c0_vec, step0_vec, ""); - s1_vec = LLVMBuildAdd(builder, c1_vec, step1_vec, ""); - s2_vec = LLVMBuildAdd(builder, c2_vec, step2_vec, ""); - m0_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s0_vec, zeros); - m1_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s1_vec, zeros); - m2_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, s2_vec, zeros); + m0_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step0_vec, c0_vec); + m1_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step1_vec, c1_vec); + m2_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step2_vec, c2_vec); m = LLVMBuildAnd(builder, m0_vec, m1_vec, ""); m = LLVMBuildAnd(builder, m, m2_vec, ""); - lp_build_name(m, "m"); - *mask = m; } -- cgit v1.2.3 From 808170a0ff6c3a51a1b69a54ed8045b2e0f7d0d1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Dec 2009 09:00:58 -0700 Subject: llvmpipe: replace INT_MIN/2 with INT_MIN Since changing the in/out test we can just use INT_MIN to be sure the comparison against the step values always passes. --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- src/gallium/drivers/llvmpipe/lp_rast_tri.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 015865a6d6..24393c8e89 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -281,7 +281,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, 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/2, c2 = INT_MIN/2, c3 = INT_MIN/2; + const int32_t c1 = INT_MIN, c2 = INT_MIN, c3 = INT_MIN; 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; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index d6e8d6d5ab..bc7397f50c 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -90,7 +90,7 @@ block_full_4( struct lp_rasterizer_task *rast_task, int x, int y ) { /* Set c1,c2,c3 to large values so the in/out test always passes */ - const int32_t c1 = INT_MIN/2, c2 = INT_MIN/2, c3 = INT_MIN/2; + 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, -- cgit v1.2.3 From c9240c4c8f67a06403b29992ab96b9a48f68b01d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 6 Jan 2010 17:00:26 +0000 Subject: llvmpipe: remove dead code --- src/gallium/drivers/llvmpipe/lp_clear.c | 1 - src/gallium/drivers/llvmpipe/lp_context.h | 1 - src/gallium/drivers/llvmpipe/lp_flush.c | 1 - src/gallium/drivers/llvmpipe/lp_rast.c | 1 - src/gallium/drivers/llvmpipe/lp_state.h | 7 ------- src/gallium/drivers/llvmpipe/lp_state_derived.c | 16 ++++++++-------- 6 files changed, 8 insertions(+), 19 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c index 4bae44e2ea..3e8c410925 100644 --- a/src/gallium/drivers/llvmpipe/lp_clear.c +++ b/src/gallium/drivers/llvmpipe/lp_clear.c @@ -36,7 +36,6 @@ #include "lp_clear.h" #include "lp_context.h" #include "lp_setup.h" -#include "lp_state.h" /** diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index b796148457..194692045d 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -88,7 +88,6 @@ struct llvmpipe_context { /** Vertex format */ struct vertex_info vertex_info; - struct vertex_info vertex_info_vbuf; /** Which vertex shader output slot contains point size */ int psize_slot; diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index e6519cb216..9405150c4f 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -35,7 +35,6 @@ #include "lp_flush.h" #include "lp_context.h" #include "lp_surface.h" -#include "lp_state.h" #include "lp_winsys.h" #include "lp_setup.h" diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 24393c8e89..6772ff332b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -34,7 +34,6 @@ #include "lp_scene_queue.h" #include "lp_debug.h" #include "lp_fence.h" -#include "lp_state.h" #include "lp_rast.h" #include "lp_rast_priv.h" #include "lp_tile_soa.h" diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 64fe3600f5..6017dc553a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -215,11 +215,4 @@ void llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp); -struct vertex_info * -llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe); - -struct vertex_info * -llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe); - - #endif diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index ab827045ed..cc7b09fd4d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -43,29 +43,29 @@ * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * - * This function validates the vertex layout and returns a pointer to a - * vertex_info object. + * This function validates the vertex layout. */ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct lp_fragment_shader *lpfs = llvmpipe->fs; - struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf; + struct vertex_info *vinfo = &llvmpipe->vertex_info; const uint num = draw_num_vs_outputs(llvmpipe->draw); uint i; - /* Tell draw_vbuf to simply emit the whole post-xform vertex as-is. + /* Tell setup to tell the draw module to simply emit the whole + * post-xform vertex as-is. * * Not really sure if this is the best approach. */ - vinfo_vbuf->num_attribs = 0; + vinfo->num_attribs = 0; for (i = 0; i < num; i++) { - draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, i); } - draw_compute_vertex_size(vinfo_vbuf); + draw_compute_vertex_size(vinfo); - lp_setup_set_vertex_info(llvmpipe->setup, vinfo_vbuf); + lp_setup_set_vertex_info(llvmpipe->setup, vinfo); /* llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, -- 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_rast.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_rast.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 f4b29e6ad38939318ce233ad28c70a608e7db0bd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 13 Jan 2010 15:49:24 +0000 Subject: llvmpipe: improve empty-bin test We emit at most two clear packets (color and z respectively). --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 4c13d4d80b..9606418a37 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -584,7 +584,7 @@ is_empty_bin( struct lp_rasterizer *rast, int i; if (head->next != NULL || - head->count > PIPE_MAX_COLOR_BUFS + 1) + head->count > 2) return FALSE; for (i = 0; i < head->count; i++) -- cgit v1.2.3 From db83ad4b4353ea6f9c755f18bf1455ea78b5bf12 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 13 Jan 2010 16:29:39 +0000 Subject: llvmpipe: improve empty-bin test further Remove unused param, add comments. Thanks to Brian for review. --- src/gallium/drivers/llvmpipe/lp_rast.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 9606418a37..0a8d730580 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -576,13 +576,23 @@ rasterize_bin( struct lp_rasterizer *rast, lp_rast_end_tile( rast, thread_index ); } +/* An empty bin is one that just loads the contents of the tile and + * stores them again unchanged. This typically happens when bins have + * been flushed for some reason in the middle of a frame, or when + * incremental updates are being made to a render target. + * + * Try to avoid doing pointless work in this case. + */ static boolean -is_empty_bin( struct lp_rasterizer *rast, - const struct cmd_bin *bin ) +is_empty_bin( const struct cmd_bin *bin ) { const struct cmd_block *head = bin->commands.head; int i; + /* We emit at most two load-tile commands at the start of the first + * command block. If there are more than two commands in the + * block, we know that the bin is non-empty. + */ if (head->next != NULL || head->count > 2) return FALSE; @@ -626,7 +636,7 @@ rasterize_scene( struct lp_rasterizer *rast, assert(scene); while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { - if (!is_empty_bin( rast, bin )) + if (!is_empty_bin( bin )) rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); } } -- cgit v1.2.3 From 95ee14f147e713bd132dc56a1151232957752c90 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 13 Jan 2010 16:52:17 +0000 Subject: llvmpipe: implement lp_rast_load_zstencil Load zbuffer contents for binned scenes that don't start with a clear and which have a bound zbuffer. --- src/gallium/drivers/llvmpipe/lp_rast.c | 36 ++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 0a8d730580..7753f9bb3f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -269,6 +269,23 @@ void lp_rast_load_color( struct lp_rasterizer *rast, } +static void +lp_tile_read_z32(uint32_t *tile, + const uint8_t *map, + unsigned map_stride, + unsigned x0, unsigned y0, unsigned w, unsigned h) +{ + unsigned x, y; + const uint8_t *map_row = map + y0*map_stride; + for (y = 0; y < h; ++y) { + const uint32_t *map_pixel = (uint32_t *)(map_row + x0*4); + for (x = 0; x < w; ++x) { + *tile++ = *map_pixel++; + } + map_row += map_stride; + } +} + /** * Load tile z/stencil from the framebuffer surface. * This is a bin command called during bin processing. @@ -277,9 +294,24 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg ) { - LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + const unsigned x = rast->tasks[thread_index].x; + const unsigned y = rast->tasks[thread_index].y; + unsigned w = TILE_SIZE; + unsigned h = TILE_SIZE; + + if (x + w > rast->state.fb.width) + w -= x + w - rast->state.fb.width; - /* call u_tile func to load depth (and stencil?) from surface */ + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; + + LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); + lp_tile_read_z32(rast->tasks[thread_index].tile.depth, + rast->zsbuf_map, + rast->zsbuf_transfer->stride, + x, y, w, h); } -- cgit v1.2.3 From 4231006e29cbf9fb54c72acf35009f3b18fe62ab Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 13 Jan 2010 20:14:04 +0000 Subject: llvmpipe: add bin debugger Adjust definition of empty_bin according to what's actually in empty bins. We often have a state packet before/after load commands. Still need to do something about the fence packets. --- src/gallium/drivers/llvmpipe/lp_rast.c | 57 +++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 7753f9bb3f..6c7ece9fdb 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -608,6 +608,44 @@ rasterize_bin( struct lp_rasterizer *rast, lp_rast_end_tile( rast, thread_index ); } + +#define RAST(x) { lp_rast_##x, #x } + +static struct { + lp_rast_cmd cmd; + const char *name; +} cmd_names[] = +{ + RAST(load_color), + RAST(load_zstencil), + RAST(clear_color), + RAST(clear_zstencil), + RAST(triangle), + RAST(shade_tile), + RAST(set_state), + RAST(fence), +}; + +static void +debug_bin( const struct cmd_bin *bin ) +{ + const struct cmd_block *head = bin->commands.head; + int i, j; + + for (i = 0; i < head->count; i++) { + debug_printf("%d: ", i); + for (j = 0; j < Elements(cmd_names); j++) { + if (head->cmd[i] == cmd_names[j].cmd) { + debug_printf("%s\n", cmd_names[j].name); + break; + } + } + if (j == Elements(cmd_names)) + debug_printf("...other\n"); + } + +} + /* An empty bin is one that just loads the contents of the tile and * stores them again unchanged. This typically happens when bins have * been flushed for some reason in the middle of a frame, or when @@ -620,19 +658,28 @@ is_empty_bin( const struct cmd_bin *bin ) { const struct cmd_block *head = bin->commands.head; int i; - + + if (0) + debug_bin(bin); + /* We emit at most two load-tile commands at the start of the first - * command block. If there are more than two commands in the - * block, we know that the bin is non-empty. + * command block. In addition we seem to emit a couple of + * set-state commands even in empty bins. + * + * As a heuristic, if a bin has more than 4 commands, consider it + * non-empty. */ if (head->next != NULL || - head->count > 2) + head->count > 4) { return FALSE; + } for (i = 0; i < head->count; i++) if (head->cmd[i] != lp_rast_load_color && - head->cmd[i] != lp_rast_load_zstencil) + head->cmd[i] != lp_rast_load_zstencil && + head->cmd[i] != lp_rast_set_state) { return FALSE; + } return TRUE; } -- cgit v1.2.3 From f94a99170ecdc3286408b3628fbae9f45518007e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 18:54:48 -0700 Subject: llvmpipe: optimize lp_rast_clear_color() for non-gray colors This makes a big difference in progs that clear to a non-gray color. Some demos are 30-50% faster. --- src/gallium/drivers/llvmpipe/lp_rast.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6c7ece9fdb..3849116758 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -187,17 +187,33 @@ 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]) { + /* clear to grayscale value {x, x, x, x} */ 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 (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]; + /* Non-gray color. + * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code + * will need to change. It'll be pretty obvious when clearing no longer + * works. + */ + const unsigned chunk = TILE_SIZE / 4; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + uint8_t *c = color_tile[i]; + unsigned j; + for (j = 0; j < 4 * TILE_SIZE; j++) { + memset(c, clear_color[0], chunk); + c += chunk; + memset(c, clear_color[1], chunk); + c += chunk; + memset(c, clear_color[2], chunk); + c += chunk; + memset(c, clear_color[3], chunk); + c += chunk; + } + assert(c - color_tile[i] == TILE_SIZE * TILE_SIZE * 4); + } } } -- cgit v1.2.3 From 2ba1c8189a124932b7b35115caf8f442bf4a7125 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Jan 2010 18:58:38 -0700 Subject: llvmpipe: use one loop in lp_rast_clear_zstencil() This is just a tiny bit faster. --- src/gallium/drivers/llvmpipe/lp_rast.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3849116758..75562bf62d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -226,14 +226,13 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg) { - unsigned i, j; + unsigned i; uint32_t *depth_tile = rast->tasks[thread_index].tile.depth; 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++) - depth_tile[i*TILE_SIZE + j] = arg.clear_zstencil; + for (i = 0; i < TILE_SIZE * TILE_SIZE; i++) + depth_tile[i] = arg.clear_zstencil; } -- 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_rast.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 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_rast.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 62623c4dc5d8b646942bc65e8de350e812945ad1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 18 Jan 2010 13:10:10 -0700 Subject: llvmpipe: added show_tiles and show_subtiles debug options These options draw lines over the tiles to show the 64x64 tile bounds and 16x16 sub-tile bounds. For debugging/visualization. --- src/gallium/drivers/llvmpipe/lp_debug.h | 3 ++ src/gallium/drivers/llvmpipe/lp_rast.c | 60 ++++++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_screen.c | 2 ++ 3 files changed, 65 insertions(+) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h index 74b2757494..7128e8eb4b 100644 --- a/src/gallium/drivers/llvmpipe/lp_debug.h +++ b/src/gallium/drivers/llvmpipe/lp_debug.h @@ -45,6 +45,9 @@ st_print_current(void); #define DEBUG_QUERY 0x40 #define DEBUG_SCREEN 0x80 #define DEBUG_JIT 0x100 +#define DEBUG_SHOW_TILES 0x200 +#define DEBUG_SHOW_SUBTILES 0x400 + #ifdef DEBUG extern int LP_DEBUG; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 2e2ebee45d..440bb32235 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -461,6 +461,61 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, } +#ifdef DEBUG +/** + * Set top row and left column of the tile's pixels to white. For debugging. + */ +static void +outline_tile(uint8_t *tile) +{ + const uint8_t val = 0xff; + unsigned i; + + for (i = 0; i < TILE_SIZE; i++) { + TILE_PIXEL(tile, i, 0, 0) = val; + TILE_PIXEL(tile, i, 0, 1) = val; + TILE_PIXEL(tile, i, 0, 2) = val; + TILE_PIXEL(tile, i, 0, 3) = val; + + TILE_PIXEL(tile, 0, i, 0) = val; + TILE_PIXEL(tile, 0, i, 1) = val; + TILE_PIXEL(tile, 0, i, 2) = val; + TILE_PIXEL(tile, 0, i, 3) = val; + } +} +#endif /* DEBUG */ + + +#ifdef DEBUG +/** + * Draw grid of gray lines at 16-pixel intervals across the tile to + * show the sub-tile boundaries. For debugging. + */ +static void +outline_subtiles(uint8_t *tile) +{ + const uint8_t val = 0x80; + const unsigned step = 16; + unsigned i, j; + + for (i = 0; i < TILE_SIZE; i += 16) { + for (j = 0; j < TILE_SIZE; j++) { + TILE_PIXEL(tile, i, j, 0) = val; + TILE_PIXEL(tile, i, j, 1) = val; + TILE_PIXEL(tile, i, j, 2) = val; + TILE_PIXEL(tile, i, j, 3) = val; + + TILE_PIXEL(tile, j, i, 0) = val; + TILE_PIXEL(tile, j, i, 1) = val; + TILE_PIXEL(tile, j, i, 2) = val; + TILE_PIXEL(tile, j, i, 3) = val; + } + } + + outline_tile(tile); +} +#endif /* DEBUG */ + /** @@ -500,6 +555,11 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, thread_index, x, y, w, h); + if (LP_DEBUG & DEBUG_SHOW_SUBTILES) + outline_subtiles(rast->tasks[thread_index].tile.color[i]); + else if (LP_DEBUG & DEBUG_SHOW_TILES) + outline_tile(rast->tasks[thread_index].tile.color[i]); + lp_tile_write_4ub(transfer->texture->format, rast->tasks[thread_index].tile.color[i], rast->cbuf_map[i], diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index a28f6935b6..72f2e8ebf8 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -52,6 +52,8 @@ static const struct debug_named_value lp_debug_flags[] = { { "query", DEBUG_QUERY }, { "screen", DEBUG_SCREEN }, { "jit", DEBUG_JIT }, + { "show_tiles", DEBUG_SHOW_TILES }, + { "show_subtiles", DEBUG_SHOW_SUBTILES }, {NULL, 0} }; #endif -- cgit v1.2.3 From 0fccfc9cc0cb7699598f1739d8cd3811175cdf13 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 19 Jan 2010 09:30:44 -0700 Subject: llvmpipe: remove unneeded DEBUG checks, use step var --- src/gallium/drivers/llvmpipe/lp_rast.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 440bb32235..5fe939d234 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -461,7 +461,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, } -#ifdef DEBUG /** * Set top row and left column of the tile's pixels to white. For debugging. */ @@ -483,10 +482,8 @@ outline_tile(uint8_t *tile) TILE_PIXEL(tile, 0, i, 3) = val; } } -#endif /* DEBUG */ -#ifdef DEBUG /** * Draw grid of gray lines at 16-pixel intervals across the tile to * show the sub-tile boundaries. For debugging. @@ -498,7 +495,7 @@ outline_subtiles(uint8_t *tile) const unsigned step = 16; unsigned i, j; - for (i = 0; i < TILE_SIZE; i += 16) { + for (i = 0; i < TILE_SIZE; i += step) { for (j = 0; j < TILE_SIZE; j++) { TILE_PIXEL(tile, i, j, 0) = val; TILE_PIXEL(tile, i, j, 1) = val; @@ -514,7 +511,6 @@ outline_subtiles(uint8_t *tile) outline_tile(tile); } -#endif /* DEBUG */ -- cgit v1.2.3 From ec459f2aeca39e51f495cde455ba18d0a9489caa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 19 Jan 2010 16:58:25 -0700 Subject: llvmpipe: asst. task-related clean-ups --- src/gallium/drivers/llvmpipe/lp_rast.c | 51 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 5fe939d234..05901d07aa 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -275,7 +275,7 @@ void lp_rast_load_color( struct lp_rasterizer *rast, assert(h <= TILE_SIZE); lp_tile_read_4ub(transfer->texture->format, - rast->tasks[thread_index].tile.color[i], + task->tile.color[i], rast->cbuf_map[i], transfer->stride, x, y, @@ -309,8 +309,9 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg ) { - const unsigned x = rast->tasks[thread_index].x; - const unsigned y = rast->tasks[thread_index].y; + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; @@ -323,7 +324,7 @@ void lp_rast_load_zstencil( struct lp_rasterizer *rast, LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); - lp_tile_read_z32(rast->tasks[thread_index].tile.depth, + lp_tile_read_z32(task->tile.depth, rast->zsbuf_map, rast->zsbuf_transfer->stride, x, y, w, h); @@ -353,11 +354,12 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, unsigned thread_index, const union lp_rast_cmd_arg arg ) { - const struct lp_rast_state *state = rast->tasks[thread_index].current_state; - struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const struct lp_rast_state *state = task->current_state; + struct lp_rast_tile *tile = &task->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; + const unsigned tile_x = task->x; + const unsigned tile_y = task->y; unsigned x, y; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -404,8 +406,9 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned x, unsigned y, int32_t c1, int32_t c2, int32_t c3) { - const struct lp_rast_state *state = rast->tasks[thread_index].current_state; - struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const struct lp_rast_state *state = task->current_state; + struct lp_rast_tile *tile = &task->tile; uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; unsigned i; @@ -520,8 +523,9 @@ outline_subtiles(uint8_t *tile) static void lp_rast_store_color( struct lp_rasterizer *rast, unsigned thread_index) { - const unsigned x = rast->tasks[thread_index].x; - const unsigned y = rast->tasks[thread_index].y; + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; unsigned i; for (i = 0; i < rast->state.fb.nr_cbufs; i++) { @@ -552,12 +556,12 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, thread_index, x, y, w, h); if (LP_DEBUG & DEBUG_SHOW_SUBTILES) - outline_subtiles(rast->tasks[thread_index].tile.color[i]); + outline_subtiles(task->tile.color[i]); else if (LP_DEBUG & DEBUG_SHOW_TILES) - outline_tile(rast->tasks[thread_index].tile.color[i]); + outline_tile(task->tile.color[i]); lp_tile_write_4ub(transfer->texture->format, - rast->tasks[thread_index].tile.color[i], + task->tile.color[i], rast->cbuf_map[i], transfer->stride, x, y, @@ -587,8 +591,9 @@ lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride, static void lp_rast_store_zstencil( struct lp_rasterizer *rast, unsigned thread_index ) { - const unsigned x = rast->tasks[thread_index].x; - const unsigned y = rast->tasks[thread_index].y; + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; unsigned w = TILE_SIZE; unsigned h = TILE_SIZE; @@ -601,7 +606,7 @@ static void lp_rast_store_zstencil( struct lp_rasterizer *rast, LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); - lp_tile_write_z32(rast->tasks[thread_index].tile.depth, + lp_tile_write_z32(task->tile.depth, rast->zsbuf_map, rast->zsbuf_transfer->stride, x, y, w, h); @@ -991,12 +996,14 @@ 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++) { + struct lp_rasterizer_task *task = &rast->tasks[i]; + for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) - rast->tasks[i].tile.color[cbuf] = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); + task->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; + task->tile.depth = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); + task->rast = rast; + task->thread_index = i; } create_rast_threads(rast); -- cgit v1.2.3 From 7319ae0954980196822a09d914e8b7d9cad07d16 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 20 Jan 2010 17:47:22 -0700 Subject: llvmpipe: remove tile clipping code The surface is always a multiple of the tile size now. --- src/gallium/drivers/llvmpipe/lp_rast.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 05901d07aa..e27b6528ea 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -261,13 +261,6 @@ void lp_rast_load_color( struct lp_rasterizer *rast, 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); @@ -539,19 +532,6 @@ static void lp_rast_store_color( struct lp_rasterizer *rast, 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_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, thread_index, x, y, w, h); -- cgit v1.2.3