From: Zack Rusin Date: Wed, 19 Sep 2007 16:35:29 +0000 (-0400) Subject: Redo the cso cache to map driver data in a lot more pleasing way. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0bf7322088715bb411068c3d631b0c4be8cdff5;p=mesa.git Redo the cso cache to map driver data in a lot more pleasing way. Drivers can now create whatever they want from the state template. We use cso_state object to store the template (necessary during lookups), and the driver data. Convert blend state to the new semantics. --- diff --git a/src/mesa/pipe/cso_cache/cso_cache.h b/src/mesa/pipe/cso_cache/cso_cache.h index 352e1a6a592..7ac59089229 100644 --- a/src/mesa/pipe/cso_cache/cso_cache.h +++ b/src/mesa/pipe/cso_cache/cso_cache.h @@ -48,6 +48,11 @@ struct cso_cache { struct cso_hash *vs_hash; }; +struct cso_blend { + struct pipe_blend_state state; + void *data; +}; + enum cso_cache_type { CSO_BLEND, CSO_SAMPLER, diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index 9556a17e4db..ea7fb109b3b 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -60,13 +60,17 @@ #define FO_HW 0 #define FO_SW 1 +struct fo_state { + void *sw_state; + void *hw_state; +}; struct failover_context { struct pipe_context pipe; /**< base class */ /* The most recent drawing state as set by the driver: */ - const struct pipe_blend_state *blend; + const struct fo_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct pipe_depth_stencil_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index 04ebd33d0d4..ba110a6e4ff 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -57,17 +57,43 @@ failover_set_alpha_test_state(struct pipe_context *pipe, } -static void +static void * +failover_create_blend_state( struct pipe_context *pipe, + const struct pipe_blend_state *blend ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_blend_state(pipe, blend); + state->hw_state = failover->hw->create_blend_state(pipe, blend); + + return state; +} + +static void failover_bind_blend_state( struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + void *blend ) { struct failover_context *failover = failover_context(pipe); - failover->blend = blend; + failover->blend = (struct fo_state *)blend; failover->dirty |= FO_NEW_BLEND; failover->hw->bind_blend_state( failover->hw, blend ); } +static void +failover_delete_blend_state( struct pipe_context *pipe, + void *blend ) +{ + struct fo_state *state = (struct fo_state*)blend; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_blend_state(pipe, state->sw_state); + failover->hw->delete_blend_state(pipe, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} static void failover_set_blend_color( struct pipe_context *pipe, @@ -253,7 +279,9 @@ failover_set_vertex_element(struct pipe_context *pipe, void failover_init_state_functions( struct failover_context *failover ) { + failover->pipe.create_blend_state = failover_create_blend_state; failover->pipe.bind_blend_state = failover_bind_blend_state; + failover->pipe.delete_blend_state = failover_delete_blend_state; failover->pipe.bind_sampler_state = failover_bind_sampler_state; failover->pipe.bind_depth_stencil_state = failover_bind_depth_stencil_state; failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state; diff --git a/src/mesa/pipe/failover/fo_state_emit.c b/src/mesa/pipe/failover/fo_state_emit.c index 9d304074d0f..72697c01a9e 100644 --- a/src/mesa/pipe/failover/fo_state_emit.c +++ b/src/mesa/pipe/failover/fo_state_emit.c @@ -59,7 +59,8 @@ failover_state_emit( struct failover_context *failover ) failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test ); if (failover->dirty & FO_NEW_BLEND) - failover->sw->bind_blend_state( failover->sw, failover->blend ); + failover->sw->bind_blend_state( failover->sw, + failover->blend->sw_state ); if (failover->dirty & FO_NEW_BLEND_COLOR) failover->sw->set_blend_color( failover->sw, &failover->blend_color ); diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index aaf2ccf499c..86c108978fa 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -38,7 +38,7 @@ /* None of this state is actually used for anything yet. */ -static const struct pipe_blend_state * +static void * i915_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) { @@ -49,20 +49,20 @@ i915_create_blend_state(struct pipe_context *pipe, } static void i915_bind_blend_state( struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + void *blend ) { struct i915_context *i915 = i915_context(pipe); - i915->blend = blend; + i915->blend = (struct pipe_blend_state *)blend; i915->dirty |= I915_NEW_BLEND; } static void i915_delete_blend_state( struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + void *blend ) { - free((void*)blend); + free(blend); } static void i915_set_blend_color( struct pipe_context *pipe, diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 5766b2b7df3..adca6612d55 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -85,12 +85,10 @@ struct pipe_context { /* * State functions */ - const struct pipe_blend_state * (*create_blend_state)(struct pipe_context *, - const struct pipe_blend_state *); - void (*bind_blend_state)(struct pipe_context *, - const struct pipe_blend_state *); - void (*delete_blend_state)(struct pipe_context *, - const struct pipe_blend_state *); + void * (*create_blend_state)(struct pipe_context *, + const struct pipe_blend_state *); + void (*bind_blend_state)(struct pipe_context *, void *); + void (*delete_blend_state)(struct pipe_context *, void *); const struct pipe_sampler_state * (*create_sampler_state)( struct pipe_context *, diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 04cc743bd03..8e7776a6c7d 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -33,13 +33,13 @@ #include "pipe/p_state.h" -const struct pipe_blend_state * +void * softpipe_create_blend_state(struct pipe_context *, const struct pipe_blend_state *); void softpipe_bind_blend_state(struct pipe_context *, - const struct pipe_blend_state *); + void *); void softpipe_delete_blend_state(struct pipe_context *, - const struct pipe_blend_state *); + void *); const struct pipe_sampler_state * softpipe_create_sampler_state(struct pipe_context *, diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c index 83f456ded55..7a94e82d6f8 100644 --- a/src/mesa/pipe/softpipe/sp_state_blend.c +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -30,7 +30,7 @@ #include "sp_context.h" #include "sp_state.h" -const struct pipe_blend_state * +void * softpipe_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) { @@ -41,19 +41,19 @@ softpipe_create_blend_state(struct pipe_context *pipe, } void softpipe_bind_blend_state( struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + void *blend ) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->blend = blend; + softpipe->blend = (const struct pipe_blend_state *)blend; softpipe->dirty |= SP_NEW_BLEND; } void softpipe_delete_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend ) + void *blend ) { - free((struct pipe_blend_state *)blend); + free(blend); } diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index d94beb66c78..d5eadc3541a 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -211,14 +211,14 @@ update_blend( struct st_context *st ) if (st->ctx->Color.DitherFlag) blend.dither = 1; - struct pipe_blend_state *real_blend = + const struct cso_blend *cso = st_cached_blend_state(st, &blend); - if (st->state.blend != real_blend) { + if (st->state.blend != cso) { /* state has changed */ - st->state.blend = real_blend; + st->state.blend = cso; /* bind new state */ - st->pipe->bind_blend_state(st->pipe, real_blend); + st->pipe->bind_blend_state(st->pipe, cso->data); } if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) { diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c index d84a396e183..bd6c63b7a13 100644 --- a/src/mesa/state_tracker/st_cache.c +++ b/src/mesa/state_tracker/st_cache.c @@ -43,21 +43,22 @@ * in the cache or it will create a new state state from the given * template, will insert it in the cache and return it. */ -struct pipe_blend_state * st_cached_blend_state( - struct st_context *st, - const struct pipe_blend_state *blend) +const struct cso_blend * st_cached_blend_state(struct st_context *st, + const struct pipe_blend_state *templ) { - unsigned hash_key = cso_construct_key((void*)blend, sizeof(struct pipe_blend_state)); + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); struct cso_hash_iter iter = cso_find_state_template(st->cache, hash_key, CSO_BLEND, - (void*)blend); + (void*)templ); if (cso_hash_iter_is_null(iter)) { - const struct pipe_blend_state *created_state = st->pipe->create_blend_state( - st->pipe, blend); - iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, - (void*)created_state); + struct cso_blend *cso = malloc(sizeof(struct cso_blend)); + memcpy(&cso->state, templ, sizeof(struct pipe_blend_state)); + cso->data = st->pipe->create_blend_state(st->pipe, templ); + if (!cso->data) + cso->data = &cso->state; + iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, cso); } - return (struct pipe_blend_state*)(cso_hash_iter_data(iter)); + return ((struct cso_blend *)cso_hash_iter_data(iter)); } struct pipe_sampler_state * st_cached_sampler_state( diff --git a/src/mesa/state_tracker/st_cache.h b/src/mesa/state_tracker/st_cache.h index bcbe19b8236..fb0ff0d4db8 100644 --- a/src/mesa/state_tracker/st_cache.h +++ b/src/mesa/state_tracker/st_cache.h @@ -33,17 +33,19 @@ #ifndef ST_CACHE_H #define ST_CACHE_H +#include "pipe/cso_cache/cso_cache.h" + struct pipe_blend_state; struct pipe_sampler_state; struct st_context; -struct pipe_blend_state * st_cached_blend_state( - struct st_context *st, - const struct pipe_blend_state *blend); +const struct cso_blend * +st_cached_blend_state(struct st_context *st, + const struct pipe_blend_state *blend); -struct pipe_sampler_state * st_cached_sampler_state( - struct st_context *st, - const struct pipe_sampler_state *sampler); +struct pipe_sampler_state * +st_cached_sampler_state(struct st_context *st, + const struct pipe_sampler_state *sampler); struct pipe_depth_stencil_state *st_cached_depth_stencil_state( struct st_context *st, diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 7c669ab4578..3a6991754ac 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -298,7 +298,7 @@ clear_with_quad(GLcontext *ctx, /* blend state: RGBA masking */ { struct pipe_blend_state blend; - const struct pipe_blend_state *state; + const struct cso_blend *cso; memset(&blend, 0, sizeof(blend)); if (color) { if (ctx->Color.ColorMask[0]) @@ -312,8 +312,8 @@ clear_with_quad(GLcontext *ctx, if (st->ctx->Color.DitherFlag) blend.dither = 1; } - state = st_cached_blend_state(st, &blend); - pipe->bind_blend_state(pipe, state); + cso = st_cached_blend_state(st, &blend); + pipe->bind_blend_state(pipe, cso->data); } /* depth_stencil state: always pass/set to ref value */ @@ -411,7 +411,7 @@ clear_with_quad(GLcontext *ctx, /* Restore pipe state */ pipe->set_alpha_test_state(pipe, &st->state.alpha_test); - pipe->bind_blend_state(pipe, st->state.blend); + pipe->bind_blend_state(pipe, st->state.blend->data); pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil); pipe->bind_fs_state(pipe, st->state.fs); pipe->bind_vs_state(pipe, st->state.vs); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 67de781c831..4a554cd5a4a 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -493,8 +493,8 @@ static GLboolean any_fragment_ops(const struct st_context *st) { if (st->state.alpha_test.enabled || - st->state.blend->blend_enable || - st->state.blend->logicop_enable || + st->state.blend->state.blend_enable || + st->state.blend->state.logicop_enable || st->state.depth_stencil->depth.enabled) /* XXX more checks */ return GL_TRUE; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index a8ae5d9c562..966574b67c6 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -40,6 +40,7 @@ struct st_fragment_program; struct draw_context; struct draw_stage; struct cso_cache; +struct cso_blend; #define ST_NEW_MESA 0x1 /* Mesa state has changed */ #define ST_NEW_FRAGMENT_PROGRAM 0x2 @@ -74,7 +75,7 @@ struct st_context * though, we just shove random objects across the interface. */ struct { - const struct pipe_blend_state *blend; + const struct cso_blend *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct pipe_depth_stencil_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer;