}
/**
- * Attempts to find an item in the cache with identical data and aux
- * data to use
+ * Attempts to find an item in the cache with identical data.
*/
-static bool
-brw_try_upload_using_copy(struct brw_cache *cache,
- struct brw_cache_item *result_item,
- const void *data,
- const void *aux)
+static const struct brw_cache_item *
+brw_lookup_prog(const struct brw_cache *cache,
+ enum brw_cache_id cache_id,
+ const void *data, unsigned data_size)
{
- struct brw_context *brw = cache->brw;
+ const struct brw_context *brw = cache->brw;
int i;
- struct brw_cache_item *item;
+ const struct brw_cache_item *item;
for (i = 0; i < cache->size; i++) {
for (item = cache->items[i]; item; item = item->next) {
- const void *item_aux = item->key + item->key_size;
int ret;
- if (item->cache_id != result_item->cache_id ||
- item->size != result_item->size ||
- item->aux_size != result_item->aux_size) {
- continue;
- }
-
- if (cache->aux_compare[result_item->cache_id]) {
- if (!cache->aux_compare[result_item->cache_id](item_aux, aux))
- continue;
- } else if (memcmp(item_aux, aux, item->aux_size) != 0) {
+ if (item->cache_id != cache_id || item->size != data_size)
continue;
- }
if (!brw->has_llc)
drm_intel_bo_map(cache->bo, false);
if (ret)
continue;
- result_item->offset = item->offset;
-
- return true;
+ return item;
}
}
- return false;
+ return NULL;
}
static uint32_t
{
struct brw_context *brw = cache->brw;
struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
+ const struct brw_cache_item *matching_data =
+ brw_lookup_prog(cache, cache_id, data, data_size);
GLuint hash;
void *tmp;
hash = hash_key(item);
item->hash = hash;
- /* If we can find a matching prog/prog_data combo in the cache
- * already, then reuse the existing stuff. This will mean not
- * flagging CACHE_NEW_* when transitioning between the two
- * equivalent hash keys. This is notably useful for programs
- * generating shaders at runtime, where multiple shaders may
- * compile to the thing in our backend.
+ /* If we can find a matching prog in the cache already, then reuse the
+ * existing stuff without creating new copy into the underlying buffer
+ * object. This is notably useful for programs generating shaders at
+ * runtime, where multiple shaders may compile to the same thing in our
+ * backend.
*/
- if (!brw_try_upload_using_copy(cache, item, data, aux)) {
+ if (matching_data) {
+ item->offset = matching_data->offset;
+ } else {
item->offset = brw_alloc_item_data(cache, data_size);
/* Copy data to the buffer */