diff options
author | Zack Rusin <[email protected]> | 2007-09-14 04:08:58 -0400 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2007-09-18 06:31:22 -0400 |
commit | 9780327c5d95586a88fce94d7b47342355ead118 (patch) | |
tree | 9007ea135504d8fd90b49a391a43fa579b9374b5 /src | |
parent | ffacb1c12a77d71613e8171e31ffc348959881e4 (diff) |
First stab at immutable state objects (create/bind/delete)
We want our state objects to be immutable, handled via the
create/bind/delete calls instead of struct propagation.
Only implementing the blend state to see how it would look like
and work.
Diffstat (limited to 'src')
23 files changed, 382 insertions, 59 deletions
diff --git a/src/mesa/cso_cache/cso_cache.c b/src/mesa/cso_cache/cso_cache.c new file mode 100644 index 00000000000..bb853308bee --- /dev/null +++ b/src/mesa/cso_cache/cso_cache.c @@ -0,0 +1,176 @@ +/************************************************************************** + * + * 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: Zack Rusin <[email protected]> + */ + +#include "cso_cache.h" + +#if 1 +static unsigned hash_key( const void *key, unsigned key_size ) +{ + unsigned *ikey = (unsigned *)key; + unsigned hash = 0, i; + + assert(key_size % 4 == 0); + + /* I'm sure this can be improved on: + */ + for (i = 0; i < key_size/4; i++) + hash ^= ikey[i]; + + return hash; +} +#else +static unsigned hash_key(const unsigned char *p, int n) +{ + unsigned h = 0; + unsigned g; + + while (n--) { + h = (h << 4) + *p++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 23; + h &= ~g; + } + return h; +} +#endif + +unsigned cso_construct_key(void *item, int item_size) +{ + return hash_key((const unsigned char*)(item), item_size); +} + +struct cso_cache_item * +cso_insert_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size) +{ + struct cso_cache_item *found_state = + _mesa_HashLookup(sc->hash, hash_key); + struct cso_cache_item *item = + malloc(sizeof(struct cso_cache_item)); + _mesa_printf("inserting state ========= key = %d\n", hash_key); + item->key = hash_key; + item->state_size = state_size; + item->state = state; + item->next = 0; + + if (found_state) { + while (found_state->next) + found_state = found_state->next; + found_state->next = item; + } else + _mesa_HashInsert(sc->hash, hash_key, item); + return item; +} + +struct cso_cache_item * +cso_find_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size) +{ + struct cso_cache_item *found_state = + _mesa_HashLookup(sc->hash, hash_key); + + while (found_state && + (found_state->state_size != state_size || + memcmp(found_state->state, state, state_size))) { + found_state = found_state->next; + } + + _mesa_printf("finding state ========== %d (%p)\n", hash_key, found_state); + return found_state; +} + +struct cso_cache_item * +cso_remove_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size) +{ + struct cso_cache_item *found_state = + _mesa_HashLookup(sc->hash, hash_key); + struct cso_cache_item *prev = 0; + + while (found_state && + (found_state->state_size != state_size || + memcmp(found_state->state, state, state_size))) { + prev = found_state; + found_state = found_state->next; + } + if (found_state) { + if (prev) + prev->next = found_state->next; + else { + if (found_state->next) + _mesa_HashInsert(sc->hash, hash_key, found_state->next); + else + _mesa_HashRemove(sc->hash, hash_key); + } + } + return found_state; +} + +struct cso_cache *cso_cache_create(void) +{ + struct cso_cache *sc = malloc(sizeof(struct cso_cache)); + + sc->hash = _mesa_NewHashTable(); + + return sc; +} + +void cso_cache_destroy(struct cso_cache *sc) +{ + assert(sc); + assert(sc->hash); + _mesa_DeleteHashTable(sc->hash); + free(sc); +} + +/* This function will either find the state of the given template + * 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 * cso_cached_blend_state( + struct st_context *st, + const struct pipe_blend_state *blend) +{ + unsigned hash_key = cso_construct_key((void*)blend, sizeof(struct pipe_blend_state)); + struct cso_cache_item *cache_item = cso_find_state(st->cache, + hash_key, + (void*)blend, + sizeof(struct pipe_blend_state)); + if (!cache_item) { + const struct pipe_blend_state *created_state = st->pipe->create_blend_state( + st->pipe, blend); + cache_item = cso_insert_state(st->cache, hash_key, + (void*)created_state, sizeof(struct pipe_blend_state)); + } + return (struct pipe_blend_state*)cache_item->state; +} diff --git a/src/mesa/cso_cache/cso_cache.h b/src/mesa/cso_cache/cso_cache.h new file mode 100644 index 00000000000..ca0a2d576a9 --- /dev/null +++ b/src/mesa/cso_cache/cso_cache.h @@ -0,0 +1,75 @@ +/************************************************************************** + * + * 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: + * Zack Rusin <[email protected]> + */ + +#ifndef CSO_CACHE_H +#define CSO_CACHE_H + +#include "state_tracker/st_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + + +#include "main/hash.h" + +struct cso_cache_item { + unsigned key; + + unsigned state_size; + const void *state; + + struct cso_cache_item *next; +}; + +struct cso_cache { + struct _mesa_HashTable *hash; +}; + +void cso_cache_destroy(struct cso_cache *sc); +struct cso_cache *cso_cache_create(void); + +unsigned cso_construct_key(void *item, int item_size); + +struct cso_cache_item *cso_insert_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size); +struct cso_cache_item *cso_find_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size); +struct cso_cache_item *cso_remove_state(struct cso_cache *sc, + unsigned hash_key, + void *state, int state_size); + +struct pipe_blend_state *cso_cached_blend_state( + struct st_context *pipe, + const struct pipe_blend_state *state); + +#endif diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index 5666d4e8306..b065aa832a4 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -67,8 +67,9 @@ struct failover_context { /* The most recent drawing state as set by the driver: */ + const struct pipe_blend_state *blend; + struct pipe_alpha_test_state alpha_test; - struct pipe_blend_state blend; 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 097acf7d579..2357d7ef5ce 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -58,14 +58,14 @@ failover_set_alpha_test_state(struct pipe_context *pipe, static void -failover_set_blend_state( struct pipe_context *pipe, +failover_bind_blend_state( struct pipe_context *pipe, const struct pipe_blend_state *blend ) { struct failover_context *failover = failover_context(pipe); - failover->blend = *blend; + failover->blend = blend; failover->dirty |= FO_NEW_BLEND; - failover->hw->set_blend_state( failover->hw, blend ); + failover->hw->bind_blend_state( failover->hw, blend ); } @@ -266,9 +266,10 @@ failover_set_vertex_element(struct pipe_context *pipe, void failover_init_state_functions( struct failover_context *failover ) { + failover->pipe.bind_blend_state = failover_bind_blend_state; + failover->pipe.set_alpha_test_state = failover_set_alpha_test_state; failover->pipe.set_blend_color = failover_set_blend_color; - failover->pipe.set_blend_state = failover_set_blend_state; failover->pipe.set_clip_state = failover_set_clip_state; failover->pipe.set_clear_color_state = failover_set_clear_color_state; failover->pipe.set_depth_state = failover_set_depth_test_state; diff --git a/src/mesa/pipe/failover/fo_state_emit.c b/src/mesa/pipe/failover/fo_state_emit.c index 52fcf5dbc95..77413d100b3 100644 --- a/src/mesa/pipe/failover/fo_state_emit.c +++ b/src/mesa/pipe/failover/fo_state_emit.c @@ -59,7 +59,7 @@ 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->set_blend_state( failover->sw, &failover->blend ); + failover->sw->bind_blend_state( failover->sw, failover->blend ); 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_context.h b/src/mesa/pipe/i915simple/i915_context.h index c30c79d83c9..215c5294fa6 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -123,8 +123,9 @@ struct i915_context /* The most recent drawing state as set by the driver: */ + const struct pipe_blend_state *blend; + struct pipe_alpha_test_state alpha_test; - struct pipe_blend_state blend; 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 f5ea721cc8e..478988fd4a9 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -37,17 +37,37 @@ /* None of this state is actually used for anything yet. */ -static void i915_set_blend_state( struct pipe_context *pipe, + +static const struct pipe_blend_state * +i915_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + /*struct i915_context *i915 = i915_context(pipe);*/ + + struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state)); + memcpy(new_blend, blend, sizeof(struct pipe_blend_state)); + + return new_blend; +} + +static void i915_bind_blend_state( struct pipe_context *pipe, const struct pipe_blend_state *blend ) { struct i915_context *i915 = i915_context(pipe); - i915->blend = *blend; + i915->blend = blend; i915->dirty |= I915_NEW_BLEND; } +static void i915_delete_blend_state( struct pipe_context *pipe, + const struct pipe_blend_state *blend ) +{ + /*struct i915_context *i915 = i915_context(pipe);*/ + free(blend); +} + static void i915_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { @@ -289,9 +309,12 @@ static void i915_set_vertex_element( struct pipe_context *pipe, void i915_init_state_functions( struct i915_context *i915 ) { + 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; + i915->pipe.set_alpha_test_state = i915_set_alpha_test_state; i915->pipe.set_blend_color = i915_set_blend_color; - i915->pipe.set_blend_state = i915_set_blend_state; i915->pipe.set_clip_state = i915_set_clip_state; i915->pipe.set_clear_color_state = i915_set_clear_color_state; i915->pipe.set_constant_buffer = i915_set_constant_buffer; diff --git a/src/mesa/pipe/i915simple/i915_state_dynamic.c b/src/mesa/pipe/i915simple/i915_state_dynamic.c index e648357754f..49a30fac115 100644 --- a/src/mesa/pipe/i915simple/i915_state_dynamic.c +++ b/src/mesa/pipe/i915simple/i915_state_dynamic.c @@ -82,7 +82,7 @@ static void upload_MODES4( struct i915_context *i915 ) { modes4 |= (_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(i915_translate_logic_op(i915->blend.logicop_func))); + LOGIC_OP_FUNC(i915_translate_logic_op(i915->blend->logicop_func))); } /* Always, so that we know when state is in-active: @@ -204,13 +204,13 @@ static void upload_IAB( struct i915_context *i915 ) unsigned iab = 0; { - unsigned eqRGB = i915->blend.rgb_func; - unsigned srcRGB = i915->blend.rgb_src_factor; - unsigned dstRGB = i915->blend.rgb_dst_factor; + unsigned eqRGB = i915->blend->rgb_func; + unsigned srcRGB = i915->blend->rgb_src_factor; + unsigned dstRGB = i915->blend->rgb_dst_factor; - unsigned eqA = i915->blend.alpha_func; - unsigned srcA = i915->blend.alpha_src_factor; - unsigned dstA = i915->blend.alpha_dst_factor; + unsigned eqA = i915->blend->alpha_func; + unsigned srcA = i915->blend->alpha_src_factor; + unsigned dstA = i915->blend->alpha_dst_factor; /* Special handling for MIN/MAX filter modes handled at * state_tracker level. diff --git a/src/mesa/pipe/i915simple/i915_state_immediate.c b/src/mesa/pipe/i915simple/i915_state_immediate.c index 38a24733e12..aaca534f5ad 100644 --- a/src/mesa/pipe/i915simple/i915_state_immediate.c +++ b/src/mesa/pipe/i915simple/i915_state_immediate.c @@ -145,22 +145,22 @@ static void upload_S5( struct i915_context *i915 ) } /* I915_NEW_BLEND */ - if (i915->blend.logicop_enable) + if (i915->blend->logicop_enable) LIS5 |= S5_LOGICOP_ENABLE; - if (i915->blend.dither) + if (i915->blend->dither) LIS5 |= S5_COLOR_DITHER_ENABLE; - if ((i915->blend.colormask & PIPE_MASK_R) == 0) + if ((i915->blend->colormask & PIPE_MASK_R) == 0) LIS5 |= S5_WRITEDISABLE_RED; - if ((i915->blend.colormask & PIPE_MASK_G) == 0) + if ((i915->blend->colormask & PIPE_MASK_G) == 0) LIS5 |= S5_WRITEDISABLE_GREEN; - if ((i915->blend.colormask & PIPE_MASK_B) == 0) + if ((i915->blend->colormask & PIPE_MASK_B) == 0) LIS5 |= S5_WRITEDISABLE_BLUE; - if ((i915->blend.colormask & PIPE_MASK_A) == 0) + if ((i915->blend->colormask & PIPE_MASK_A) == 0) LIS5 |= S5_WRITEDISABLE_ALPHA; @@ -205,11 +205,11 @@ static void upload_S6( struct i915_context *i915 ) /* I915_NEW_BLEND */ - if (i915->blend.blend_enable) + if (i915->blend->blend_enable) { - unsigned funcRGB = i915->blend.rgb_func; - unsigned srcRGB = i915->blend.rgb_src_factor; - unsigned dstRGB = i915->blend.rgb_dst_factor; + unsigned funcRGB = i915->blend->rgb_func; + unsigned srcRGB = i915->blend->rgb_src_factor; + unsigned dstRGB = i915->blend->rgb_dst_factor; LIS6 |= (S6_CBUF_BLEND_ENABLE | SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index ec5555c38e9..b9af69fc050 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -31,7 +31,7 @@ #include "p_state.h" #include "p_compiler.h" - +struct pipe_state_cache; /** * Software pipeline rendering context. Basically a collection of * state setting functions, plus VBO drawing entrypoint. @@ -85,12 +85,16 @@ 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 (*set_alpha_test_state)( struct pipe_context *, const struct pipe_alpha_test_state * ); - void (*set_blend_state)( struct pipe_context *, - const struct pipe_blend_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 92357808e29..b9c7013e9e1 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -250,9 +250,12 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.max_texture_size = softpipe_max_texture_size; /* state setters */ + 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; + softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; - softpipe->pipe.set_blend_state = softpipe_set_blend_state; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 13d1143c890..7fecf2974ac 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -71,8 +71,9 @@ struct softpipe_context { /* The most recent drawing state as set by the driver: */ + const struct pipe_blend_state *blend; + struct pipe_alpha_test_state alpha_test; - struct pipe_blend_state blend; 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 0f0736479f2..2fcbea1f22e 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -11,12 +11,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->quad.first = sp->quad.output; - if (sp->blend.colormask != 0xf) { + if (sp->blend->colormask != 0xf) { sp->quad.colormask->next = sp->quad.first; sp->quad.first = sp->quad.colormask; } - if (sp->blend.blend_enable) { + if (sp->blend->blend_enable) { sp->quad.blend->next = sp->quad.first; sp->quad.first = sp->quad.blend; } diff --git a/src/mesa/pipe/softpipe/sp_quad_blend.c b/src/mesa/pipe/softpipe/sp_quad_blend.c index e5335f3b19a..6c7135e53c5 100755 --- a/src/mesa/pipe/softpipe/sp_quad_blend.c +++ b/src/mesa/pipe/softpipe/sp_quad_blend.c @@ -111,7 +111,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Compute src/first term RGB */ - switch (softpipe->blend.rgb_src_factor) { + switch (softpipe->blend->rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[0], quad->outputs.color[0]); /* R */ VEC4_COPY(source[1], quad->outputs.color[1]); /* G */ @@ -253,7 +253,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Compute src/first term A */ - switch (softpipe->blend.alpha_src_factor) { + switch (softpipe->blend->alpha_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[3], quad->outputs.color[3]); /* A */ break; @@ -275,7 +275,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Compute dest/second term RGB */ - switch (softpipe->blend.rgb_dst_factor) { + switch (softpipe->blend->rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -301,7 +301,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Compute dest/second term A */ - switch (softpipe->blend.alpha_dst_factor) { + switch (softpipe->blend->alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -323,7 +323,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Combine RGB terms */ - switch (softpipe->blend.rgb_func) { + switch (softpipe->blend->rgb_func) { case PIPE_BLEND_ADD: VEC4_ADD(quad->outputs.color[0], source[0], dest[0]); /* R */ VEC4_ADD(quad->outputs.color[1], source[1], dest[1]); /* G */ @@ -356,7 +356,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) /* * Combine A terms */ - switch (softpipe->blend.alpha_func) { + switch (softpipe->blend->alpha_func) { case PIPE_BLEND_ADD: VEC4_ADD(quad->outputs.color[3], source[3], dest[3]); /* A */ break; diff --git a/src/mesa/pipe/softpipe/sp_quad_colormask.c b/src/mesa/pipe/softpipe/sp_quad_colormask.c index 7bb65bf8c80..c3e110532a1 100644 --- a/src/mesa/pipe/softpipe/sp_quad_colormask.c +++ b/src/mesa/pipe/softpipe/sp_quad_colormask.c @@ -49,19 +49,19 @@ colormask_quad(struct quad_stage *qs, struct quad_header *quad) sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest); /* R */ - if (!(softpipe->blend.colormask & PIPE_MASK_R)) + if (!(softpipe->blend->colormask & PIPE_MASK_R)) COPY_4V(quad->outputs.color[0], dest[0]); /* G */ - if (!(softpipe->blend.colormask & PIPE_MASK_G)) + if (!(softpipe->blend->colormask & PIPE_MASK_G)) COPY_4V(quad->outputs.color[1], dest[1]); /* B */ - if (!(softpipe->blend.colormask & PIPE_MASK_B)) + if (!(softpipe->blend->colormask & PIPE_MASK_B)) COPY_4V(quad->outputs.color[2], dest[2]); /* A */ - if (!(softpipe->blend.colormask & PIPE_MASK_A)) + if (!(softpipe->blend->colormask & PIPE_MASK_A)) COPY_4V(quad->outputs.color[3], dest[3]); /* pass quad to next stage */ diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index f40ebe3e2b8..e2b1a2a1641 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -33,6 +33,13 @@ #include "pipe/p_state.h" +const struct pipe_blend_state * +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 softpipe_delete_blend_state(struct pipe_context *, + const struct pipe_blend_state *); void softpipe_set_framebuffer_state( struct pipe_context *, const struct pipe_framebuffer_state * ); @@ -40,9 +47,6 @@ void softpipe_set_framebuffer_state( struct pipe_context *, void softpipe_set_alpha_test_state( struct pipe_context *, const struct pipe_alpha_test_state * ); -void softpipe_set_blend_state( struct pipe_context *, - const struct pipe_blend_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 b2e85d86cc0..57f2df79238 100644 --- a/src/mesa/pipe/softpipe/sp_state_blend.c +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -30,17 +30,32 @@ #include "sp_context.h" #include "sp_state.h" +const struct pipe_blend_state * +softpipe_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state)); + memcpy(new_blend, blend, sizeof(struct pipe_blend_state)); + + return new_blend; +} -void softpipe_set_blend_state( struct pipe_context *pipe, +void softpipe_bind_blend_state( struct pipe_context *pipe, const struct pipe_blend_state *blend ) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->blend = *blend; + softpipe->blend = blend; softpipe->dirty |= SP_NEW_BLEND; } +void softpipe_delete_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend ) +{ + free(blend); +} + void softpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) diff --git a/src/mesa/sources b/src/mesa/sources index ec561294c5a..e57942d6641 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -186,6 +186,9 @@ TGSIDECO_SOURCES = \ TGSIMESA_SOURCES = \ pipe/tgsi/mesa/mesa_to_tgsi.c +STATECACHE_SOURCES = \ + cso_cache/cso_cache.c + STATETRACKER_SOURCES = \ state_tracker/st_atom.c \ state_tracker/st_atom_alphatest.c \ @@ -373,6 +376,7 @@ SOLO_SOURCES = \ $(TGSIEXEC_SOURCES) \ $(TGSIDECO_SOURCES) \ $(TGSIMESA_SOURCES) \ + $(STATECACHE_SOURCES) \ $(STATETRACKER_SOURCES) \ $(TNL_SOURCES) \ $(SHADER_SOURCES) \ diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index afd21a6141c..d007d50ad39 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -36,6 +36,7 @@ #include "st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "cso_cache/cso_cache.h" /** @@ -209,10 +210,14 @@ update_blend( struct st_context *st ) if (st->ctx->Color.DitherFlag) blend.dither = 1; - if (memcmp(&blend, &st->state.blend, sizeof(blend)) != 0) { + struct pipe_blend_state *real_blend = + cso_cached_blend_state(st, &blend); + + if (st->state.blend != real_blend) { /* state has changed */ - st->state.blend = blend; /* struct copy */ - st->pipe->set_blend_state(st->pipe, &blend); /* set new state */ + st->state.blend = real_blend; + /* bind new state */ + st->pipe->bind_blend_state(st->pipe, real_blend); } if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) { diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index fa222df2a48..dc8a84af08f 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -49,6 +49,8 @@ #include "pipe/tgsi/mesa/mesa_to_tgsi.h" +#include "cso_cache/cso_cache.h" + #include "vf/vf.h" @@ -295,7 +297,8 @@ clear_with_quad(GLcontext *ctx, if (st->ctx->Color.DitherFlag) blend.dither = 1; } - pipe->set_blend_state(pipe, &blend); + const struct pipe_blend_state *state = cso_cached_blend_state(st, &blend); + pipe->bind_blend_state(pipe, state); } /* depth state: always pass */ @@ -390,7 +393,7 @@ clear_with_quad(GLcontext *ctx, /* Restore pipe state */ pipe->set_alpha_test_state(pipe, &st->state.alpha_test); - pipe->set_blend_state(pipe, &st->state.blend); + pipe->bind_blend_state(pipe, st->state.blend); pipe->set_depth_state(pipe, &st->state.depth); pipe->set_fs_state(pipe, &st->state.fs); pipe->set_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 e2280cdafa8..c2d231cdb5d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -474,8 +474,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->blend_enable || + st->state.blend->logicop_enable || st->state.depth.enabled) /* XXX more checks */ return GL_TRUE; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 6ab643f1fef..26815d5cd42 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -45,6 +45,7 @@ #include "st_program.h" #include "pipe/p_context.h" #include "pipe/draw/draw_context.h" +#include "cso_cache/cso_cache.h" void st_invalidate_state(GLcontext * ctx, GLuint new_state) @@ -71,6 +72,8 @@ struct st_context *st_create_context( GLcontext *ctx, st->dirty.mesa = ~0; st->dirty.st = ~0; + st->cache = cso_cache_create(); + st_init_atoms( st ); st_init_draw( st ); @@ -112,6 +115,7 @@ void st_destroy_context( struct st_context *st ) /*st_destroy_cb_teximage( st );*/ st_destroy_cb_texture( st ); #endif + cso_cache_destroy( st->cache ); st->pipe->destroy( st->pipe ); FREE( st ); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 56cae7d9734..bd2efdb960b 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -39,7 +39,7 @@ struct st_texture_image; struct st_fragment_program; struct draw_context; struct draw_stage; - +struct cso_cache; #define ST_NEW_MESA 0x1 /* Mesa state has changed */ #define ST_NEW_FRAGMENT_PROGRAM 0x2 @@ -74,8 +74,9 @@ struct st_context * though, we just shove random objects across the interface. */ struct { + const struct pipe_blend_state *blend; + struct pipe_alpha_test_state alpha_test; - struct pipe_blend_state blend; struct pipe_blend_color blend_color; struct pipe_clear_color_state clear_color; struct pipe_clip_state clip; @@ -122,6 +123,8 @@ struct st_context struct st_fragment_program *fp; struct pipe_buffer_handle *default_attrib_buffer; + + struct cso_cache *cache; }; |