00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "brw_state.h"
00034
00035 #include "brw_wm.h"
00036 #include "brw_vs.h"
00037 #include "brw_clip.h"
00038 #include "brw_sf.h"
00039 #include "brw_gs.h"
00040
00041 #include "util/u_memory.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static unsigned hash_key( const void *key, unsigned key_size )
00054 {
00055 unsigned *ikey = (unsigned *)key;
00056 unsigned hash = 0, i;
00057
00058 assert(key_size % 4 == 0);
00059
00060
00061
00062 for (i = 0; i < key_size/4; i++)
00063 hash ^= ikey[i];
00064
00065 return hash;
00066 }
00067
00068 static struct brw_cache_item *search_cache( struct brw_cache *cache,
00069 unsigned hash,
00070 const void *key,
00071 unsigned key_size)
00072 {
00073 struct brw_cache_item *c;
00074
00075 for (c = cache->items[hash % cache->size]; c; c = c->next) {
00076 if (c->hash == hash &&
00077 c->key_size == key_size &&
00078 memcmp(c->key, key, key_size) == 0)
00079 return c;
00080 }
00081
00082 return NULL;
00083 }
00084
00085
00086 static void rehash( struct brw_cache *cache )
00087 {
00088 struct brw_cache_item **items;
00089 struct brw_cache_item *c, *next;
00090 unsigned size, i;
00091
00092 size = cache->size * 3;
00093 items = (struct brw_cache_item**) MALLOC(size * sizeof(*items));
00094 memset(items, 0, size * sizeof(*items));
00095
00096 for (i = 0; i < cache->size; i++)
00097 for (c = cache->items[i]; c; c = next) {
00098 next = c->next;
00099 c->next = items[c->hash % size];
00100 items[c->hash % size] = c;
00101 }
00102
00103 FREE(cache->items);
00104 cache->items = items;
00105 cache->size = size;
00106 }
00107
00108
00109 boolean brw_search_cache( struct brw_cache *cache,
00110 const void *key,
00111 unsigned key_size,
00112 void *aux_return,
00113 unsigned *offset_return)
00114 {
00115 struct brw_cache_item *item;
00116 unsigned addr = 0;
00117 unsigned hash = hash_key(key, key_size);
00118
00119 item = search_cache(cache, hash, key, key_size);
00120
00121 if (item) {
00122 if (aux_return)
00123 *(void **)aux_return = (void *)((char *)item->key + item->key_size);
00124
00125 *offset_return = addr = item->offset;
00126 }
00127
00128 if (item == NULL || addr != cache->last_addr) {
00129 cache->brw->state.dirty.cache |= 1<<cache->id;
00130 cache->last_addr = addr;
00131 }
00132
00133 return item != NULL;
00134 }
00135
00136 unsigned brw_upload_cache( struct brw_cache *cache,
00137 const void *key,
00138 unsigned key_size,
00139 const void *data,
00140 unsigned data_size,
00141 const void *aux,
00142 void *aux_return )
00143 {
00144 unsigned offset;
00145 struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
00146 unsigned hash = hash_key(key, key_size);
00147 void *tmp = MALLOC(key_size + cache->aux_size);
00148
00149 if (!brw_pool_alloc(cache->pool, data_size, 1 << 6, &offset)) {
00150
00151
00152 debug_printf("brw_pool_alloc failed\n");
00153 exit(1);
00154 }
00155
00156 memcpy(tmp, key, key_size);
00157
00158 if (cache->aux_size)
00159 memcpy(tmp+key_size, aux, cache->aux_size);
00160
00161 item->key = tmp;
00162 item->hash = hash;
00163 item->key_size = key_size;
00164 item->offset = offset;
00165 item->data_size = data_size;
00166
00167 if (++cache->n_items > cache->size * 1.5)
00168 rehash(cache);
00169
00170 hash %= cache->size;
00171 item->next = cache->items[hash];
00172 cache->items[hash] = item;
00173
00174 if (aux_return) {
00175 assert(cache->aux_size);
00176 *(void **)aux_return = (void *)((char *)item->key + item->key_size);
00177 }
00178
00179 if (BRW_DEBUG & DEBUG_STATE)
00180 debug_printf("upload %s: %d bytes to pool buffer %p offset %x\n",
00181 cache->name,
00182 data_size,
00183 (void*)cache->pool->buffer,
00184 offset);
00185
00186
00187
00188 cache->brw->winsys->buffer_subdata_typed(cache->brw->winsys,
00189 cache->pool->buffer,
00190 offset,
00191 data_size,
00192 data,
00193 cache->id);
00194
00195 cache->brw->state.dirty.cache |= 1<<cache->id;
00196 cache->last_addr = offset;
00197
00198 return offset;
00199 }
00200
00201
00202
00203 unsigned brw_cache_data_sz(struct brw_cache *cache,
00204 const void *data,
00205 unsigned data_size)
00206 {
00207 unsigned addr;
00208
00209 if (!brw_search_cache(cache, data, data_size, NULL, &addr)) {
00210 addr = brw_upload_cache(cache,
00211 data, data_size,
00212 data, data_size,
00213 NULL, NULL);
00214 }
00215
00216 return addr;
00217 }
00218
00219 unsigned brw_cache_data(struct brw_cache *cache,
00220 const void *data)
00221 {
00222 return brw_cache_data_sz(cache, data, cache->key_size);
00223 }
00224
00225 enum pool_type {
00226 DW_SURFACE_STATE,
00227 DW_GENERAL_STATE
00228 };
00229
00230 static void brw_init_cache( struct brw_context *brw,
00231 const char *name,
00232 unsigned id,
00233 unsigned key_size,
00234 unsigned aux_size,
00235 enum pool_type pool_type)
00236 {
00237 struct brw_cache *cache = &brw->cache[id];
00238 cache->brw = brw;
00239 cache->id = id;
00240 cache->name = name;
00241 cache->items = NULL;
00242
00243 cache->size = 7;
00244 cache->n_items = 0;
00245 cache->items = (struct brw_cache_item **)
00246 CALLOC(cache->size, sizeof(struct brw_cache_item));
00247
00248
00249 cache->key_size = key_size;
00250 cache->aux_size = aux_size;
00251 switch (pool_type) {
00252 case DW_GENERAL_STATE: cache->pool = &brw->pool[BRW_GS_POOL]; break;
00253 case DW_SURFACE_STATE: cache->pool = &brw->pool[BRW_SS_POOL]; break;
00254 default: assert(0); break;
00255 }
00256 }
00257
00258 void brw_init_caches( struct brw_context *brw )
00259 {
00260
00261 brw_init_cache(brw,
00262 "CC_VP",
00263 BRW_CC_VP,
00264 sizeof(struct brw_cc_viewport),
00265 0,
00266 DW_GENERAL_STATE);
00267
00268 brw_init_cache(brw,
00269 "CC_UNIT",
00270 BRW_CC_UNIT,
00271 sizeof(struct brw_cc_unit_state),
00272 0,
00273 DW_GENERAL_STATE);
00274
00275 brw_init_cache(brw,
00276 "WM_PROG",
00277 BRW_WM_PROG,
00278 sizeof(struct brw_wm_prog_key),
00279 sizeof(struct brw_wm_prog_data),
00280 DW_GENERAL_STATE);
00281
00282 brw_init_cache(brw,
00283 "SAMPLER_DEFAULT_COLOR",
00284 BRW_SAMPLER_DEFAULT_COLOR,
00285 sizeof(struct brw_sampler_default_color),
00286 0,
00287 DW_GENERAL_STATE);
00288
00289 brw_init_cache(brw,
00290 "SAMPLER",
00291 BRW_SAMPLER,
00292 0,
00293 0,
00294 DW_GENERAL_STATE);
00295
00296 brw_init_cache(brw,
00297 "WM_UNIT",
00298 BRW_WM_UNIT,
00299 sizeof(struct brw_wm_unit_state),
00300 0,
00301 DW_GENERAL_STATE);
00302
00303 brw_init_cache(brw,
00304 "SF_PROG",
00305 BRW_SF_PROG,
00306 sizeof(struct brw_sf_prog_key),
00307 sizeof(struct brw_sf_prog_data),
00308 DW_GENERAL_STATE);
00309
00310 brw_init_cache(brw,
00311 "SF_VP",
00312 BRW_SF_VP,
00313 sizeof(struct brw_sf_viewport),
00314 0,
00315 DW_GENERAL_STATE);
00316
00317 brw_init_cache(brw,
00318 "SF_UNIT",
00319 BRW_SF_UNIT,
00320 sizeof(struct brw_sf_unit_state),
00321 0,
00322 DW_GENERAL_STATE);
00323
00324 brw_init_cache(brw,
00325 "VS_UNIT",
00326 BRW_VS_UNIT,
00327 sizeof(struct brw_vs_unit_state),
00328 0,
00329 DW_GENERAL_STATE);
00330
00331 brw_init_cache(brw,
00332 "VS_PROG",
00333 BRW_VS_PROG,
00334 sizeof(struct brw_vs_prog_key),
00335 sizeof(struct brw_vs_prog_data),
00336 DW_GENERAL_STATE);
00337
00338 brw_init_cache(brw,
00339 "CLIP_UNIT",
00340 BRW_CLIP_UNIT,
00341 sizeof(struct brw_clip_unit_state),
00342 0,
00343 DW_GENERAL_STATE);
00344
00345 brw_init_cache(brw,
00346 "CLIP_PROG",
00347 BRW_CLIP_PROG,
00348 sizeof(struct brw_clip_prog_key),
00349 sizeof(struct brw_clip_prog_data),
00350 DW_GENERAL_STATE);
00351
00352 brw_init_cache(brw,
00353 "GS_UNIT",
00354 BRW_GS_UNIT,
00355 sizeof(struct brw_gs_unit_state),
00356 0,
00357 DW_GENERAL_STATE);
00358
00359 brw_init_cache(brw,
00360 "GS_PROG",
00361 BRW_GS_PROG,
00362 sizeof(struct brw_gs_prog_key),
00363 sizeof(struct brw_gs_prog_data),
00364 DW_GENERAL_STATE);
00365
00366 brw_init_cache(brw,
00367 "SS_SURFACE",
00368 BRW_SS_SURFACE,
00369 sizeof(struct brw_surface_state),
00370 0,
00371 DW_SURFACE_STATE);
00372
00373 brw_init_cache(brw,
00374 "SS_SURF_BIND",
00375 BRW_SS_SURF_BIND,
00376 sizeof(struct brw_surface_binding_table),
00377 0,
00378 DW_SURFACE_STATE);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 static void clear_cache( struct brw_cache *cache )
00398 {
00399 struct brw_cache_item *c, *next;
00400 unsigned i;
00401
00402 for (i = 0; i < cache->size; i++) {
00403 for (c = cache->items[i]; c; c = next) {
00404 next = c->next;
00405 free((void *)c->key);
00406 free(c);
00407 }
00408 cache->items[i] = NULL;
00409 }
00410
00411 cache->n_items = 0;
00412 }
00413
00414 void brw_clear_all_caches( struct brw_context *brw )
00415 {
00416 int i;
00417
00418 if (BRW_DEBUG & DEBUG_STATE)
00419 debug_printf("%s\n", __FUNCTION__);
00420
00421 for (i = 0; i < BRW_MAX_CACHE; i++)
00422 clear_cache(&brw->cache[i]);
00423
00424 if (brw->curbe.last_buf) {
00425 FREE(brw->curbe.last_buf);
00426 brw->curbe.last_buf = NULL;
00427 }
00428
00429 brw->state.dirty.brw |= ~0;
00430 brw->state.dirty.cache |= ~0;
00431 }
00432
00433
00434
00435
00436
00437 void brw_destroy_caches( struct brw_context *brw )
00438 {
00439 unsigned i;
00440
00441 for (i = 0; i < BRW_MAX_CACHE; i++)
00442 clear_cache(&brw->cache[i]);
00443 }