summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2010-03-09 14:19:29 +0100
committerRoland Scheidegger <sroland@vmware.com>2010-03-09 14:19:29 +0100
commitfe9f8536f1b1e7a3a2ac10afd8078e8f4d327578 (patch)
tree41a84ba1db471ec26f2e4aa149059bc816ae6e6e
parent4240987cecdaaaeb2d6188f7c83ff4cb8e670c59 (diff)
auxiliary: fix vertex elements cso
potentially could have got a match even though the cso was different (in case of different count and first few elements the same).
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h7
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c19
2 files changed, 19 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h
index d884d5410f..fb09b83c62 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.h
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.h
@@ -146,8 +146,13 @@ 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 pipe_vertex_element state[PIPE_MAX_ATTRIBS];
+ struct cso_velems_state state;
void *data;
cso_state_callback delete_state;
struct pipe_context *context;
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 95e3c18e53..510366a8d4 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -1152,18 +1152,25 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
unsigned key_size, hash_key;
struct cso_hash_iter iter;
void *handle;
-
- key_size = sizeof(struct pipe_vertex_element) * count;
- hash_key = cso_construct_key((void*)states, key_size);
- iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)states, key_size);
+ 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, states, key_size);
- cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state[0]);
+ 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;