diff options
Diffstat (limited to 'src/gallium/auxiliary/cso_cache')
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_cache.c | 21 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_cache.h | 16 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.c | 336 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.h | 52 |
4 files changed, 284 insertions, 141 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index a6a07e72c2..900c64df4b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -43,6 +43,7 @@ struct cso_cache { struct cso_hash *vs_hash; struct cso_hash *rasterizer_hash; struct cso_hash *sampler_hash; + struct cso_hash *velements_hash; int max_size; cso_sanitize_callback sanitize_cb; @@ -108,6 +109,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_VELEMENTS: + hash = sc->velements_hash; + break; } return hash; @@ -161,6 +165,13 @@ static void delete_vs_state(void *state, void *data) FREE(state); } +static void delete_velements(void *state, void *data) +{ + struct cso_velements *cso = (struct cso_velements *)state; + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); +} static INLINE void delete_cso(void *state, enum cso_cache_type type) { @@ -183,6 +194,9 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type) case CSO_VERTEX_SHADER: delete_vs_state(state, 0); break; + case CSO_VELEMENTS: + delete_velements(state, 0); + break; default: assert(0); FREE(state); @@ -294,6 +308,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->velements_hash = cso_hash_create(); sc->sanitize_cb = sanitize_cb; sc->sanitize_data = 0; @@ -325,6 +340,9 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, case CSO_VERTEX_SHADER: hash = sc->vs_hash; break; + case CSO_VELEMENTS: + hash = sc->velements_hash; + break; } iter = cso_hash_first_node(hash); @@ -351,6 +369,7 @@ void cso_cache_delete(struct cso_cache *sc) cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0); cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0); cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0); + cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0); cso_hash_delete(sc->blend_hash); cso_hash_delete(sc->sampler_hash); @@ -358,6 +377,7 @@ 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->velements_hash); FREE(sc); } @@ -372,6 +392,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number) sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size); sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size); sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size); + sanitize_hash(sc, sc->velements_hash, CSO_VELEMENTS, sc->max_size); } int cso_maximum_cache_size(const struct cso_cache *sc) diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index eea60b940b..fb09b83c62 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -53,6 +53,7 @@ * - rasterizer (old setup) * - sampler * - vertex shader + * - vertex elements * * Things that are not constant state objects include: * - blend_color @@ -90,7 +91,8 @@ enum cso_cache_type { CSO_DEPTH_STENCIL_ALPHA, CSO_RASTERIZER, CSO_FRAGMENT_SHADER, - CSO_VERTEX_SHADER + CSO_VERTEX_SHADER, + CSO_VELEMENTS }; typedef void (*cso_state_callback)(void *ctx, void *obj); @@ -144,6 +146,18 @@ struct cso_sampler { struct pipe_context *context; }; +struct cso_velems_state { + unsigned count; + struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS]; +}; + +struct cso_velements { + struct cso_velems_state state; + void *data; + cso_state_callback delete_state; + struct pipe_context *context; +}; + unsigned cso_construct_key(void *item, int item_size); struct cso_cache *cso_cache_create(void); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index a7335c340c..d6f8dd34bf 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -37,7 +37,9 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_parse.h" #include "cso_cache/cso_context.h" @@ -69,17 +71,17 @@ struct cso_context { unsigned nr_vertex_samplers_saved; void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; - uint nr_textures; + uint nr_fragment_sampler_views; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_vertex_textures; + uint nr_vertex_sampler_views; + struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; - uint nr_textures_saved; - struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_fragment_sampler_views_saved; + struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS]; - uint nr_vertex_textures_saved; - struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_vertex_sampler_views_saved; + struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS]; /** Current and saved state. * The saved state is used as a 1-deep stack. @@ -89,6 +91,7 @@ struct cso_context { void *rasterizer, *rasterizer_saved; void *fragment_shader, *fragment_shader_saved, *geometry_shader; void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved; + void *velements, *velements_saved; struct pipe_clip_state clip; struct pipe_clip_state clip_saved; @@ -174,6 +177,20 @@ static boolean delete_vs_state(struct cso_context *ctx, void *state) return FALSE; } +static boolean delete_vertex_elements(struct cso_context *ctx, + void *state) +{ + struct cso_velements *cso = (struct cso_velements *)state; + + if (ctx->velements == cso->data) + return FALSE; + + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return TRUE; +} + static INLINE boolean delete_cso(struct cso_context *ctx, void *state, enum cso_cache_type type) @@ -197,6 +214,9 @@ static INLINE boolean delete_cso(struct cso_context *ctx, case CSO_VERTEX_SHADER: return delete_vs_state(ctx, state); break; + case CSO_VELEMENTS: + return delete_vertex_elements(ctx, state); + break; default: assert(0); FREE(state); @@ -271,16 +291,17 @@ void cso_release_all( struct cso_context *ctx ) ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); ctx->pipe->bind_fs_state( ctx->pipe, NULL ); ctx->pipe->bind_vs_state( ctx->pipe, NULL ); + ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL ); } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - pipe_texture_reference(&ctx->textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL); + pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL); } free_framebuffer_state(&ctx->fb); @@ -597,114 +618,6 @@ cso_restore_vertex_samplers(struct cso_context *ctx) } -enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, - uint count, - struct pipe_texture **textures ) -{ - uint i; - - ctx->nr_textures = count; - - for (i = 0; i < count; i++) - pipe_texture_reference(&ctx->textures[i], textures[i]); - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures); - - return PIPE_OK; -} - -void cso_save_sampler_textures( struct cso_context *ctx ) -{ - uint i; - - ctx->nr_textures_saved = ctx->nr_textures; - for (i = 0; i < ctx->nr_textures; i++) { - assert(!ctx->textures_saved[i]); - pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); - } -} - -void cso_restore_sampler_textures( struct cso_context *ctx ) -{ - uint i; - - ctx->nr_textures = ctx->nr_textures_saved; - - for (i = 0; i < ctx->nr_textures; i++) { - pipe_texture_reference(&ctx->textures[i], NULL); - ctx->textures[i] = ctx->textures_saved[i]; - ctx->textures_saved[i] = NULL; - } - for ( ; i < PIPE_MAX_SAMPLERS; i++) - pipe_texture_reference(&ctx->textures[i], NULL); - - ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); - - ctx->nr_textures_saved = 0; -} - - - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *ctx, - uint count, - struct pipe_texture **textures) -{ - uint i; - - ctx->nr_vertex_textures = count; - - for (i = 0; i < count; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], textures[i]); - } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - } - - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures); - - return PIPE_OK; -} - -void -cso_save_vertex_sampler_textures(struct cso_context *ctx) -{ - uint i; - - ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures; - for (i = 0; i < ctx->nr_vertex_textures; i++) { - assert(!ctx->vertex_textures_saved[i]); - pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]); - } -} - -void -cso_restore_vertex_sampler_textures(struct cso_context *ctx) -{ - uint i; - - ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved; - - for (i = 0; i < ctx->nr_vertex_textures; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - ctx->vertex_textures[i] = ctx->vertex_textures_saved[i]; - ctx->vertex_textures_saved[i] = NULL; - } - for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - pipe_texture_reference(&ctx->vertex_textures[i], NULL); - } - - ctx->pipe->set_vertex_sampler_textures(ctx->pipe, - ctx->nr_vertex_textures, - ctx->vertex_textures); - - ctx->nr_vertex_textures_saved = 0; -} - - - enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { @@ -1130,7 +1043,6 @@ void cso_restore_geometry_shader(struct cso_context *ctx) ctx->geometry_shader_saved = NULL; } - /* clip state */ static INLINE void @@ -1180,3 +1092,185 @@ cso_restore_clip(struct cso_context *ctx) ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved); } } + +enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, + unsigned count, + const struct pipe_vertex_element *states) +{ + unsigned key_size, hash_key; + struct cso_hash_iter iter; + void *handle; + struct cso_velems_state velems_state; + + /* need to include the count into the stored state data too. + Otherwise first few count pipe_vertex_elements could be identical even if count + is different, and there's no guarantee the hash would be different in that + case neither */ + key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned); + velems_state.count = count; + memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count); + hash_key = cso_construct_key((void*)&velems_state, key_size); + iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size); + + if (cso_hash_iter_is_null(iter)) { + struct cso_velements *cso = MALLOC(sizeof(struct cso_velements)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + + memcpy(&cso->state, &velems_state, key_size); + cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state.velems[0]); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + + handle = cso->data; + } + else { + handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data; + } + + if (ctx->velements != handle) { + ctx->velements = handle; + ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle); + } + return PIPE_OK; +} + +void cso_save_vertex_elements(struct cso_context *ctx) +{ + assert(!ctx->velements_saved); + ctx->velements_saved = ctx->velements; +} + +void cso_restore_vertex_elements(struct cso_context *ctx) +{ + if (ctx->velements != ctx->velements_saved) { + ctx->velements = ctx->velements_saved; + ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved); + } + ctx->velements_saved = NULL; +} + +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(count, cso->nr_fragment_sampler_views), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = count; +} + +void +cso_save_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views; + + for (i = 0; i < cso->nr_fragment_sampler_views; i++) { + assert(!cso->fragment_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], + cso->fragment_sampler_views[i]); + } +} + +void +cso_restore_fragment_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_fragment_sampler_views; i++) { + pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL); + } + + cso->pipe->set_fragment_sampler_views(cso->pipe, + MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved), + cso->fragment_sampler_views); + + cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved; + cso->nr_fragment_sampler_views_saved = 0; +} + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views) +{ + uint i; + + for (i = 0; i < count; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(count, cso->nr_vertex_sampler_views), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = count; +} + +void +cso_save_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views; + + for (i = 0; i < cso->nr_vertex_sampler_views; i++) { + assert(!cso->vertex_sampler_views_saved[i]); + + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], + cso->vertex_sampler_views[i]); + } +} + +void +cso_restore_vertex_sampler_views(struct cso_context *cso) +{ + uint i; + + for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]); + pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL); + } + for (; i < cso->nr_vertex_sampler_views; i++) { + pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL); + } + + cso->pipe->set_vertex_sampler_views(cso->pipe, + MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved), + cso->vertex_sampler_views); + + cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved; + cso->nr_vertex_sampler_views_saved = 0; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 251a9a644f..d6bcb1fe8f 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -103,24 +103,11 @@ void cso_single_vertex_sampler_done(struct cso_context *cso); - -enum pipe_error cso_set_sampler_textures( struct cso_context *cso, - uint count, - struct pipe_texture **textures ); -void cso_save_sampler_textures( struct cso_context *cso ); -void cso_restore_sampler_textures( struct cso_context *cso ); - - - -enum pipe_error -cso_set_vertex_sampler_textures(struct cso_context *cso, - uint count, - struct pipe_texture **textures); -void -cso_save_vertex_sampler_textures(struct cso_context *cso); -void -cso_restore_vertex_sampler_textures(struct cso_context *cso); - +enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, + unsigned count, + const struct pipe_vertex_element *states); +void cso_save_vertex_elements(struct cso_context *ctx); +void cso_restore_vertex_elements(struct cso_context *ctx); /* These aren't really sensible -- most of the time the api provides @@ -157,7 +144,6 @@ void cso_save_geometry_shader(struct cso_context *cso); void cso_restore_geometry_shader(struct cso_context *cso); - enum pipe_error cso_set_framebuffer(struct cso_context *cso, const struct pipe_framebuffer_state *fb); void cso_save_framebuffer(struct cso_context *cso); @@ -193,6 +179,34 @@ void cso_restore_clip(struct cso_context *cso); +/* fragment sampler view state */ + +void +cso_set_fragment_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_fragment_sampler_views(struct cso_context *cso); + +void +cso_restore_fragment_sampler_views(struct cso_context *cso); + + +/* vertex sampler view state */ + +void +cso_set_vertex_sampler_views(struct cso_context *cso, + uint count, + struct pipe_sampler_view **views); + +void +cso_save_vertex_sampler_views(struct cso_context *cso); + +void +cso_restore_vertex_sampler_views(struct cso_context *cso); + + #ifdef __cplusplus } #endif |