summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/cso_cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/cso_cache')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.c21
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h16
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c336
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h52
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