From a1a989f0be8dc34082b52bb3b3a6eacb36d9e75e Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 28 Sep 2007 04:33:55 -0400 Subject: [PATCH] Redoing the way we handle vertex shaders for the draw module. --- src/mesa/pipe/draw/draw_context.c | 8 ---- src/mesa/pipe/draw/draw_context.h | 9 ++-- src/mesa/pipe/draw/draw_private.h | 14 ++++++- src/mesa/pipe/draw/draw_vertex_fetch.c | 2 +- src/mesa/pipe/draw/draw_vertex_shader.c | 50 +++++++++++++++++++++-- src/mesa/pipe/i915simple/i915_state.c | 44 ++++++++++++-------- src/mesa/pipe/softpipe/sp_context.c | 8 ++-- src/mesa/pipe/softpipe/sp_context.h | 8 +++- src/mesa/pipe/softpipe/sp_state.h | 14 ++++--- src/mesa/pipe/softpipe/sp_state_derived.c | 2 +- src/mesa/pipe/softpipe/sp_state_fs.c | 49 +++++++++++++++++----- src/mesa/state_tracker/st_cb_program.c | 7 ---- src/mesa/state_tracker/st_draw.c | 2 +- src/mesa/state_tracker/st_program.c | 8 ---- src/mesa/state_tracker/st_program.h | 4 -- 15 files changed, 152 insertions(+), 77 deletions(-) diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index 66c66ff698e..5efb173228f 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -155,14 +155,6 @@ void draw_set_viewport_state( struct draw_context *draw, } -void -draw_set_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader) -{ - draw_flush( draw ); - draw->vertex_shader = *shader; -} - void draw_set_vertex_buffer(struct draw_context *draw, diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 0ccf5f60466..398e96d94d2 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -92,9 +92,12 @@ void draw_set_rasterize_stage( struct draw_context *draw, struct draw_stage *stage ); -void -draw_set_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader); +void * draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader); +void draw_bind_vertex_shader(struct draw_context *draw, + void *vcso); +void draw_delete_vertex_shader(struct draw_context *draw, + void *vcso); void diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index ebef5347ab9..2f52299f74a 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -46,6 +46,7 @@ #include "draw_vertex.h" +#include "x86/rtasm/x86sse.h" /** * Basic vertex info. @@ -104,7 +105,7 @@ struct draw_stage void (*tri)( struct draw_stage *, struct prim_header * ); - + void (*end)( struct draw_stage * ); void (*reset_stipple_counter)( struct draw_stage * ); @@ -116,6 +117,15 @@ struct draw_stage #define VCACHE_OVERFLOW 4 #define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ +/** + * Private version of the compiled vertex_shader + */ +struct draw_vertex_shader { + const struct pipe_shader_state *state; +#if defined(__i386__) || defined(__386__) + struct x86_function sse2_program; +#endif +}; /** * Private context for the drawing module. @@ -145,7 +155,7 @@ struct draw_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; - struct pipe_shader_state vertex_shader; + const struct draw_vertex_shader *vertex_shader; struct pipe_vertex_buffer feedback_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element feedback_element[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/draw/draw_vertex_fetch.c b/src/mesa/pipe/draw/draw_vertex_fetch.c index 2b839d641eb..bc37e18c341 100644 --- a/src/mesa/pipe/draw/draw_vertex_fetch.c +++ b/src/mesa/pipe/draw/draw_vertex_fetch.c @@ -85,7 +85,7 @@ void draw_vertex_fetch( struct draw_context *draw, /*printf("fetch vertex %u: \n", j);*/ /* loop over vertex attributes (vertex shader inputs) */ - for (attr = 0; attr < draw->vertex_shader.num_inputs; attr++) { + for (attr = 0; attr < draw->vertex_shader->state->num_inputs; attr++) { unsigned buf = draw->vertex_element[attr].vertex_buffer_index; const void *src diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c index a2e1cdc472d..f7ddbd19093 100644 --- a/src/mesa/pipe/draw/draw_vertex_shader.c +++ b/src/mesa/pipe/draw/draw_vertex_shader.c @@ -36,6 +36,8 @@ #include "draw_context.h" #include "draw_vertex.h" +#include "x86/rtasm/x86sse.h" + #include "pipe/tgsi/exec/tgsi_core.h" static INLINE unsigned @@ -70,6 +72,7 @@ typedef void (XSTDCALL *codegen_function) ( float (*constant)[4], struct tgsi_exec_vector *temporary ); + /** * Transform vertices with the current vertex program/shader * Up to four vertices can be shaded at a time. @@ -92,7 +95,7 @@ run_vertex_program(struct draw_context *draw, const float *trans = draw->viewport.translate; assert(count <= 4); - assert(draw->vertex_shader.output_semantic_name[0] + assert(draw->vertex_shader->state->output_semantic_name[0] == TGSI_SEMANTIC_POSITION); #ifdef DEBUG @@ -101,7 +104,7 @@ run_vertex_program(struct draw_context *draw, /* init machine state */ tgsi_exec_machine_init(&machine, - draw->vertex_shader.tokens, + draw->vertex_shader->state->tokens, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); @@ -114,8 +117,8 @@ run_vertex_program(struct draw_context *draw, draw_vertex_fetch( draw, &machine, elts, count ); /* run shader */ - if( draw->vertex_shader.executable != NULL ) { - codegen_function func = (codegen_function) draw->vertex_shader.executable; + if( draw->vertex_shader->state->executable != NULL ) { + codegen_function func = (codegen_function) draw->vertex_shader->state->executable; func( machine.Inputs, machine.Outputs, @@ -206,3 +209,42 @@ void draw_vertex_shader_queue_flush( struct draw_context *draw ) draw->vs.queue_nr = 0; } + +void * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + struct draw_vertex_shader *vs = calloc(1, sizeof(struct draw_vertex_shader)); + + vs->state = shader; +#if defined(__i386__) || defined(__386__) + x86_init_func(&vs->sse2_program); + + tgsi_emit_sse2(shader->tokens, &vs->sse2_program); + + ((struct pipe_shader_state*)(vs->state))->executable = + x86_get_func(&vs->sse2_program); +#endif + + return vs; +} + +void draw_bind_vertex_shader(struct draw_context *draw, + void *vcso) +{ + draw_flush(draw); + draw->vertex_shader = (struct draw_vertex_shader*)(vcso); +} + +void draw_delete_vertex_shader(struct draw_context *draw, + void *vcso) +{ + struct draw_vertex_shader *vs = (struct draw_vertex_shader*)(vcso); +#if defined(__i386__) || defined(__386__) + x86_release_func(&vs->sse2_program); +#endif + free(vcso); +} + + + diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 5c6d37a4661..19ca5e575fb 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -443,16 +443,13 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe, { } - -static void * -i915_create_shader_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) +static void * i915_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { return 0; } -static void i915_bind_fs_state( struct pipe_context *pipe, - void *fs ) +static void i915_bind_fs_state(struct pipe_context *pipe, void *fs) { struct i915_context *i915 = i915_context(pipe); @@ -461,20 +458,35 @@ static void i915_bind_fs_state( struct pipe_context *pipe, i915->dirty |= I915_NEW_FS; } +static void i915_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + /*do nothing*/ +} -static void i915_bind_vs_state(struct pipe_context *pipe, - void *vs) +static void * +i915_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { struct i915_context *i915 = i915_context(pipe); /* just pass-through to draw module */ - draw_set_vertex_shader(i915->draw, (const struct pipe_shader_state *)vs); + return draw_create_vertex_shader(i915->draw, templ); } -static void i915_delete_shader_state(struct pipe_context *pipe, - void *shader) +static void i915_bind_vs_state(struct pipe_context *pipe, void *vs) { - /*do nothing*/ + struct i915_context *i915 = i915_context(pipe); + + /* just pass-through to draw module */ + draw_bind_vertex_shader(i915->draw, vs); +} + +static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + struct i915_context *i915 = i915_context(pipe); + + /* just pass-through to draw module */ + draw_delete_vertex_shader(i915->draw, shader); } static void i915_set_constant_buffer(struct pipe_context *pipe, @@ -707,12 +719,12 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.create_rasterizer_state = i915_create_rasterizer_state; i915->pipe.bind_rasterizer_state = i915_bind_rasterizer_state; i915->pipe.delete_rasterizer_state = i915_delete_rasterizer_state; - i915->pipe.create_fs_state = i915_create_shader_state; + i915->pipe.create_fs_state = i915_create_fs_state; i915->pipe.bind_fs_state = i915_bind_fs_state; - i915->pipe.delete_fs_state = i915_delete_shader_state; - i915->pipe.create_vs_state = i915_create_shader_state; + i915->pipe.delete_fs_state = i915_delete_fs_state; + i915->pipe.create_vs_state = i915_create_vs_state; i915->pipe.bind_vs_state = i915_bind_vs_state; - i915->pipe.delete_vs_state = i915_delete_shader_state; + i915->pipe.delete_vs_state = i915_delete_vs_state; i915->pipe.set_blend_color = i915_set_blend_color; i915->pipe.set_clip_state = i915_set_clip_state; diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index e415966dae1..695bf1a9e02 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -275,12 +275,12 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; - softpipe->pipe.create_fs_state = softpipe_create_shader_state; + softpipe->pipe.create_fs_state = softpipe_create_fs_state; softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; - softpipe->pipe.delete_fs_state = softpipe_delete_shader_state; - softpipe->pipe.create_vs_state = softpipe_create_shader_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + softpipe->pipe.create_vs_state = softpipe_create_vs_state; softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; - softpipe->pipe.delete_vs_state = softpipe_delete_shader_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_clip_state = softpipe_set_clip_state; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index c0a681f3d6b..ccf29b5683d 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -62,8 +62,12 @@ struct draw_stage; #define SP_NEW_VS 0x2000 #define SP_NEW_CONSTANTS 0x4000 +struct sp_vertex_shader_state { + const struct pipe_shader_state *state; + void *draw_data; +}; -struct softpipe_context { +struct softpipe_context { struct pipe_context pipe; /**< base class */ struct softpipe_winsys *winsys; /**< window system interface */ @@ -76,7 +80,7 @@ struct softpipe_context { const struct pipe_depth_stencil_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer; const struct pipe_shader_state *fs; - const struct pipe_shader_state *vs; + const struct sp_vertex_shader_state *vs; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index f0e1461d258..f9061e86e53 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -87,12 +87,14 @@ void softpipe_set_constant_buffer(struct pipe_context *, void softpipe_set_feedback_state( struct pipe_context *, const struct pipe_feedback_state * ); -void * -softpipe_create_shader_state( struct pipe_context *, - const struct pipe_shader_state * ); -void softpipe_bind_fs_state( struct pipe_context *, void * ); -void softpipe_bind_vs_state( struct pipe_context *, void * ); -void softpipe_delete_shader_state( struct pipe_context *, void * ); +void *softpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); void softpipe_set_polygon_stipple( struct pipe_context *, const struct pipe_poly_stipple * ); diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 6c6e7980698..b6145df8e25 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -43,7 +43,7 @@ */ static void calculate_vertex_layout( struct softpipe_context *softpipe ) { - const struct pipe_shader_state *vs = softpipe->vs; + const struct pipe_shader_state *vs = softpipe->vs->state; const struct pipe_shader_state *fs = softpipe->fs; const interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 8306a95f449..f1bec2c73ac 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -33,10 +33,13 @@ #include "pipe/draw/draw_context.h" -void * softpipe_create_shader_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) +void * softpipe_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { - /* we just want the pipe_shader_state template in the bind calls */ + /* Decide whether we'll be codegenerating this shader and if so do + * that now. + */ + return 0; } @@ -49,25 +52,51 @@ void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) softpipe->dirty |= SP_NEW_FS; } +void softpipe_delete_fs_state(struct pipe_context *pipe, + void *shader) +{ +} + + +void * softpipe_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct sp_vertex_shader_state *state = + malloc(sizeof(struct sp_vertex_shader_state)); + + state->state = templ; + state->draw_data = draw_create_vertex_shader(softpipe->draw, + state->state); + + return state; +} void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->vs = (struct pipe_shader_state *)vs; + softpipe->vs = (const struct sp_vertex_shader_state *)vs; - softpipe->dirty |= SP_NEW_VS; + draw_bind_vertex_shader(softpipe->draw, softpipe->vs->draw_data); - draw_set_vertex_shader(softpipe->draw, (struct pipe_shader_state *)vs); + softpipe->dirty |= SP_NEW_VS; } - -void softpipe_delete_shader_state( struct pipe_context *pipe, - void *shader ) +void softpipe_delete_vs_state(struct pipe_context *pipe, + void *vs) { - /* do nothing */ + struct softpipe_context *softpipe = softpipe_context(pipe); + + struct sp_vertex_shader_state *state = + (struct sp_vertex_shader_state *)vs; + + draw_delete_vertex_shader(softpipe->draw, state->draw_data); + free(state); } + + void softpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *buf) diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 25dbc2c2442..3a7ce9405e8 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -86,10 +86,6 @@ static struct gl_program *st_new_program( GLcontext *ctx, prog->serialNo = 1; -#if defined(__i386__) || defined(__386__) - x86_init_func( &prog->sse2_program ); -#endif - return _mesa_init_vertex_program( ctx, &prog->Base, target, @@ -129,9 +125,6 @@ static void st_delete_program( GLcontext *ctx, case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *stvp = (struct st_vertex_program *) prog; -#if defined(__i386__) || defined(__386__) - x86_release_func( &stvp->sse2_program ); -#endif st_remove_vertex_program(st, stvp); } break; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index ce5bf0c8a94..7c836ba2c13 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -405,7 +405,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_viewport_state(draw, &st->state.viewport); draw_set_clip_state(draw, &st->state.clip); draw_set_rasterizer_state(draw, &st->state.rasterizer->state); - draw_set_vertex_shader(draw, &st->state.vs->state); + draw_bind_vertex_shader(draw, st->state.vs->data); /* XXX need to set vertex info too */ diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 44cc33b09fb..116b59a067a 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -253,14 +253,6 @@ st_translate_vertex_program(struct st_context *st, if (TGSI_DEBUG) tgsi_dump( tokensOut, 0 ); -#if defined(__i386__) || defined(__386__) - if (stvp->sse2_program.csr == stvp->sse2_program.store) - tgsi_emit_sse2( tokensOut, &stvp->sse2_program ); - - if (!cso->state.executable) - ((struct cso_vertex_shader*)cso)->state.executable = (void *) x86_get_func( &stvp->sse2_program ); -#endif - return cso; } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 6e106c16b02..2b792013131 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -79,10 +79,6 @@ struct st_vertex_program /** The program in TGSI format */ struct tgsi_token tokens[ST_FP_MAX_TOKENS]; -#if defined(__i386__) || defined(__386__) - struct x86_function sse2_program; -#endif - /** Pointer to the corresponding cached shader */ const struct cso_vertex_shader *vs; -- 2.30.2