summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2008-04-22 18:20:34 -0400
committerZack Rusin <[email protected]>2008-04-22 18:32:36 -0400
commitf088b53769aacbee20135d912c33d688b6002011 (patch)
tree89e68585a1cc17695cd57b8c2ef9641a7ae44c77 /src/gallium
parent500c41b8ba3ad025c69e63a2c74da90674a8037d (diff)
Cache translate's structs for emits and fetches.
Results in a fair speed improvement.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c63
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c65
2 files changed, 114 insertions, 14 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index 490da4cca3a..d35329aba0f 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -33,13 +33,66 @@
#include "draw/draw_pt.h"
#include "translate/translate.h"
+#include "cso_cache/cso_cache.h"
+#include "cso_cache/cso_hash.h"
struct pt_emit {
struct draw_context *draw;
struct translate *translate;
+
+ struct cso_hash *hash;
};
+static INLINE unsigned translate_hash_key_size(struct translate_key *key)
+{
+ unsigned size = sizeof(struct translate_key) -
+ sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements);
+ return size;
+}
+
+static INLINE unsigned create_key(struct translate_key *key)
+{
+ unsigned hash_key;
+ unsigned size = translate_hash_key_size(key);
+ /*debug_printf("key size = %d, (els = %d)\n",
+ size, key->nr_elements);*/
+ hash_key = cso_construct_key(key, size);
+ return hash_key;
+}
+
+static struct translate *cached_translate(struct pt_emit *emit,
+ struct translate_key *key)
+{
+ unsigned hash_key = create_key(key);
+ struct cso_hash_iter iter = cso_hash_find(emit->hash, hash_key);
+ struct translate *translate = 0;
+
+ if (cso_hash_iter_is_null(iter)) {
+ translate = translate_create(key);
+ cso_hash_insert(emit->hash, hash_key, translate);
+ /*debug_printf("\tCREATED with %d\n", hash_key);*/
+ } else {
+ translate = cso_hash_iter_data(iter);
+ /*debug_printf("\tOK with %d\n", hash_key);*/
+ }
+
+ return translate;
+}
+
+
+static INLINE void delete_translates(struct pt_emit *emit)
+{
+ struct cso_hash *hash = emit->hash;
+ struct cso_hash_iter iter = cso_hash_first_node(hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ struct translate *state = (struct translate*)cso_hash_iter_data(iter);
+ iter = cso_hash_iter_next(iter);
+ if (state) {
+ state->release(state);
+ }
+ }
+}
void draw_pt_emit_prepare( struct pt_emit *emit,
unsigned prim )
@@ -123,10 +176,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
if (!emit->translate ||
memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0)
{
- if (emit->translate)
- emit->translate->release(emit->translate);
-
- emit->translate = translate_create( &hw_key );
+ emit->translate = cached_translate(emit, &hw_key);
}
}
@@ -188,14 +238,15 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
return NULL;
emit->draw = draw;
+ emit->hash = cso_hash_create();
return emit;
}
void draw_pt_emit_destroy( struct pt_emit *emit )
{
- if (emit->translate)
- emit->translate->release( emit->translate );
+ delete_translates(emit);
+ cso_hash_delete(emit->hash);
FREE(emit);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index f98bce6eac0..93da811ed81 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -33,16 +33,67 @@
#include "draw/draw_pt.h"
#include "translate/translate.h"
+#include "cso_cache/cso_cache.h"
+#include "cso_cache/cso_hash.h"
struct pt_fetch {
struct draw_context *draw;
struct translate *translate;
-
+
unsigned vertex_size;
+
+ struct cso_hash *hash;
};
+static INLINE unsigned translate_hash_key_size(struct translate_key *key)
+{
+ unsigned size = sizeof(struct translate_key) -
+ sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements);
+ return size;
+}
+
+static INLINE unsigned create_key(struct translate_key *key)
+{
+ unsigned hash_key;
+ unsigned size = translate_hash_key_size(key);
+ /*debug_printf("key size = %d, (els = %d)\n",
+ size, key->nr_elements);*/
+ hash_key = cso_construct_key(key, size);
+ return hash_key;
+}
+
+static struct translate *cached_translate(struct pt_fetch *fetch,
+ struct translate_key *key)
+{
+ unsigned hash_key = create_key(key);
+ struct cso_hash_iter iter = cso_hash_find(fetch->hash, hash_key);
+ struct translate *translate = 0;
+
+ if (cso_hash_iter_is_null(iter)) {
+ translate = translate_create(key);
+ cso_hash_insert(fetch->hash, hash_key, translate);
+ /*debug_printf("\tCREATED with %d\n", hash_key);*/
+ } else {
+ translate = cso_hash_iter_data(iter);
+ /*debug_printf("\tOK with %d\n", hash_key);*/
+ }
+
+ return translate;
+}
+static INLINE void delete_translates(struct pt_fetch *fetch)
+{
+ struct cso_hash *hash = fetch->hash;
+ struct cso_hash_iter iter = cso_hash_first_node(hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ struct translate *state = (struct translate*)cso_hash_iter_data(iter);
+ iter = cso_hash_iter_next(iter);
+ if (state) {
+ state->release(state);
+ }
+ }
+}
/* Perform the fetch from API vertex elements & vertex buffers, to a
* contiguous set of float[4] attributes as required for the
@@ -112,10 +163,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
if (!fetch->translate ||
memcmp(&fetch->translate->key, &key, sizeof(key)) != 0)
{
- if (fetch->translate)
- fetch->translate->release(fetch->translate);
-
- fetch->translate = translate_create( &key );
+ fetch->translate = cached_translate(fetch, &key);
{
static struct vertex_header vh = { 0, 0, 0, 0xffff };
@@ -159,15 +207,16 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
if (!fetch)
return NULL;
-
+
fetch->draw = draw;
+ fetch->hash = cso_hash_create();
return fetch;
}
void draw_pt_fetch_destroy( struct pt_fetch *fetch )
{
- if (fetch->translate)
- fetch->translate->release( fetch->translate );
+ delete_translates(fetch);
+ cso_hash_delete(fetch->hash);
FREE(fetch);
}