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 31ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h" 322a0675eb75b8ca52efab739218bf93922bf884b5José Fonseca 334f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 344f25420bdd834e81a3e22733304efc5261c2998aBrian Paul 359780327c5d95586a88fce94d7b47342355ead118Zack Rusin#include "cso_cache.h" 36e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin#include "cso_hash.h" 379780327c5d95586a88fce94d7b47342355ead118Zack Rusin 38bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin 39bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusinstruct cso_cache { 401dbcb83881f508280ed78dae6834d341936712f2Dave Airlie struct cso_hash *hashes[CSO_CACHE_MAX]; 41bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin int max_size; 42026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin 43026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin cso_sanitize_callback sanitize_cb; 44026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin void *sanitize_data; 45bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin}; 46bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin 479780327c5d95586a88fce94d7b47342355ead118Zack Rusin#if 1 48e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstatic unsigned hash_key(const void *key, unsigned key_size) 499780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 509780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned *ikey = (unsigned *)key; 519780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned hash = 0, i; 529780327c5d95586a88fce94d7b47342355ead118Zack Rusin 539780327c5d95586a88fce94d7b47342355ead118Zack Rusin assert(key_size % 4 == 0); 549780327c5d95586a88fce94d7b47342355ead118Zack Rusin 559780327c5d95586a88fce94d7b47342355ead118Zack Rusin /* I'm sure this can be improved on: 569780327c5d95586a88fce94d7b47342355ead118Zack Rusin */ 579780327c5d95586a88fce94d7b47342355ead118Zack Rusin for (i = 0; i < key_size/4; i++) 589780327c5d95586a88fce94d7b47342355ead118Zack Rusin hash ^= ikey[i]; 599780327c5d95586a88fce94d7b47342355ead118Zack Rusin 609780327c5d95586a88fce94d7b47342355ead118Zack Rusin return hash; 619780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 629780327c5d95586a88fce94d7b47342355ead118Zack Rusin#else 639780327c5d95586a88fce94d7b47342355ead118Zack Rusinstatic unsigned hash_key(const unsigned char *p, int n) 649780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 659780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned h = 0; 669780327c5d95586a88fce94d7b47342355ead118Zack Rusin unsigned g; 679780327c5d95586a88fce94d7b47342355ead118Zack Rusin 689780327c5d95586a88fce94d7b47342355ead118Zack Rusin while (n--) { 699780327c5d95586a88fce94d7b47342355ead118Zack Rusin h = (h << 4) + *p++; 709780327c5d95586a88fce94d7b47342355ead118Zack Rusin if ((g = (h & 0xf0000000)) != 0) 719780327c5d95586a88fce94d7b47342355ead118Zack Rusin h ^= g >> 23; 729780327c5d95586a88fce94d7b47342355ead118Zack Rusin h &= ~g; 739780327c5d95586a88fce94d7b47342355ead118Zack Rusin } 749780327c5d95586a88fce94d7b47342355ead118Zack Rusin return h; 759780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 769780327c5d95586a88fce94d7b47342355ead118Zack Rusin#endif 779780327c5d95586a88fce94d7b47342355ead118Zack Rusin 789780327c5d95586a88fce94d7b47342355ead118Zack Rusinunsigned cso_construct_key(void *item, int item_size) 799780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 80e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return hash_key((item), item_size); 819780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 829780327c5d95586a88fce94d7b47342355ead118Zack Rusin 831dbcb83881f508280ed78dae6834d341936712f2Dave Airliestatic INLINE struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) 84e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin{ 851dbcb83881f508280ed78dae6834d341936712f2Dave Airlie struct cso_hash *hash; 861dbcb83881f508280ed78dae6834d341936712f2Dave Airlie hash = sc->hashes[type]; 87e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return hash; 88e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin} 89e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 907838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusinstatic void delete_blend_state(void *state, void *data) 917838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 927838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin struct cso_blend *cso = (struct cso_blend *)state; 9338dc0f809d5f72b382676be6f72ea675a3929455José Fonseca if (cso->delete_state) 947838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin cso->delete_state(cso->context, cso->data); 9538dc0f809d5f72b382676be6f72ea675a3929455José Fonseca FREE(state); 967838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 977838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 987838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusinstatic void delete_depth_stencil_state(void *state, void *data) 997838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 1007838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; 10138dc0f809d5f72b382676be6f72ea675a3929455José Fonseca if (cso->delete_state) 1027838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin cso->delete_state(cso->context, cso->data); 10338dc0f809d5f72b382676be6f72ea675a3929455José Fonseca FREE(state); 1047838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 1057838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 1067838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusinstatic void delete_sampler_state(void *state, void *data) 1077838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 1087838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin struct cso_sampler *cso = (struct cso_sampler *)state; 10938dc0f809d5f72b382676be6f72ea675a3929455José Fonseca if (cso->delete_state) 1107838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin cso->delete_state(cso->context, cso->data); 11138dc0f809d5f72b382676be6f72ea675a3929455José Fonseca FREE(state); 1127838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 1137838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 1147838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusinstatic void delete_rasterizer_state(void *state, void *data) 1157838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 1167838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin struct cso_rasterizer *cso = (struct cso_rasterizer *)state; 11738dc0f809d5f72b382676be6f72ea675a3929455José Fonseca if (cso->delete_state) 1187838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin cso->delete_state(cso->context, cso->data); 11938dc0f809d5f72b382676be6f72ea675a3929455José Fonseca FREE(state); 1207838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 1217838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 12251d139f03898e5e46af6363c6bba131455738cc4Roland Scheideggerstatic void delete_velements(void *state, void *data) 12351d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger{ 12451d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger struct cso_velements *cso = (struct cso_velements *)state; 12551d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger if (cso->delete_state) 12651d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger cso->delete_state(cso->context, cso->data); 12751d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger FREE(state); 12851d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger} 1297838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 1307838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusinstatic INLINE void delete_cso(void *state, enum cso_cache_type type) 1317838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 1327838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin switch (type) { 13338dc0f809d5f72b382676be6f72ea675a3929455José Fonseca case CSO_BLEND: 1347838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin delete_blend_state(state, 0); 1357838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin break; 13638dc0f809d5f72b382676be6f72ea675a3929455José Fonseca case CSO_SAMPLER: 1377838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin delete_sampler_state(state, 0); 1387838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin break; 13938dc0f809d5f72b382676be6f72ea675a3929455José Fonseca case CSO_DEPTH_STENCIL_ALPHA: 1407838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin delete_depth_stencil_state(state, 0); 1417838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin break; 14238dc0f809d5f72b382676be6f72ea675a3929455José Fonseca case CSO_RASTERIZER: 1437838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin delete_rasterizer_state(state, 0); 1447838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin break; 14551d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger case CSO_VELEMENTS: 14651d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger delete_velements(state, 0); 14751d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger break; 14838dc0f809d5f72b382676be6f72ea675a3929455José Fonseca default: 14938dc0f809d5f72b382676be6f72ea675a3929455José Fonseca assert(0); 15038dc0f809d5f72b382676be6f72ea675a3929455José Fonseca FREE(state); 1517838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin } 1527838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 1537838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 154026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin 155026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusinstatic INLINE void sanitize_hash(struct cso_cache *sc, 156026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin struct cso_hash *hash, 157026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin enum cso_cache_type type, 1587838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin int max_size) 1597838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin{ 160026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin if (sc->sanitize_cb) 161026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sc->sanitize_cb(hash, type, max_size, sc->sanitize_data); 162026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin} 163026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin 164026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin 165026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusinstatic INLINE void sanitize_cb(struct cso_hash *hash, enum cso_cache_type type, 166026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin int max_size, void *user_data) 167026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin{ 1687838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin /* if we're approach the maximum size, remove fourth of the entries 1697838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin * otherwise every subsequent call will go through the same */ 170be9a2457388d99a2185f258aeb5ef5183ccfbbb2Zack Rusin int hash_size = cso_hash_size(hash); 171be9a2457388d99a2185f258aeb5ef5183ccfbbb2Zack Rusin int max_entries = (max_size > hash_size) ? max_size : hash_size; 1727838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin int to_remove = (max_size < max_entries) * max_entries/4; 173be9a2457388d99a2185f258aeb5ef5183ccfbbb2Zack Rusin if (hash_size > max_size) 174be9a2457388d99a2185f258aeb5ef5183ccfbbb2Zack Rusin to_remove += hash_size - max_size; 1757838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin while (to_remove) { 1767838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin /*remove elements until we're good */ 1777838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin /*fixme: currently we pick the nodes to remove at random*/ 1787838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin struct cso_hash_iter iter = cso_hash_first_node(hash); 1797838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin void *cso = cso_hash_take(hash, cso_hash_iter_key(iter)); 1807838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin delete_cso(cso, type); 1817838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin --to_remove; 1827838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin } 1837838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin} 1847838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 185e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter 1869780327c5d95586a88fce94d7b47342355ead118Zack Rusincso_insert_state(struct cso_cache *sc, 187e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type, 188e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin void *state) 1899780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 190e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 191026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sanitize_hash(sc, hash, type, sc->max_size); 1927838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 193e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_insert(hash, hash_key, state); 1949780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 1959780327c5d95586a88fce94d7b47342355ead118Zack Rusin 196e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter 1979780327c5d95586a88fce94d7b47342355ead118Zack Rusincso_find_state(struct cso_cache *sc, 198e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type) 1999780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 200e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 2019780327c5d95586a88fce94d7b47342355ead118Zack Rusin 202e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_find(hash, hash_key); 2039780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 2049780327c5d95586a88fce94d7b47342355ead118Zack Rusin 2056c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 2066c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonsecavoid *cso_hash_find_data_from_template( struct cso_hash *hash, 2076c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca unsigned hash_key, 2086c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca void *templ, 2096c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca int size ) 2106c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca{ 2116c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca struct cso_hash_iter iter = cso_hash_find(hash, hash_key); 2126c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca while (!cso_hash_iter_is_null(iter)) { 2136c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca void *iter_data = cso_hash_iter_data(iter); 2146c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca if (!memcmp(iter_data, templ, size)) { 215e1180c2d694851ed12e86027aa406ee20546e6d3Zack Rusin /* We found a match 2166c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca */ 217e1180c2d694851ed12e86027aa406ee20546e6d3Zack Rusin return iter_data; 2186c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca } 2196c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca iter = cso_hash_iter_next(iter); 2206c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca } 2216c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca return NULL; 2226c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca} 2236c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 2246c597238b2e168b63738ac8cc9167c1d09185aadJosé Fonseca 225e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinstruct cso_hash_iter cso_find_state_template(struct cso_cache *sc, 226e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type, 227847ac8ec5ff683076dff17d8e0426a64b4ad65e7Roland Scheidegger void *templ, unsigned size) 2289780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 229e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); 230e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin while (!cso_hash_iter_is_null(iter)) { 231e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin void *iter_data = cso_hash_iter_data(iter); 232e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin if (!memcmp(iter_data, templ, size)) 233e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return iter; 234e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin iter = cso_hash_iter_next(iter); 2359780327c5d95586a88fce94d7b47342355ead118Zack Rusin } 236e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return iter; 237e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin} 238e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin 239e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinvoid * cso_take_state(struct cso_cache *sc, 240e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin unsigned hash_key, enum cso_cache_type type) 241e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin{ 242e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin struct cso_hash *hash = _cso_hash_for_type(sc, type); 243e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusin return cso_hash_take(hash, hash_key); 2449780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 2459780327c5d95586a88fce94d7b47342355ead118Zack Rusin 2469780327c5d95586a88fce94d7b47342355ead118Zack Rusinstruct cso_cache *cso_cache_create(void) 2479780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 2482a0675eb75b8ca52efab739218bf93922bf884b5José Fonseca struct cso_cache *sc = MALLOC_STRUCT(cso_cache); 2491dbcb83881f508280ed78dae6834d341936712f2Dave Airlie int i; 250785831fc6fc56815d9637c7dd2acbcee6dfbbb0aKeith Whitwell if (sc == NULL) 251785831fc6fc56815d9637c7dd2acbcee6dfbbb0aKeith Whitwell return NULL; 2529780327c5d95586a88fce94d7b47342355ead118Zack Rusin 253bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin sc->max_size = 4096; 2541dbcb83881f508280ed78dae6834d341936712f2Dave Airlie for (i = 0; i < CSO_CACHE_MAX; i++) 2551dbcb83881f508280ed78dae6834d341936712f2Dave Airlie sc->hashes[i] = cso_hash_create(); 2561dbcb83881f508280ed78dae6834d341936712f2Dave Airlie 257026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sc->sanitize_cb = sanitize_cb; 258026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sc->sanitize_data = 0; 2599780327c5d95586a88fce94d7b47342355ead118Zack Rusin 2609780327c5d95586a88fce94d7b47342355ead118Zack Rusin return sc; 2619780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 2629780327c5d95586a88fce94d7b47342355ead118Zack Rusin 2636abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusinvoid cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, 264e7985105695a18c29c13deb2b8f40c15eef72ee6Zack Rusin cso_state_callback func, void *user_data) 2656abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin{ 2661dbcb83881f508280ed78dae6834d341936712f2Dave Airlie struct cso_hash *hash = _cso_hash_for_type(sc, type); 2676abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin struct cso_hash_iter iter; 2686abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin 2696abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin iter = cso_hash_first_node(hash); 2706abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin while (!cso_hash_iter_is_null(iter)) { 2716abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin void *state = cso_hash_iter_data(iter); 27236feb5eacf16467d06d5cd9f63d19f17f933f1efZack Rusin iter = cso_hash_iter_next(iter); 2736abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin if (state) { 2746abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin func(state, user_data); 2756abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin } 2766abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin } 2776abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin} 2786abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin 279e16c045b83f5c5b4f4064df67623bb76b46b6619Zack Rusinvoid cso_cache_delete(struct cso_cache *sc) 2809780327c5d95586a88fce94d7b47342355ead118Zack Rusin{ 2811dbcb83881f508280ed78dae6834d341936712f2Dave Airlie int i; 2829780327c5d95586a88fce94d7b47342355ead118Zack Rusin assert(sc); 283f311893bf4cd4e20e5b43fa404c4a2f656791943Zack Rusin 284f311893bf4cd4e20e5b43fa404c4a2f656791943Zack Rusin if (!sc) 285f311893bf4cd4e20e5b43fa404c4a2f656791943Zack Rusin return; 286f311893bf4cd4e20e5b43fa404c4a2f656791943Zack Rusin 2876abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin /* delete driver data */ 2886abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin cso_for_each_state(sc, CSO_BLEND, delete_blend_state, 0); 2896abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin cso_for_each_state(sc, CSO_DEPTH_STENCIL_ALPHA, delete_depth_stencil_state, 0); 2906abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0); 2916abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0); 29251d139f03898e5e46af6363c6bba131455738cc4Roland Scheidegger cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0); 2936abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin 2941dbcb83881f508280ed78dae6834d341936712f2Dave Airlie for (i = 0; i < CSO_CACHE_MAX; i++) 2951dbcb83881f508280ed78dae6834d341936712f2Dave Airlie cso_hash_delete(sc->hashes[i]); 2961dbcb83881f508280ed78dae6834d341936712f2Dave Airlie 2972a0675eb75b8ca52efab739218bf93922bf884b5José Fonseca FREE(sc); 2989780327c5d95586a88fce94d7b47342355ead118Zack Rusin} 2996abb82da7e676384e7e2c9732307b23f8ed7157dZack Rusin 300bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusinvoid cso_set_maximum_cache_size(struct cso_cache *sc, int number) 301bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin{ 3021dbcb83881f508280ed78dae6834d341936712f2Dave Airlie int i; 3031dbcb83881f508280ed78dae6834d341936712f2Dave Airlie 304bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin sc->max_size = number; 3057838aaffdb9d34427ebcb73aac585c85d9622018Zack Rusin 3061dbcb83881f508280ed78dae6834d341936712f2Dave Airlie for (i = 0; i < CSO_CACHE_MAX; i++) 3071dbcb83881f508280ed78dae6834d341936712f2Dave Airlie sanitize_hash(sc, sc->hashes[i], i, sc->max_size); 308bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin} 309bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin 310bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusinint cso_maximum_cache_size(const struct cso_cache *sc) 311bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin{ 312bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin return sc->max_size; 313bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin} 314bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9Zack Rusin 315026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusinvoid cso_cache_set_sanitize_callback(struct cso_cache *sc, 316026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin cso_sanitize_callback cb, 317026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin void *user_data) 318026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin{ 319026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sc->sanitize_cb = cb; 320026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin sc->sanitize_data = user_data; 321026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin} 322026e31a068981724fb0c98f6d1fc87d086fd2da6Zack Rusin 323