cso_cache.c revision 6c597238b2e168b63738ac8cc9167c1d09185aad
19780327c5d95586a88fce94d7b47342355ead118Zack Rusin/************************************************************************** 29780327c5d95586a88fce94d7b47342355ead118Zack Rusin * 39780327c5d95586a88fce94d7b47342355ead118Zack Rusin * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 49780327c5d95586a88fce94d7b47342355ead118Zack Rusin * All Rights Reserved. 59780327c5d95586a88fce94d7b47342355ead118Zack Rusin * 69780327c5d95586a88fce94d7b47342355ead118Zack Rusin * Permission is hereby granted, free of charge, to any person obtaining a 79780327c5d95586a88fce94d7b47342355ead118Zack Rusin * copy of this software and associated documentation files (the 89780327c5d95586a88fce94d7b47342355ead118Zack Rusin * "Software"), to deal in the Software without restriction, including 99780327c5d95586a88fce94d7b47342355ead118Zack Rusin * without limitation the rights to use, copy, modify, merge, publish, 109780327c5d95586a88fce94d7b47342355ead118Zack Rusin * distribute, sub license, and/or sell copies of the Software, and to 119780327c5d95586a88fce94d7b47342355ead118Zack Rusin * permit persons to whom the Software is furnished to do so, subject to 129780327c5d95586a88fce94d7b47342355ead118Zack Rusin * the following conditions: 139780327c5d95586a88fce94d7b47342355ead118Zack Rusin * 149780327c5d95586a88fce94d7b47342355ead118Zack Rusin * The above copyright notice and this permission notice (including the 159780327c5d95586a88fce94d7b47342355ead118Zack Rusin * next paragraph) shall be included in all copies or substantial portions 169780327c5d95586a88fce94d7b47342355ead118Zack Rusin * of the Software. 179780327c5d95586a88fce94d7b47342355ead118Zack Rusin * 189780327c5d95586a88fce94d7b47342355ead118Zack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 199780327c5d95586a88fce94d7b47342355ead118Zack Rusin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 209780327c5d95586a88fce94d7b47342355ead118Zack Rusin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 219780327c5d95586a88fce94d7b47342355ead118Zack Rusin * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 229780327c5d95586a88fce94d7b47342355ead118Zack Rusin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 239780327c5d95586a88fce94d7b47342355ead118Zack Rusin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 249780327c5d95586a88fce94d7b47342355ead118Zack Rusin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 259780327c5d95586a88fce94d7b47342355ead118Zack Rusin * 269780327c5d95586a88fce94d7b47342355ead118Zack Rusin **************************************************************************/ 279780327c5d95586a88fce94d7b47342355ead118Zack Rusin 289780327c5d95586a88fce94d7b47342355ead118Zack Rusin/* Authors: Zack Rusin <zack@tungstengraphics.com> 299780327c5d95586a88fce94d7b47342355ead118Zack Rusin */ 309780327c5d95586a88fce94d7b47342355ead118Zack Rusin 319780327c5d95586a88fce94d7b47342355ead118Zack Rusin#include "cso_cache.h" 32e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin#include "cso_hash.h" 339780327c5d95586a88fce94d7b47342355ead118Zack Rusin 349780327c5d95586a88fce94d7b47342355ead118Zack Rusin#if 1 35e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstatic unsigned hash_key(const void *key, unsigned key_size) 369780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 379780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned *ikey = (unsigned *)key; 389780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned hash = 0, i; 399780327c5d95586a88fce94d7b47342355ead118Zack Rusin 409780327c5d95586a88fce94d7b47342355ead118Zack Rusin assert(key_size % 4 == 0); 419780327c5d95586a88fce94d7b47342355ead118Zack Rusin 429780327c5d95586a88fce94d7b47342355ead118Zack Rusin /* I'm sure this can be improved on: 439780327c5d95586a88fce94d7b47342355ead118Zack Rusin */ 449780327c5d95586a88fce94d7b47342355ead118Zack Rusin for (i = 0; i < key_size/4; i++) 459780327c5d95586a88fce94d7b47342355ead118Zack Rusin hash ^= ikey[i]; 469780327c5d95586a88fce94d7b47342355ead118Zack Rusin 479780327c5d95586a88fce94d7b47342355ead118Zack Rusin return hash; 489780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 499780327c5d95586a88fce94d7b47342355ead118Zack Rusin#else 509780327c5d95586a88fce94d7b47342355ead118Zack Rusinstatic unsigned hash_key(const unsigned char *p, int n) 519780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 529780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned h = 0; 539780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned g; 549780327c5d95586a88fce94d7b47342355ead118Zack Rusin 559780327c5d95586a88fce94d7b47342355ead118Zack Rusin while (n--) { 569780327c5d95586a88fce94d7b47342355ead118Zack Rusin h = (h << 4) + *p++; 579780327c5d95586a88fce94d7b47342355ead118Zack Rusin if ((g = (h & 0xf0000000)) != 0) 589780327c5d95586a88fce94d7b47342355ead118Zack Rusin h ^= g >> 23; 599780327c5d95586a88fce94d7b47342355ead118Zack Rusin h &= ~g; 609780327c5d95586a88fce94d7b47342355ead118Zack Rusin } 619780327c5d95586a88fce94d7b47342355ead118Zack Rusin return h; 629780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 639780327c5d95586a88fce94d7b47342355ead118Zack Rusin#endif 649780327c5d95586a88fce94d7b47342355ead118Zack Rusin 659780327c5d95586a88fce94d7b47342355ead118Zack Rusinunsigned cso_construct_key(void *item, int item_size) 669780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 67e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return hash_key((item), item_size); 689780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 699780327c5d95586a88fce94d7b47342355ead118Zack Rusin 70e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstatic struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) 71e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin{ 72e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = 0; 73e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 74e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin switch(type) { 75e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin case CSO_BLEND: 76e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin hash = sc->blend_hash; 77a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 78f117327a3f246713abfd4dc4320d4a1a7f1b811aZack Rusin case CSO_SAMPLER: 79f117327a3f246713abfd4dc4320d4a1a7f1b811aZack Rusin hash = sc->sampler_hash; 80a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 81bfe79babf99e6b9435195178d1ea64687c60d161Keith Whitwell case CSO_DEPTH_STENCIL_ALPHA: 82d6ac959833a8e40a27907940969c622692f749b1Zack Rusin hash = sc->depth_stencil_hash; 83a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 84294401814d1d89cc731de1c22c25333aa5d59374Zack Rusin case CSO_RASTERIZER: 85294401814d1d89cc731de1c22c25333aa5d59374Zack Rusin hash = sc->rasterizer_hash; 86a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 87f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin case CSO_FRAGMENT_SHADER: 88f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin hash = sc->fs_hash; 89a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 90f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin case CSO_VERTEX_SHADER: 91f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin hash = sc->vs_hash; 92a0e948f3aaadf56ab206a6b3e597825f2085f6d1Zack Rusin break; 93e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin } 94e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 95e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return hash; 96e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin} 97e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 98e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstatic int _cso_size_for_type(enum cso_cache_type type) 99e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin{ 100e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin switch(type) { 101e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin case CSO_BLEND: 102e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return sizeof(struct pipe_blend_state); 103f117327a3f246713abfd4dc4320d4a1a7f1b811aZack Rusin case CSO_SAMPLER: 104f117327a3f246713abfd4dc4320d4a1a7f1b811aZack Rusin return sizeof(struct pipe_sampler_state); 105bfe79babf99e6b9435195178d1ea64687c60d161Keith Whitwell case CSO_DEPTH_STENCIL_ALPHA: 106bfe79babf99e6b9435195178d1ea64687c60d161Keith Whitwell return sizeof(struct pipe_depth_stencil_alpha_state); 107294401814d1d89cc731de1c22c25333aa5d59374Zack Rusin case CSO_RASTERIZER: 108294401814d1d89cc731de1c22c25333aa5d59374Zack Rusin return sizeof(struct pipe_rasterizer_state); 109f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin case CSO_FRAGMENT_SHADER: 110f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin return sizeof(struct pipe_shader_state); 111f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin case CSO_VERTEX_SHADER: 112ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin return sizeof(struct pipe_shader_state); 113e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin } 114e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return 0; 115e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin} 116e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 117e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter 1189780327c5d95586a88fce94d7b47342355ead118Zack Rusincso_insert_state(struct cso_cache *sc, 119e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type, 120e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin void *state) 1219780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 122e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 123e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_insert(hash, hash_key, state); 1249780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 1259780327c5d95586a88fce94d7b47342355ead118Zack Rusin 126e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter 1279780327c5d95586a88fce94d7b47342355ead118Zack Rusincso_find_state(struct cso_cache *sc, 128e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type) 1299780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 130e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 1319780327c5d95586a88fce94d7b47342355ead118Zack Rusin 132e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_find(hash, hash_key); 1339780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 1349780327c5d95586a88fce94d7b47342355ead118Zack Rusin 1356c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 1366c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonsecavoid *cso_hash_find_data_from_template( struct cso_hash *hash, 1376c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca unsigned hash_key, 1386c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca void *templ, 1396c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca int size ) 1406c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca{ 1416c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca struct cso_hash_iter iter = cso_hash_find(hash, hash_key); 1426c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca while (!cso_hash_iter_is_null(iter)) { 1436c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca void *iter_data = cso_hash_iter_data(iter); 1446c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca if (!memcmp(iter_data, templ, size)) { 1456c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca /* Return the payload: 1466c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca */ 1476c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca return (unsigned char *)iter_data + size; 1486c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca } 1496c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca iter = cso_hash_iter_next(iter); 1506c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca } 1516c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca return NULL; 1526c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca} 1536c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 1546c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 155e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter cso_find_state_template(struct cso_cache *sc, 156e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type, 157e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin void *templ) 1589780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 159e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); 160e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin int size = _cso_size_for_type(type); 161e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin while (!cso_hash_iter_is_null(iter)) { 162e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin void *iter_data = cso_hash_iter_data(iter); 163e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin if (!memcmp(iter_data, templ, size)) 164e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return iter; 165e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin iter = cso_hash_iter_next(iter); 1669780327c5d95586a88fce94d7b47342355ead118Zack Rusin } 167e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return iter; 168e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin} 169e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 170e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinvoid * cso_take_state(struct cso_cache *sc, 171e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type) 172e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin{ 173e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 174e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_take(hash, hash_key); 1759780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 1769780327c5d95586a88fce94d7b47342355ead118Zack Rusin 1779780327c5d95586a88fce94d7b47342355ead118Zack Rusinstruct cso_cache *cso_cache_create(void) 1789780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 1799780327c5d95586a88fce94d7b47342355ead118Zack Rusin struct cso_cache *sc = malloc(sizeof(struct cso_cache)); 1809780327c5d95586a88fce94d7b47342355ead118Zack Rusin 181ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin sc->blend_hash = cso_hash_create(); 182ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin sc->sampler_hash = cso_hash_create(); 183d6ac959833a8e40a27907940969c622692f749b1Zack Rusin sc->depth_stencil_hash = cso_hash_create(); 184ccd63b54cfbb6bb241d55f7ac95afcd14819f469Zack Rusin sc->rasterizer_hash = cso_hash_create(); 185f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin sc->fs_hash = cso_hash_create(); 186f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin sc->vs_hash = cso_hash_create(); 1879780327c5d95586a88fce94d7b47342355ead118Zack Rusin 1889780327c5d95586a88fce94d7b47342355ead118Zack Rusin return sc; 1899780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 1909780327c5d95586a88fce94d7b47342355ead118Zack Rusin 191e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinvoid cso_cache_delete(struct cso_cache *sc) 1929780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 1939780327c5d95586a88fce94d7b47342355ead118Zack Rusin assert(sc); 194e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin cso_hash_delete(sc->blend_hash); 195f117327a3f246713abfd4dc4320d4a1a7f1b811aZack Rusin cso_hash_delete(sc->sampler_hash); 196d6ac959833a8e40a27907940969c622692f749b1Zack Rusin cso_hash_delete(sc->depth_stencil_hash); 197294401814d1d89cc731de1c22c25333aa5d59374Zack Rusin cso_hash_delete(sc->rasterizer_hash); 198f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin cso_hash_delete(sc->fs_hash); 199f22e920f478d8732695913ec0d1f7244b451a8f5Zack Rusin cso_hash_delete(sc->vs_hash); 2009780327c5d95586a88fce94d7b47342355ead118Zack Rusin free(sc); 2019780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 202