From: Stefan Dösinger stefan@codeweavers.com
--- libs/vkd3d/cache.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/cache.c b/libs/vkd3d/cache.c index 75ba0b64a..04126c2f0 100644 --- a/libs/vkd3d/cache.c +++ b/libs/vkd3d/cache.c @@ -288,8 +288,62 @@ unlock: int vkd3d_shader_cache_get(struct vkd3d_shader_cache *cache, const void *key, uint32_t key_size, void *value, uint32_t *value_size) { - FIXME("%p, %p, %#x, %p, %p stub!\n", cache, key, key_size, value, value_size); - return VKD3D_ERROR_NOT_IMPLEMENTED; + struct shader_cache_entry *e; + struct rb_entry *entry; + enum vkd3d_result ret; + uint32_t size_in; + uint64_t hash; + + TRACE("%p, %p, %#x, %p, %p.\n", cache, key, key_size, value, value_size); + + if (!vkd3d_shader_cache_trylock(cache)) + { + WARN("Cache lock not available.\n"); + return VKD3D_ERROR_LOCK_NOT_AVAILABLE; + } + + size_in = *value_size; + + hash = hash_key(key, key_size); + entry = rb_get(&cache->tree, &hash); + if (!entry) + { + WARN("entry not found\n"); + ret = VKD3D_ERROR_NOT_FOUND; + goto unlock; + } + + e = RB_ENTRY_VALUE(entry, struct shader_cache_entry, entry); + if (key_size != e->d.key_size || memcmp(key, e->payload, key_size)) + { + /* There is a return value for this, but I want to see if this ever happens. */ + FIXME("Hash collission. sizes %u, %u. read from offset %x hash %"PRIu64"\n", + key_size, e->d.key_size, e->d.offset, e->d.hash); + exit(1); + } + + *value_size = e->d.value_size; + if (!value) + { + TRACE("Found item, returning needed size %#x.\n", e->d.value_size); + ret = VKD3D_OK; + goto unlock; + } + + if (size_in < e->d.value_size) + { + WARN("Output buffer is too small, got %#x want %#x.\n", size_in, e->d.value_size); + ret = VKD3D_ERROR_MORE_DATA; + goto unlock; + } + + memcpy(value, e->payload + e->d.key_size, e->d.value_size); + ret = VKD3D_OK; + TRACE("Returning cached data.\n"); + +unlock: + vkd3d_shader_cache_unlock(cache); + return ret; }
void vkd3d_shader_cache_delete_on_destroy(struct vkd3d_shader_cache *cache)