* data) in return. Objects in the cache may not have relocations
* (pointers to other BOs) in them.
*
- * The inner workings are a simple hash table based on a CRC of the
+ * The inner workings are a simple hash table based on a FNV-1a of the
* key data.
*
* Replacement is not implemented. Instead, when the cache gets too
* big we throw out all of the cache data and let it get regenerated.
*/
-#include "main/imports.h"
#include "main/streaming-load-memcpy.h"
#include "x86/common_x86_asm.h"
#include "intel_batchbuffer.h"
#include "brw_cs.h"
#include "brw_program.h"
#include "compiler/brw_eu.h"
+#include "util/u_memory.h"
#define FILE_DEBUG_FLAG DEBUG_STATE
/** for variable-sized keys */
GLuint key_size;
- GLuint aux_size;
- const void *key;
+ GLuint prog_data_size;
+ const struct brw_base_prog_key *key;
uint32_t offset;
uint32_t size;
struct brw_cache_item *next;
};
-static unsigned
-get_program_string_id(enum brw_cache_id cache_id, const void *key)
+enum brw_cache_id
+brw_stage_cache_id(gl_shader_stage stage)
{
- switch (cache_id) {
- case BRW_CACHE_VS_PROG:
- return ((struct brw_vs_prog_key *) key)->program_string_id;
- case BRW_CACHE_TCS_PROG:
- return ((struct brw_tcs_prog_key *) key)->program_string_id;
- case BRW_CACHE_TES_PROG:
- return ((struct brw_tes_prog_key *) key)->program_string_id;
- case BRW_CACHE_GS_PROG:
- return ((struct brw_gs_prog_key *) key)->program_string_id;
- case BRW_CACHE_CS_PROG:
- return ((struct brw_cs_prog_key *) key)->program_string_id;
- case BRW_CACHE_FS_PROG:
- return ((struct brw_wm_prog_key *) key)->program_string_id;
- default:
- unreachable("no program string id for this kind of program");
- }
+ static const enum brw_cache_id stage_ids[] = {
+ BRW_CACHE_VS_PROG,
+ BRW_CACHE_TCS_PROG,
+ BRW_CACHE_TES_PROG,
+ BRW_CACHE_GS_PROG,
+ BRW_CACHE_FS_PROG,
+ BRW_CACHE_CS_PROG,
+ };
+ assert((int)stage >= 0 && stage < ARRAY_SIZE(stage_ids));
+ return stage_ids[stage];
}
static GLuint
hash_key(struct brw_cache_item *item)
{
- GLuint *ikey = (GLuint *)item->key;
- GLuint hash = item->cache_id, i;
-
- assert(item->key_size % 4 == 0);
-
- /* I'm sure this can be improved on:
- */
- for (i = 0; i < item->key_size/4; i++) {
- hash ^= ikey[i];
- hash = (hash << 5) | (hash >> 27);
- }
+ uint32_t hash = _mesa_fnv32_1a_offset_bias;
+ hash = _mesa_fnv32_1a_accumulate(hash, item->cache_id);
+ hash = _mesa_fnv32_1a_accumulate_block(hash, item->key, item->key_size);
return hash;
}
* Returns the buffer object matching cache_id and key, or NULL.
*/
bool
-brw_search_cache(struct brw_cache *cache,
- enum brw_cache_id cache_id,
- const void *key, GLuint key_size,
- uint32_t *inout_offset, void *inout_aux)
+brw_search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
+ const void *key, GLuint key_size, uint32_t *inout_offset,
+ void *inout_prog_data, bool flag_state)
{
- struct brw_context *brw = cache->brw;
struct brw_cache_item *item;
struct brw_cache_item lookup;
GLuint hash;
if (item == NULL)
return false;
- void *aux = ((char *) item->key) + item->key_size;
+ void *prog_data = ((char *) item->key) + item->key_size;
- if (item->offset != *inout_offset || aux != *((void **) inout_aux)) {
- brw->ctx.NewDriverState |= (1 << cache_id);
+ if (item->offset != *inout_offset ||
+ prog_data != *((void **) inout_prog_data)) {
+ if (likely(flag_state))
+ cache->brw->ctx.NewDriverState |= (1 << cache_id);
*inout_offset = item->offset;
- *((void **) inout_aux) = aux;
+ *((void **) inout_prog_data) = prog_data;
}
return true;
perf_debug("Copying to larger program cache: %u kB -> %u kB\n",
(unsigned) cache->bo->size / 1024, new_size / 1024);
- new_bo = brw_bo_alloc(brw->bufmgr, "program cache", new_size, 64);
+ new_bo = brw_bo_alloc(brw->bufmgr, "program cache", new_size,
+ BRW_MEMZONE_SHADER);
if (can_do_exec_capture(brw->screen))
- new_bo->kflags = EXEC_OBJECT_CAPTURE;
+ new_bo->kflags |= EXEC_OBJECT_CAPTURE;
void *map = brw_bo_map(brw, new_bo, MAP_READ | MAP_WRITE |
MAP_ASYNC | MAP_PERSISTENT);
for (unsigned i = 0; i < cache->size; i++) {
for (struct brw_cache_item *c = cache->items[i]; c; c = c->next) {
if (c->cache_id == cache_id &&
- get_program_string_id(cache_id, c->key) == program_string_id) {
+ c->key->program_string_id == program_string_id) {
return c->key;
}
}
GLuint key_size,
const void *data,
GLuint data_size,
- const void *aux,
- GLuint aux_size,
+ const void *prog_data,
+ GLuint prog_data_size,
uint32_t *out_offset,
- void *out_aux)
+ void *out_prog_data)
{
struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
const struct brw_cache_item *matching_data =
item->size = data_size;
item->key = key;
item->key_size = key_size;
- item->aux_size = aux_size;
+ item->prog_data_size = prog_data_size;
hash = hash_key(item);
item->hash = hash;
memcpy(cache->map + item->offset, data, data_size);
}
- /* Set up the memory containing the key and aux_data */
- tmp = malloc(key_size + aux_size);
+ /* Set up the memory containing the key and prog_data */
+ tmp = malloc(key_size + prog_data_size);
memcpy(tmp, key, key_size);
- memcpy(tmp + key_size, aux, aux_size);
+ memcpy(tmp + key_size, prog_data, prog_data_size);
item->key = tmp;
cache->n_items++;
*out_offset = item->offset;
- *(void **)out_aux = (void *)((char *)item->key + item->key_size);
+ *(void **)out_prog_data = (void *)((char *)item->key + item->key_size);
cache->brw->ctx.NewDriverState |= 1 << cache_id;
}
cache->items =
calloc(cache->size, sizeof(struct brw_cache_item *));
- cache->bo = brw_bo_alloc(brw->bufmgr, "program cache", 4096, 64);
+ cache->bo = brw_bo_alloc(brw->bufmgr, "program cache", 16384,
+ BRW_MEMZONE_SHADER);
if (can_do_exec_capture(brw->screen))
- cache->bo->kflags = EXEC_OBJECT_CAPTURE;
+ cache->bo->kflags |= EXEC_OBJECT_CAPTURE;
cache->map = brw_bo_map(brw, cache->bo, MAP_READ | MAP_WRITE |
MAP_ASYNC | MAP_PERSISTENT);
c->cache_id == BRW_CACHE_GS_PROG ||
c->cache_id == BRW_CACHE_FS_PROG ||
c->cache_id == BRW_CACHE_CS_PROG) {
- const void *item_aux = c->key + c->key_size;
- brw_stage_prog_data_free(item_aux);
+ const void *item_prog_data = ((char *)c->key) + c->key_size;
+ brw_stage_prog_data_free(item_prog_data);
}
free((void *)c->key);
free(c);
perf_debug("Exceeded state cache size limit. Clearing the set "
"of compiled programs, which will trigger recompiles\n");
brw_clear_cache(brw, &brw->cache);
+ brw_cache_new_bo(&brw->cache, brw->cache.bo->size);
}
}