From 6cb87cf26f904b891faa42268f373864fa33541d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 21 Sep 2007 07:00:20 -0400 Subject: [PATCH] Make the alpha test state a cso. --- src/mesa/pipe/cso_cache/cso_cache.c | 7 +++ src/mesa/pipe/cso_cache/cso_cache.h | 13 ++++-- src/mesa/pipe/failover/fo_context.h | 4 +- src/mesa/pipe/failover/fo_state.c | 45 ++++++++++++++++--- src/mesa/pipe/failover/fo_state_emit.c | 3 +- src/mesa/pipe/i915simple/i915_context.h | 2 +- src/mesa/pipe/i915simple/i915_state.c | 24 ++++++++-- .../pipe/i915simple/i915_state_immediate.c | 6 +-- src/mesa/pipe/p_context.h | 32 +++++++------ src/mesa/pipe/softpipe/sp_context.c | 4 +- src/mesa/pipe/softpipe/sp_context.h | 2 +- src/mesa/pipe/softpipe/sp_quad.c | 2 +- src/mesa/pipe/softpipe/sp_quad_alpha_test.c | 4 +- src/mesa/pipe/softpipe/sp_state.h | 12 +++-- src/mesa/pipe/softpipe/sp_state_blend.c | 20 +++++++-- src/mesa/state_tracker/st_atom.c | 1 + src/mesa/state_tracker/st_atom.h | 1 + src/mesa/state_tracker/st_atom_alphatest.c | 15 +++---- src/mesa/state_tracker/st_cache.c | 20 +++++++++ src/mesa/state_tracker/st_cache.h | 4 ++ src/mesa/state_tracker/st_cb_clear.c | 6 ++- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- src/mesa/state_tracker/st_context.h | 10 ++--- 23 files changed, 176 insertions(+), 63 deletions(-) diff --git a/src/mesa/pipe/cso_cache/cso_cache.c b/src/mesa/pipe/cso_cache/cso_cache.c index 71f0d087261..0bba5914dc8 100644 --- a/src/mesa/pipe/cso_cache/cso_cache.c +++ b/src/mesa/pipe/cso_cache/cso_cache.c @@ -90,6 +90,9 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_ case CSO_VERTEX_SHADER: hash = sc->vs_hash; break; + case CSO_ALPHA_TEST: + hash = sc->alpha_hash; + break; } return hash; @@ -110,6 +113,8 @@ static int _cso_size_for_type(enum cso_cache_type type) return sizeof(struct pipe_shader_state); case CSO_VERTEX_SHADER: return sizeof(struct pipe_shader_state); + case CSO_ALPHA_TEST: + return sizeof(struct pipe_alpha_test_state); } return 0; } @@ -164,6 +169,7 @@ struct cso_cache *cso_cache_create(void) sc->rasterizer_hash = cso_hash_create(); sc->fs_hash = cso_hash_create(); sc->vs_hash = cso_hash_create(); + sc->alpha_hash = cso_hash_create(); return sc; } @@ -177,5 +183,6 @@ void cso_cache_delete(struct cso_cache *sc) cso_hash_delete(sc->rasterizer_hash); cso_hash_delete(sc->fs_hash); cso_hash_delete(sc->vs_hash); + cso_hash_delete(sc->alpha_hash); free(sc); } diff --git a/src/mesa/pipe/cso_cache/cso_cache.h b/src/mesa/pipe/cso_cache/cso_cache.h index 2acb58c66b6..cd36dd51e98 100644 --- a/src/mesa/pipe/cso_cache/cso_cache.h +++ b/src/mesa/pipe/cso_cache/cso_cache.h @@ -40,12 +40,13 @@ struct cso_hash; struct cso_cache { + struct cso_hash *alpha_hash; struct cso_hash *blend_hash; - struct cso_hash *sampler_hash; struct cso_hash *depth_stencil_hash; - struct cso_hash *rasterizer_hash; struct cso_hash *fs_hash; struct cso_hash *vs_hash; + struct cso_hash *rasterizer_hash; + struct cso_hash *sampler_hash; }; struct cso_blend { @@ -78,13 +79,19 @@ struct cso_sampler { void *data; }; +struct cso_alpha_test { + struct pipe_alpha_test_state state; + void *data; +}; + enum cso_cache_type { CSO_BLEND, CSO_SAMPLER, CSO_DEPTH_STENCIL, CSO_RASTERIZER, CSO_FRAGMENT_SHADER, - CSO_VERTEX_SHADER + CSO_VERTEX_SHADER, + CSO_ALPHA_TEST }; unsigned cso_construct_key(void *item, int item_size); diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index 8a2fbe2be9b..7a597013ab2 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -64,12 +64,13 @@ struct fo_state { void *sw_state; void *hw_state; }; -struct failover_context { +struct failover_context { struct pipe_context pipe; /**< base class */ /* The most recent drawing state as set by the driver: */ + const struct fo_state *alpha_test; const struct fo_state *blend; const struct fo_state *sampler[PIPE_MAX_SAMPLERS]; const struct fo_state *depth_stencil; @@ -77,7 +78,6 @@ struct failover_context { const struct fo_state *fragment_shader; const struct fo_state *vertex_shader; - struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index ce3f0ca6358..f63137f5913 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -45,15 +45,44 @@ * lower overheads. */ +static void * +failover_create_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_alpha_test_state(pipe, templ); + state->hw_state = failover->hw->create_alpha_test_state(pipe, templ); + + return state; +} + static void -failover_set_alpha_test_state(struct pipe_context *pipe, - const struct pipe_alpha_test_state *alpha) +failover_bind_alpha_test_state(struct pipe_context *pipe, + void *alpha) { struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state *)alpha; - failover->alpha_test = *alpha; + failover->alpha_test = state; failover->dirty |= FO_NEW_ALPHA_TEST; - failover->hw->set_alpha_test_state( failover->hw, alpha ); + failover->hw->bind_alpha_test_state(failover->hw, + state->hw_state); +} + +static void +failover_delete_alpha_test_state(struct pipe_context *pipe, + void *alpha) +{ + struct fo_state *state = (struct fo_state*)alpha; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_alpha_test_state(pipe, state->sw_state); + failover->hw->delete_alpha_test_state(pipe, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); } @@ -95,7 +124,7 @@ failover_delete_blend_state( struct pipe_context *pipe, free(state); } -static void +static void failover_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { @@ -414,8 +443,11 @@ failover_set_vertex_element(struct pipe_context *pipe, void failover_init_state_functions( struct failover_context *failover ) { + failover->pipe.create_alpha_test_state = failover_create_alpha_test_state; + failover->pipe.bind_alpha_test_state = failover_bind_alpha_test_state; + failover->pipe.delete_alpha_test_state = failover_delete_alpha_test_state; failover->pipe.create_blend_state = failover_create_blend_state; - failover->pipe.bind_blend_state = failover_bind_blend_state; + failover->pipe.bind_blend_state = failover_bind_blend_state; failover->pipe.delete_blend_state = failover_delete_blend_state; failover->pipe.create_sampler_state = failover_create_sampler_state; failover->pipe.bind_sampler_state = failover_bind_sampler_state; @@ -433,7 +465,6 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.bind_vs_state = failover_bind_vs_state; failover->pipe.delete_vs_state = failover_delete_vs_state; - failover->pipe.set_alpha_test_state = failover_set_alpha_test_state; failover->pipe.set_blend_color = failover_set_blend_color; failover->pipe.set_clip_state = failover_set_clip_state; failover->pipe.set_clear_color_state = failover_set_clear_color_state; diff --git a/src/mesa/pipe/failover/fo_state_emit.c b/src/mesa/pipe/failover/fo_state_emit.c index c0ea6810246..a3aff8abd2a 100644 --- a/src/mesa/pipe/failover/fo_state_emit.c +++ b/src/mesa/pipe/failover/fo_state_emit.c @@ -56,7 +56,8 @@ failover_state_emit( struct failover_context *failover ) unsigned i; if (failover->dirty & FO_NEW_ALPHA_TEST) - failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test ); + failover->sw->bind_alpha_test_state( failover->sw, + failover->alpha_test->sw_state ); if (failover->dirty & FO_NEW_BLEND) failover->sw->bind_blend_state( failover->sw, diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index f1e10f34332..9958a8592dc 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -154,13 +154,13 @@ struct i915_context /* The most recent drawing state as set by the driver: */ + const struct pipe_alpha_test_state *alpha_test; const struct i915_blend_state *blend; const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct i915_depth_stencil_state *depth_stencil; const struct i915_rasterizer_state *rasterizer; const struct pipe_shader_state *fs; - struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 525f8ce13a2..8bfd2da3b5c 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -394,16 +394,29 @@ static void i915_delete_depth_stencil_state(struct pipe_context *pipe, free(depth_stencil); } -static void i915_set_alpha_test_state(struct pipe_context *pipe, - const struct pipe_alpha_test_state *alpha) + +static void * +i915_create_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *alpha) +{ + return 0; +} + +static void i915_bind_alpha_test_state(struct pipe_context *pipe, + void *alpha) { struct i915_context *i915 = i915_context(pipe); - i915->alpha_test = *alpha; + i915->alpha_test = (const struct pipe_alpha_test_state*)alpha; i915->dirty |= I915_NEW_ALPHA_TEST; } +static void i915_delete_alpha_test_state(struct pipe_context *pipe, + void *alpha) +{ +} + static void i915_set_scissor_state( struct pipe_context *pipe, const struct pipe_scissor_state *scissor ) { @@ -664,6 +677,10 @@ static void i915_set_vertex_element( struct pipe_context *pipe, void i915_init_state_functions( struct i915_context *i915 ) { + i915->pipe.create_alpha_test_state = i915_create_alpha_test_state; + i915->pipe.bind_alpha_test_state = i915_bind_alpha_test_state; + i915->pipe.delete_alpha_test_state = i915_delete_alpha_test_state; + i915->pipe.create_blend_state = i915_create_blend_state; i915->pipe.bind_blend_state = i915_bind_blend_state; i915->pipe.delete_blend_state = i915_delete_blend_state; @@ -686,7 +703,6 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.bind_vs_state = i915_bind_vs_state; i915->pipe.delete_vs_state = i915_delete_shader_state; - i915->pipe.set_alpha_test_state = i915_set_alpha_test_state; i915->pipe.set_blend_color = i915_set_blend_color; i915->pipe.set_clip_state = i915_set_clip_state; i915->pipe.set_clear_color_state = i915_set_clear_color_state; diff --git a/src/mesa/pipe/i915simple/i915_state_immediate.c b/src/mesa/pipe/i915simple/i915_state_immediate.c index 874c3819f25..014fddfdda5 100644 --- a/src/mesa/pipe/i915simple/i915_state_immediate.c +++ b/src/mesa/pipe/i915simple/i915_state_immediate.c @@ -121,9 +121,9 @@ static void upload_S6( struct i915_context *i915 ) /* I915_NEW_ALPHA_TEST */ - if (i915->alpha_test.enabled) { - int test = i915_translate_compare_func(i915->alpha_test.func); - ubyte refByte = float_to_ubyte(i915->alpha_test.ref); + if (i915->alpha_test->enabled) { + int test = i915_translate_compare_func(i915->alpha_test->func); + ubyte refByte = float_to_ubyte(i915->alpha_test->ref); LIS6 |= (S6_ALPHA_TEST_ENABLE | diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index 07ee0198807..8ba1031efe5 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -86,26 +86,30 @@ struct pipe_context { /* * State functions */ + void * (*create_alpha_test_state)(struct pipe_context *, + const struct pipe_alpha_test_state *); + void (*bind_alpha_test_state)(struct pipe_context *, void *); + void (*delete_alpha_test_state)(struct pipe_context *, void *); + 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 *); + void (*bind_blend_state)(struct pipe_context *, void *); + void (*delete_blend_state)(struct pipe_context *, void *); void * (*create_sampler_state)(struct pipe_context *, const struct pipe_sampler_state *); - void (*bind_sampler_state)(struct pipe_context *, unsigned unit, - void *); - void (*delete_sampler_state)(struct pipe_context *, void *); + void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *); + void (*delete_sampler_state)(struct pipe_context *, void *); - void *(*create_rasterizer_state)(struct pipe_context *, - const struct pipe_rasterizer_state *); - void (*bind_rasterizer_state)(struct pipe_context *, void *); - void (*delete_rasterizer_state)(struct pipe_context *, void *); + void * (*create_rasterizer_state)(struct pipe_context *, + const struct pipe_rasterizer_state *); + void (*bind_rasterizer_state)(struct pipe_context *, void *); + void (*delete_rasterizer_state)(struct pipe_context *, void *); void * (*create_depth_stencil_state)(struct pipe_context *, const struct pipe_depth_stencil_state *); - void (*bind_depth_stencil_state)(struct pipe_context *, void *); - void (*delete_depth_stencil_state)(struct pipe_context *, void *); + void (*bind_depth_stencil_state)(struct pipe_context *, void *); + void (*delete_depth_stencil_state)(struct pipe_context *, void *); void * (*create_fs_state)(struct pipe_context *, const struct pipe_shader_state *); @@ -117,9 +121,9 @@ struct pipe_context { void (*bind_vs_state)(struct pipe_context *, void *); void (*delete_vs_state)(struct pipe_context *, void *); - void (*set_alpha_test_state)( struct pipe_context *, - const struct pipe_alpha_test_state * ); - + /* The following look more properties than states. + * maybe combine a few of them into states or pass them + * in the bind calls to the state */ void (*set_blend_color)( struct pipe_context *, const struct pipe_blend_color * ); diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index cac44606f74..a6ab45314cf 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -260,6 +260,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.get_param = softpipe_get_param; /* state setters */ + softpipe->pipe.create_alpha_test_state = softpipe_create_alpha_test_state; + softpipe->pipe.bind_alpha_test_state = softpipe_bind_alpha_test_state; + softpipe->pipe.delete_alpha_test_state = softpipe_delete_alpha_test_state; softpipe->pipe.create_blend_state = softpipe_create_blend_state; softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; @@ -279,7 +282,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; softpipe->pipe.delete_vs_state = softpipe_delete_shader_state; - softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 95215eb6408..7b1518cfaca 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -70,6 +70,7 @@ struct softpipe_context { /* The most recent drawing state as set by the driver: */ + const struct pipe_alpha_test_state *alpha_test; const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct pipe_depth_stencil_state *depth_stencil; @@ -77,7 +78,6 @@ struct softpipe_context { const struct pipe_shader_state *fs; const struct pipe_shader_state *vs; - struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index fc4f8328cf8..74a21dc54b4 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -54,7 +54,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->quad.first = sp->quad.depth_test; } - if (sp->alpha_test.enabled) { + if (sp->alpha_test->enabled) { sp->quad.alpha_test->next = sp->quad.first; sp->quad.first = sp->quad.alpha_test; } diff --git a/src/mesa/pipe/softpipe/sp_quad_alpha_test.c b/src/mesa/pipe/softpipe/sp_quad_alpha_test.c index 64c1624bd0e..4f28414b0e0 100644 --- a/src/mesa/pipe/softpipe/sp_quad_alpha_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_alpha_test.c @@ -14,10 +14,10 @@ static void alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - const float ref = softpipe->alpha_test.ref; + const float ref = softpipe->alpha_test->ref; unsigned passMask = 0x0, j; - switch (softpipe->alpha_test.func) { + switch (softpipe->alpha_test->func) { case PIPE_FUNC_NEVER: quad->mask = 0x0; break; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 62323c41c3b..f0e1461d258 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -33,6 +33,15 @@ #include "pipe/p_state.h" + +void * +softpipe_create_alpha_test_state(struct pipe_context *, + const struct pipe_alpha_test_state *); +void +softpipe_bind_alpha_test_state(struct pipe_context *, void *); +void +softpipe_delete_alpha_test_state(struct pipe_context *, void *); + void * softpipe_create_blend_state(struct pipe_context *, const struct pipe_blend_state *); @@ -62,9 +71,6 @@ void softpipe_delete_rasterizer_state(struct pipe_context *, void *); void softpipe_set_framebuffer_state( struct pipe_context *, const struct pipe_framebuffer_state * ); -void softpipe_set_alpha_test_state( struct pipe_context *, - const struct pipe_alpha_test_state * ); - void softpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ); diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c index cf476079557..cb0921f687b 100644 --- a/src/mesa/pipe/softpipe/sp_state_blend.c +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -71,17 +71,31 @@ void softpipe_set_blend_color( struct pipe_context *pipe, * into one file. */ +void * +softpipe_create_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *alpha) +{ + return 0; +} + void -softpipe_set_alpha_test_state(struct pipe_context *pipe, - const struct pipe_alpha_test_state *alpha) +softpipe_bind_alpha_test_state(struct pipe_context *pipe, + void *alpha) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->alpha_test = *alpha; + softpipe->alpha_test = (const struct pipe_alpha_test_state *)alpha; softpipe->dirty |= SP_NEW_ALPHA_TEST; } +void +softpipe_delete_alpha_test_state(struct pipe_context *pipe, + void *alpha) +{ + /* do nothing */ +} + void * softpipe_create_depth_stencil_state(struct pipe_context *pipe, const struct pipe_depth_stencil_state *depth_stencil) diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index a4af3aeb205..fc339b91ed7 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -62,6 +62,7 @@ static const struct st_tracked_state *atoms[] = &st_update_texture, &st_update_vs_constants, &st_update_fs_constants, + &st_update_alpha_test }; diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index 26f6514698c..6710c1a2695 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -60,6 +60,7 @@ const struct st_tracked_state st_update_sampler; const struct st_tracked_state st_update_texture; const struct st_tracked_state st_update_fs_constants; const struct st_tracked_state st_update_vs_constants; +const struct st_tracked_state st_update_alpha_test; #endif diff --git a/src/mesa/state_tracker/st_atom_alphatest.c b/src/mesa/state_tracker/st_atom_alphatest.c index 4378154053d..873520ab025 100644 --- a/src/mesa/state_tracker/st_atom_alphatest.c +++ b/src/mesa/state_tracker/st_atom_alphatest.c @@ -33,6 +33,7 @@ #include "st_context.h" +#include "st_cache.h" #include "st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -63,6 +64,7 @@ static void update_alpha_test( struct st_context *st ) { struct pipe_alpha_test_state alpha; + const struct cso_alpha_test *cso; memset(&alpha, 0, sizeof(alpha)); @@ -71,11 +73,11 @@ update_alpha_test( struct st_context *st ) alpha.func = gl_alpha_func_to_sp(st->ctx->Color.AlphaFunc); alpha.ref = st->ctx->Color.AlphaRef; } - - if (memcmp(&alpha, &st->state.alpha_test, sizeof(alpha)) != 0) { + cso = st_cached_alpha_test_state(st, &alpha); + if (st->state.alpha_test != cso) { /* state has changed */ - st->state.alpha_test = alpha; /* struct copy */ - st->pipe->set_alpha_test_state(st->pipe, &alpha); /* set new state */ + st->state.alpha_test = cso; + st->pipe->bind_alpha_test_state(st->pipe, cso->data); /* bind new state */ } } @@ -88,8 +90,3 @@ const struct st_tracked_state st_update_alpha_test = { }, .update = update_alpha_test }; - - - - - diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c index 01d1934232b..1686721990a 100644 --- a/src/mesa/state_tracker/st_cache.c +++ b/src/mesa/state_tracker/st_cache.c @@ -159,3 +159,23 @@ st_cached_vs_state(struct st_context *st, } return (struct cso_vertex_shader*)(cso_hash_iter_data(iter)); } + +const struct cso_alpha_test * +st_cached_alpha_test_state(struct st_context *st, + const struct pipe_alpha_test_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_alpha_test_state)); + struct cso_hash_iter iter = cso_find_state_template(st->cache, + hash_key, CSO_ALPHA_TEST, + (void*)templ); + if (cso_hash_iter_is_null(iter)) { + struct cso_alpha_test *cso = malloc(sizeof(struct cso_alpha_test)); + memcpy(&cso->state, templ, sizeof(struct pipe_alpha_test_state)); + cso->data = st->pipe->create_alpha_test_state(st->pipe, &cso->state); + if (!cso->data) + cso->data = &cso->state; + iter = cso_insert_state(st->cache, hash_key, CSO_ALPHA_TEST, cso); + } + return ((struct cso_alpha_test *)cso_hash_iter_data(iter)); +} diff --git a/src/mesa/state_tracker/st_cache.h b/src/mesa/state_tracker/st_cache.h index 483af6fdb43..422f668c561 100644 --- a/src/mesa/state_tracker/st_cache.h +++ b/src/mesa/state_tracker/st_cache.h @@ -39,6 +39,10 @@ struct pipe_blend_state; struct pipe_sampler_state; struct st_context; +const struct cso_alpha_test * +st_cached_alpha_test_state(struct st_context *st, + const struct pipe_alpha_test_state *alpha); + const struct cso_blend * st_cached_blend_state(struct st_context *st, const struct pipe_blend_state *blend); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 5e632050885..c53446d588d 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -275,8 +275,10 @@ clear_with_quad(GLcontext *ctx, /* alpha state: disabled */ { struct pipe_alpha_test_state alpha_test; + const struct cso_alpha_test *cso; memset(&alpha_test, 0, sizeof(alpha_test)); - pipe->set_alpha_test_state(pipe, &alpha_test); + cso = st_cached_alpha_test_state(st, &alpha_test); + pipe->bind_alpha_test_state(pipe, cso->data); } /* blend state: RGBA masking */ @@ -379,7 +381,7 @@ clear_with_quad(GLcontext *ctx, draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); /* Restore pipe state */ - pipe->set_alpha_test_state(pipe, &st->state.alpha_test); + pipe->bind_alpha_test_state(pipe, st->state.alpha_test->data); pipe->bind_blend_state(pipe, st->state.blend->data); pipe->bind_depth_stencil_state(pipe, st->state.depth_stencil->data); pipe->bind_fs_state(pipe, st->state.fs->data); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index d814e341575..65c54655464 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -468,7 +468,7 @@ compatible_formats(GLenum format, GLenum type, GLuint pipeFormat) static GLboolean any_fragment_ops(const struct st_context *st) { - if (st->state.alpha_test.enabled || + if (st->state.alpha_test->state.enabled || st->state.blend->state.blend_enable || st->state.blend->state.logicop_enable || st->state.depth_stencil->state.depth.enabled) diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 55a857f46d4..3713328eb14 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -75,14 +75,14 @@ struct st_context * though, we just shove random objects across the interface. */ struct { - const struct cso_blend *blend; - const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS]; - const struct cso_depth_stencil *depth_stencil; - const struct cso_rasterizer *rasterizer; + const struct cso_alpha_test *alpha_test; + const struct cso_blend *blend; + const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS]; + const struct cso_depth_stencil *depth_stencil; + const struct cso_rasterizer *rasterizer; const struct cso_fragment_shader *fs; const struct cso_vertex_shader *vs; - struct pipe_alpha_test_state alpha_test; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; -- 2.30.2