From a6d9d18faecef9963be3e4b64a21b89889b4670d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 28 May 2010 16:54:35 +0100 Subject: [PATCH] llvmpipe: hook up basic gs and multiple constant buffer support --- src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_context.c | 7 +- src/gallium/drivers/llvmpipe/lp_context.h | 3 +- src/gallium/drivers/llvmpipe/lp_state.h | 9 ++ .../drivers/llvmpipe/lp_state_derived.c | 2 +- src/gallium/drivers/llvmpipe/lp_state_fs.c | 8 +- src/gallium/drivers/llvmpipe/lp_state_gs.c | 113 ++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_texture.c | 2 +- 8 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_state_gs.c diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 2c38dc42b09..a0646692e7b 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -54,6 +54,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_clip.c', 'lp_state_derived.c', 'lp_state_fs.c', + 'lp_state_gs.c', 'lp_state_rasterizer.c', 'lp_state_sampler.c', 'lp_state_surface.c', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 32b80d3a9f6..9e88a6e09f4 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -48,7 +48,7 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - uint i; + uint i, j; lp_print_counters(); @@ -72,8 +72,8 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) } for (i = 0; i < Elements(llvmpipe->constants); i++) { - if (llvmpipe->constants[i]) { - pipe_resource_reference(&llvmpipe->constants[i], NULL); + for (j = 0; j < Elements(llvmpipe->constants[i]); j++) { + pipe_resource_reference(&llvmpipe->constants[i][j], NULL); } } @@ -112,6 +112,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe_init_vertex_funcs(llvmpipe); llvmpipe_init_fs_funcs(llvmpipe); llvmpipe_init_vs_funcs(llvmpipe); + llvmpipe_init_gs_funcs(llvmpipe); llvmpipe_init_rasterizer_funcs(llvmpipe); llvmpipe_init_context_resource_funcs( &llvmpipe->pipe ); llvmpipe_init_surface_functions(llvmpipe); diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 689265fa30d..cb04d4a4d54 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -60,13 +60,14 @@ struct llvmpipe_context { const struct pipe_rasterizer_state *rasterizer; struct lp_fragment_shader *fs; const struct lp_vertex_shader *vs; + const struct lp_geometry_shader *gs; const struct lp_velems_state *velems; /** Other rendering state */ struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - struct pipe_resource *constants[PIPE_SHADER_TYPES]; + struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index c268f966473..3f7a85b6827 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -53,6 +53,7 @@ #define LP_NEW_VS 0x2000 #define LP_NEW_QUERY 0x4000 #define LP_NEW_BLEND_COLOR 0x8000 +#define LP_NEW_GS 0x10000 struct vertex_info; @@ -68,6 +69,11 @@ struct lp_vertex_shader struct draw_vertex_shader *draw_data; }; +/** Subclass of pipe_shader_state */ +struct lp_geometry_shader { + struct pipe_shader_state shader; + struct draw_geometry_shader *draw_data; +}; /** Vertex element state */ struct lp_velems_state @@ -108,6 +114,9 @@ llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe); void llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe); +void +llvmpipe_init_gs_funcs(struct llvmpipe_context *llvmpipe); + void llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe); diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 9e066f5c656..d20a5218d41 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -186,7 +186,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) if (llvmpipe->dirty & LP_NEW_CONSTANTS) lp_setup_set_fs_constants(llvmpipe->setup, - llvmpipe->constants[PIPE_SHADER_FRAGMENT]); + llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]); if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) lp_setup_set_fragment_sampler_views(llvmpipe->setup, diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 6896bedf189..2619e043fdf 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1078,18 +1078,18 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, const void *data = constants ? llvmpipe_resource_data(constants) : NULL; assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); + assert(index < PIPE_MAX_CONSTANT_BUFFERS); - if(llvmpipe->constants[shader] == constants) + if(llvmpipe->constants[shader][index] == constants) return; draw_flush(llvmpipe->draw); /* note: reference counting */ - pipe_resource_reference(&llvmpipe->constants[shader], constants); + pipe_resource_reference(&llvmpipe->constants[shader][index], constants); if(shader == PIPE_SHADER_VERTEX) { - draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, + draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, index, data, size); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_gs.c b/src/gallium/drivers/llvmpipe/lp_state_gs.c new file mode 100644 index 00000000000..e5eeb88e2ba --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_gs.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_texture.h" + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "draw/draw_context.h" +#include "draw/draw_vs.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_parse.h" + + +static void * +llvmpipe_create_gs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_geometry_shader *state; + + state = CALLOC_STRUCT(lp_geometry_shader); + if (state == NULL ) + goto fail; + + /* debug */ + if (0) + tgsi_dump(templ->tokens, 0); + + /* copy shader tokens, the ones passed in will go away. + */ + state->shader.tokens = tgsi_dup_tokens(templ->tokens); + if (state->shader.tokens == NULL) + goto fail; + + state->draw_data = draw_create_geometry_shader(llvmpipe->draw, templ); + if (state->draw_data == NULL) + goto fail; + + return state; + +fail: + if (state) { + FREE( (void *)state->shader.tokens ); + FREE( state->draw_data ); + FREE( state ); + } + return NULL; +} + + +static void +llvmpipe_bind_gs_state(struct pipe_context *pipe, void *gs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->gs = (struct lp_geometry_shader *)gs; + + draw_bind_geometry_shader(llvmpipe->draw, + (llvmpipe->gs ? llvmpipe->gs->draw_data : NULL)); + + llvmpipe->dirty |= LP_NEW_GS; +} + + +static void +llvmpipe_delete_gs_state(struct pipe_context *pipe, void *gs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + struct lp_geometry_shader *state = + (struct lp_geometry_shader *)gs; + + draw_delete_geometry_shader(llvmpipe->draw, + (state) ? state->draw_data : 0); + FREE(state); +} + + +void +llvmpipe_init_gs_funcs(struct llvmpipe_context *llvmpipe) +{ + llvmpipe->pipe.create_gs_state = llvmpipe_create_gs_state; + llvmpipe->pipe.bind_gs_state = llvmpipe_bind_gs_state; + llvmpipe->pipe.delete_gs_state = llvmpipe_delete_gs_state; +} diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index d86056ca34c..0d526ead89d 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -219,7 +219,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen, pipe_reference_init(&lpr->base.reference, 1); lpr->base.screen = &screen->base; - assert(lpr->base.bind); + /* assert(lpr->base.bind); */ if (resource_is_texture(&lpr->base)) { if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) { -- 2.30.2