Replacing mesa's main hash with one that handles collisions, moving state_tracker related caching to the state tracker to keep cso cache independent of it. Cleanups.tags/mesa_20090313
@@ -29,9 +29,10 @@ | |||
*/ | |||
#include "cso_cache.h" | |||
#include "cso_hash.h" | |||
#if 1 | |||
static unsigned hash_key( const void *key, unsigned key_size ) | |||
static unsigned hash_key(const void *key, unsigned key_size) | |||
{ | |||
unsigned *ikey = (unsigned *)key; | |||
unsigned hash = 0, i; | |||
@@ -63,114 +64,84 @@ static unsigned hash_key(const unsigned char *p, int n) | |||
unsigned cso_construct_key(void *item, int item_size) | |||
{ | |||
return hash_key((const unsigned char*)(item), item_size); | |||
return hash_key((item), item_size); | |||
} | |||
struct cso_cache_item * | |||
static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) | |||
{ | |||
struct cso_hash *hash = 0; | |||
switch(type) { | |||
case CSO_BLEND: | |||
hash = sc->blend_hash; | |||
} | |||
return hash; | |||
} | |||
static int _cso_size_for_type(enum cso_cache_type type) | |||
{ | |||
switch(type) { | |||
case CSO_BLEND: | |||
return sizeof(struct pipe_blend_state); | |||
} | |||
return 0; | |||
} | |||
struct cso_hash_iter | |||
cso_insert_state(struct cso_cache *sc, | |||
unsigned hash_key, | |||
void *state, int state_size) | |||
unsigned hash_key, enum cso_cache_type type, | |||
void *state) | |||
{ | |||
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_hash *hash = _cso_hash_for_type(sc, type); | |||
return cso_hash_insert(hash, hash_key, state); | |||
} | |||
struct cso_cache_item * | |||
struct cso_hash_iter | |||
cso_find_state(struct cso_cache *sc, | |||
unsigned hash_key, | |||
void *state, int state_size) | |||
unsigned hash_key, enum cso_cache_type type) | |||
{ | |||
struct cso_cache_item *found_state = | |||
_mesa_HashLookup(sc->hash, hash_key); | |||
struct cso_hash *hash = _cso_hash_for_type(sc, type); | |||
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; | |||
return cso_hash_find(hash, hash_key); | |||
} | |||
struct cso_cache_item * | |||
cso_remove_state(struct cso_cache *sc, | |||
unsigned hash_key, | |||
void *state, int state_size) | |||
struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, | |||
unsigned hash_key, enum cso_cache_type type, | |||
void *templ) | |||
{ | |||
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); | |||
} | |||
struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); | |||
int size = _cso_size_for_type(type); | |||
while (!cso_hash_iter_is_null(iter)) { | |||
void *iter_data = cso_hash_iter_data(iter); | |||
if (!memcmp(iter_data, templ, size)) | |||
return iter; | |||
iter = cso_hash_iter_next(iter); | |||
} | |||
return found_state; | |||
return iter; | |||
} | |||
void * cso_take_state(struct cso_cache *sc, | |||
unsigned hash_key, enum cso_cache_type type) | |||
{ | |||
struct cso_hash *hash = _cso_hash_for_type(sc, type); | |||
return cso_hash_take(hash, hash_key); | |||
} | |||
struct cso_cache *cso_cache_create(void) | |||
{ | |||
struct cso_cache *sc = malloc(sizeof(struct cso_cache)); | |||
sc->hash = _mesa_NewHashTable(); | |||
sc->blend_hash = cso_hash_create(); | |||
return sc; | |||
} | |||
void cso_cache_destroy(struct cso_cache *sc) | |||
void cso_cache_delete(struct cso_cache *sc) | |||
{ | |||
assert(sc); | |||
assert(sc->hash); | |||
_mesa_DeleteHashTable(sc->hash); | |||
assert(sc->blend_hash); | |||
cso_hash_delete(sc->blend_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; | |||
} |
@@ -33,43 +33,34 @@ | |||
#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_hash; | |||
struct cso_cache { | |||
struct _mesa_HashTable *hash; | |||
struct cso_hash *blend_hash; | |||
}; | |||
void cso_cache_destroy(struct cso_cache *sc); | |||
struct cso_cache *cso_cache_create(void); | |||
enum cso_cache_type { | |||
CSO_BLEND, | |||
}; | |||
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 cso_cache *cso_cache_create(void); | |||
void cso_cache_delete(struct cso_cache *sc); | |||
struct pipe_blend_state *cso_cached_blend_state( | |||
struct st_context *pipe, | |||
const struct pipe_blend_state *state); | |||
struct cso_hash_iter cso_insert_state(struct cso_cache *sc, | |||
unsigned hash_key, enum cso_cache_type type, | |||
void *state); | |||
struct cso_hash_iter cso_find_state(struct cso_cache *sc, | |||
unsigned hash_key, enum cso_cache_type type); | |||
struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, | |||
unsigned hash_key, enum cso_cache_type type, | |||
void *templ); | |||
void * cso_take_state(struct cso_cache *sc, unsigned hash_key, | |||
enum cso_cache_type type); | |||
#endif |
@@ -0,0 +1,381 @@ | |||
/************************************************************************** | |||
* | |||
* 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 <zack@tungstengraphics.com> | |||
*/ | |||
#include "cso_hash.h" | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <assert.h> | |||
#define MAX(a, b) ((a > b) ? (a) : (b)) | |||
static const int MinNumBits = 4; | |||
static const unsigned char prime_deltas[] = { | |||
0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3, | |||
1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0 | |||
}; | |||
static int primeForNumBits(int numBits) | |||
{ | |||
return (1 << numBits) + prime_deltas[numBits]; | |||
} | |||
/* | |||
Returns the smallest integer n such that | |||
primeForNumBits(n) >= hint. | |||
*/ | |||
static int countBits(int hint) | |||
{ | |||
int numBits = 0; | |||
int bits = hint; | |||
while (bits > 1) { | |||
bits >>= 1; | |||
numBits++; | |||
} | |||
if (numBits >= (int)sizeof(prime_deltas)) { | |||
numBits = sizeof(prime_deltas) - 1; | |||
} else if (primeForNumBits(numBits) < hint) { | |||
++numBits; | |||
} | |||
return numBits; | |||
} | |||
struct cso_node { | |||
struct cso_node *next; | |||
unsigned key; | |||
void *value; | |||
}; | |||
struct cso_hash_data { | |||
struct cso_node *fakeNext; | |||
struct cso_node **buckets; | |||
int size; | |||
int nodeSize; | |||
short userNumBits; | |||
short numBits; | |||
int numBuckets; | |||
}; | |||
struct cso_hash { | |||
union { | |||
struct cso_hash_data *d; | |||
struct cso_node *e; | |||
} data; | |||
}; | |||
static void *cso_data_allocate_node(struct cso_hash_data *hash) | |||
{ | |||
return malloc(hash->nodeSize); | |||
} | |||
static void cso_data_free_node(void *node) | |||
{ | |||
free(node); | |||
} | |||
static struct cso_node * | |||
cso_hash_create_node(struct cso_hash *hash, | |||
unsigned akey, void *avalue, | |||
struct cso_node **anextNode) | |||
{ | |||
struct cso_node *node = cso_data_allocate_node(hash->data.d); | |||
node->key = akey; | |||
node->value = avalue; | |||
node->next = (struct cso_node*)(*anextNode); | |||
*anextNode = node; | |||
++hash->data.d->size; | |||
return node; | |||
} | |||
static void cso_data_rehash(struct cso_hash_data *hash, int hint) | |||
{ | |||
if (hint < 0) { | |||
hint = countBits(-hint); | |||
if (hint < MinNumBits) | |||
hint = MinNumBits; | |||
hash->userNumBits = hint; | |||
while (primeForNumBits(hint) < (hash->size >> 1)) | |||
++hint; | |||
} else if (hint < MinNumBits) { | |||
hint = MinNumBits; | |||
} | |||
if (hash->numBits != hint) { | |||
struct cso_node *e = (struct cso_node *)(hash); | |||
struct cso_node **oldBuckets = hash->buckets; | |||
int oldNumBuckets = hash->numBuckets; | |||
int i = 0; | |||
hash->numBits = hint; | |||
hash->numBuckets = primeForNumBits(hint); | |||
hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); | |||
for (i = 0; i < hash->numBuckets; ++i) | |||
hash->buckets[i] = e; | |||
for (i = 0; i < oldNumBuckets; ++i) { | |||
struct cso_node *firstNode = oldBuckets[i]; | |||
while (firstNode != e) { | |||
unsigned h = firstNode->key; | |||
struct cso_node *lastNode = firstNode; | |||
while (lastNode->next != e && lastNode->next->key == h) | |||
lastNode = lastNode->next; | |||
struct cso_node *afterLastNode = lastNode->next; | |||
struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; | |||
while (*beforeFirstNode != e) | |||
beforeFirstNode = &(*beforeFirstNode)->next; | |||
lastNode->next = *beforeFirstNode; | |||
*beforeFirstNode = firstNode; | |||
firstNode = afterLastNode; | |||
} | |||
} | |||
free(oldBuckets); | |||
} | |||
} | |||
static void cso_data_might_grow(struct cso_hash_data *hash) | |||
{ | |||
if (hash->size >= hash->numBuckets) | |||
cso_data_rehash(hash, hash->numBits + 1); | |||
} | |||
static void cso_data_has_shrunk(struct cso_hash_data *hash) | |||
{ | |||
if (hash->size <= (hash->numBuckets >> 3) && | |||
hash->numBits > hash->userNumBits) { | |||
int max = MAX(hash->numBits-2, hash->userNumBits); | |||
cso_data_rehash(hash, max); | |||
} | |||
} | |||
static struct cso_node *cso_data_first_node(struct cso_hash_data *hash) | |||
{ | |||
struct cso_node *e = (struct cso_node *)(hash); | |||
struct cso_node **bucket = hash->buckets; | |||
int n = hash->numBuckets; | |||
while (n--) { | |||
if (*bucket != e) | |||
return *bucket; | |||
++bucket; | |||
} | |||
return e; | |||
} | |||
static struct cso_node **cso_hash_find_node(struct cso_hash *hash, unsigned akey) | |||
{ | |||
struct cso_node **node; | |||
if (hash->data.d->numBuckets) { | |||
node = (struct cso_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]); | |||
assert(*node == hash->data.e || (*node)->next); | |||
while (*node != hash->data.e && (*node)->key != akey) | |||
node = &(*node)->next; | |||
} else { | |||
node = (struct cso_node **)((const struct cso_node * const *)(&hash->data.e)); | |||
} | |||
return node; | |||
} | |||
struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, | |||
unsigned key, void *data) | |||
{ | |||
cso_data_might_grow(hash->data.d); | |||
struct cso_node **nextNode = cso_hash_find_node(hash, key); | |||
struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); | |||
struct cso_hash_iter iter = {hash, node}; | |||
return iter; | |||
} | |||
struct cso_hash * cso_hash_create(void) | |||
{ | |||
struct cso_hash *hash = malloc(sizeof(struct cso_hash)); | |||
hash->data.d = malloc(sizeof(struct cso_hash_data)); | |||
hash->data.d->fakeNext = 0; | |||
hash->data.d->buckets = 0; | |||
hash->data.d->size = 0; | |||
hash->data.d->nodeSize = sizeof(struct cso_node); | |||
hash->data.d->userNumBits = MinNumBits; | |||
hash->data.d->numBits = 0; | |||
hash->data.d->numBuckets = 0; | |||
return hash; | |||
} | |||
void cso_hash_delete(struct cso_hash *hash) | |||
{ | |||
struct cso_node *e_for_x = (struct cso_node *)(hash->data.d); | |||
struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets); | |||
int n = hash->data.d->numBuckets; | |||
while (n--) { | |||
struct cso_node *cur = *bucket++; | |||
while (cur != e_for_x) { | |||
struct cso_node *next = cur->next; | |||
cso_data_free_node(cur); | |||
cur = next; | |||
} | |||
} | |||
free(hash->data.d->buckets); | |||
free(hash->data.d); | |||
free(hash); | |||
} | |||
struct cso_hash_iter cso_hash_find(struct cso_hash *hash, | |||
unsigned key) | |||
{ | |||
struct cso_node **nextNode = cso_hash_find_node(hash, key); | |||
struct cso_hash_iter iter = {hash, *nextNode}; | |||
return iter; | |||
} | |||
unsigned cso_hash_iter_key(struct cso_hash_iter iter) | |||
{ | |||
if (!iter.node || iter.hash->data.e == iter.node) | |||
return 0; | |||
return iter.node->key; | |||
} | |||
void * cso_hash_iter_data(struct cso_hash_iter iter) | |||
{ | |||
if (!iter.node || iter.hash->data.e == iter.node) | |||
return 0; | |||
return iter.node->value; | |||
} | |||
static struct cso_node *cso_hash_data_next(struct cso_node *node) | |||
{ | |||
union { | |||
struct cso_node *next; | |||
struct cso_node *e; | |||
struct cso_hash_data *d; | |||
} a; | |||
a.next = node->next; | |||
if (!a.next) { | |||
fprintf(stderr, "iterating beyond the last element\n"); | |||
return 0; | |||
} | |||
if (a.next->next) | |||
return a.next; | |||
int start = (node->key % a.d->numBuckets) + 1; | |||
struct cso_node **bucket = a.d->buckets + start; | |||
int n = a.d->numBuckets - start; | |||
while (n--) { | |||
if (*bucket != a.e) | |||
return *bucket; | |||
++bucket; | |||
} | |||
return a.e; | |||
} | |||
static struct cso_node *cso_hash_data_prev(struct cso_node *node) | |||
{ | |||
union { | |||
struct cso_node *e; | |||
struct cso_hash_data *d; | |||
} a; | |||
a.e = node; | |||
while (a.e->next) | |||
a.e = a.e->next; | |||
int start; | |||
if (node == a.e) | |||
start = a.d->numBuckets - 1; | |||
else | |||
start = node->key % a.d->numBuckets; | |||
struct cso_node *sentinel = node; | |||
struct cso_node **bucket = a.d->buckets + start; | |||
while (start >= 0) { | |||
if (*bucket != sentinel) { | |||
struct cso_node *prev = *bucket; | |||
while (prev->next != sentinel) | |||
prev = prev->next; | |||
return prev; | |||
} | |||
sentinel = a.e; | |||
--bucket; | |||
--start; | |||
} | |||
fprintf(stderr, "iterating backward beyond first element\n"); | |||
return a.e; | |||
} | |||
struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter) | |||
{ | |||
struct cso_hash_iter next = {iter.hash, cso_hash_data_next(iter.node)}; | |||
return next; | |||
} | |||
int cso_hash_iter_is_null(struct cso_hash_iter iter) | |||
{ | |||
if (!iter.node || iter.node == iter.hash->data.e) | |||
return 1; | |||
return 0; | |||
} | |||
void * cso_hash_take(struct cso_hash *hash, | |||
unsigned akey) | |||
{ | |||
struct cso_node **node = cso_hash_find_node(hash, akey); | |||
if (*node != hash->data.e) { | |||
void *t = (*node)->value; | |||
struct cso_node *next = (*node)->next; | |||
cso_data_free_node(*node); | |||
*node = next; | |||
--hash->data.d->size; | |||
cso_data_has_shrunk(hash->data.d); | |||
return t; | |||
} | |||
return 0; | |||
} | |||
struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter) | |||
{ | |||
struct cso_hash_iter prev = {iter.hash, | |||
cso_hash_data_prev(iter.node)}; | |||
return prev; | |||
} | |||
struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash) | |||
{ | |||
struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; | |||
return iter; | |||
} |
@@ -0,0 +1,62 @@ | |||
/************************************************************************** | |||
* | |||
* 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 <zack@tungstengraphics.com> | |||
*/ | |||
#ifndef CSO_HASH_H | |||
#define CSO_HASH_H | |||
struct cso_hash; | |||
struct cso_node; | |||
struct cso_hash_iter { | |||
struct cso_hash *hash; | |||
struct cso_node *node; | |||
}; | |||
struct cso_hash *cso_hash_create(void); | |||
void cso_hash_delete(struct cso_hash *hash); | |||
struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, | |||
void *data); | |||
void *cso_hash_take(struct cso_hash *hash, unsigned key); | |||
struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); | |||
struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key); | |||
int cso_hash_iter_is_null(struct cso_hash_iter iter); | |||
unsigned cso_hash_iter_key(struct cso_hash_iter iter); | |||
void *cso_hash_iter_data(struct cso_hash_iter iter); | |||
struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); | |||
struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); | |||
#endif |
@@ -187,6 +187,7 @@ TGSIMESA_SOURCES = \ | |||
pipe/tgsi/mesa/mesa_to_tgsi.c | |||
STATECACHE_SOURCES = \ | |||
cso_cache/cso_hash.c \ | |||
cso_cache/cso_cache.c | |||
STATETRACKER_SOURCES = \ | |||
@@ -220,6 +221,7 @@ STATETRACKER_SOURCES = \ | |||
state_tracker/st_cb_readpixels.c \ | |||
state_tracker/st_cb_strings.c \ | |||
state_tracker/st_cb_texture.c \ | |||
state_tracker/st_cache.c \ | |||
state_tracker/st_context.c \ | |||
state_tracker/st_draw.c \ | |||
state_tracker/st_format.c \ |
@@ -33,10 +33,11 @@ | |||
#include "st_context.h" | |||
#include "st_cache.h" | |||
#include "st_atom.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "cso_cache/cso_cache.h" | |||
/** | |||
@@ -211,7 +212,7 @@ update_blend( struct st_context *st ) | |||
blend.dither = 1; | |||
struct pipe_blend_state *real_blend = | |||
cso_cached_blend_state(st, &blend); | |||
st_cached_blend_state(st, &blend); | |||
if (st->state.blend != real_blend) { | |||
/* state has changed */ |
@@ -0,0 +1,61 @@ | |||
/************************************************************************** | |||
* | |||
* 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 <zack@tungstengraphics.com> | |||
*/ | |||
#include "st_cache.h" | |||
#include "st_context.h" | |||
#include "pipe/p_state.h" | |||
#include "cso_cache/cso_cache.h" | |||
#include "cso_cache/cso_hash.h" | |||
/* 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 * st_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_hash_iter iter = cso_find_state_template(st->cache, | |||
hash_key, CSO_BLEND, | |||
(void*)blend); | |||
if (cso_hash_iter_is_null(iter)) { | |||
const struct pipe_blend_state *created_state = st->pipe->create_blend_state( | |||
st->pipe, blend); | |||
iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, | |||
(void*)created_state); | |||
} | |||
return (struct pipe_blend_state*)(cso_hash_iter_data(iter)); | |||
} |
@@ -0,0 +1,43 @@ | |||
/************************************************************************** | |||
* | |||
* 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 <zack@tungstengraphics.com> | |||
*/ | |||
#ifndef ST_CACHE_H | |||
#define ST_CACHE_H | |||
struct pipe_blend_state; | |||
struct st_context; | |||
struct pipe_blend_state * st_cached_blend_state( | |||
struct st_context *st, | |||
const struct pipe_blend_state *blend); | |||
#endif |
@@ -35,6 +35,7 @@ | |||
#include "main/macros.h" | |||
#include "shader/prog_instruction.h" | |||
#include "st_atom.h" | |||
#include "st_cache.h" | |||
#include "st_context.h" | |||
#include "st_cb_clear.h" | |||
#include "st_cb_fbo.h" | |||
@@ -49,8 +50,6 @@ | |||
#include "pipe/tgsi/mesa/mesa_to_tgsi.h" | |||
#include "cso_cache/cso_cache.h" | |||
#include "vf/vf.h" | |||
@@ -297,7 +296,7 @@ clear_with_quad(GLcontext *ctx, | |||
if (st->ctx->Color.DitherFlag) | |||
blend.dither = 1; | |||
} | |||
const struct pipe_blend_state *state = cso_cached_blend_state(st, &blend); | |||
const struct pipe_blend_state *state = st_cached_blend_state(st, &blend); | |||
pipe->bind_blend_state(pipe, state); | |||
} | |||
@@ -115,7 +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 ); | |||
cso_cache_delete( st->cache ); | |||
st->pipe->destroy( st->pipe ); | |||
FREE( st ); |