From: Stefan Dösinger stefan@codeweavers.com
--- libs/vkd3d/cache.c | 2 +- libs/vkd3d/device.c | 7 +++++++ libs/vkd3d/state.c | 35 +++++++++++++++++++++++++++++++---- libs/vkd3d/vkd3d_private.h | 11 +++++++++++ 4 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d/cache.c b/libs/vkd3d/cache.c index 049cf00ed..5a158e9c3 100644 --- a/libs/vkd3d/cache.c +++ b/libs/vkd3d/cache.c @@ -421,7 +421,7 @@ static inline uint64_t mvkHash64(const uint64_t *pVals, size_t count, uint64_t s return hash; }
-static uint64_t hash_key(const void *key, size_t size) +uint64_t hash_key(const void *key, size_t size) { uint64_t last = 0, ret;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 93771d638..d5cc50f0c 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -4403,6 +4403,7 @@ static bool d3d12_device_load_cache(struct vkd3d_shader_cache *cache, const void *key, uint32_t key_size, const void *value, uint32_t value_size, void *context) { + const struct vkd3d_shader_cache_root_signature *rs; const struct vkd3d_shader_cache_entry *e = value; struct d3d12_device *device = context; VkRenderPass rp; @@ -4417,6 +4418,12 @@ static bool d3d12_device_load_cache(struct vkd3d_shader_cache *cache, vkd3d_render_pass_cache_find(device->render_pass_cache, device, key, &rp); break;
+ case SHADER_CACHE_ENTRY_ROOT_SIGNATURE: + rs = value; + d3d12_root_signature_create(device, rs->dxbc, value_size + - offsetof(struct vkd3d_shader_cache_root_signature, dxbc[0]), NULL); + break; + case SHADER_CACHE_ENTRY_VULKAN_BLOB: break; } diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 417707088..f39055f90 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1532,6 +1532,7 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device, D3D12_VERSIONED_ROOT_SIGNATURE_DESC d3d12; struct vkd3d_shader_versioned_root_signature_desc vkd3d; } root_signature_desc; + struct vkd3d_shader_cache_root_signature *cache_value; struct d3d12_root_signature *object; uint32_t size = sizeof(object); HRESULT hr; @@ -1542,8 +1543,13 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device, if (ret == VKD3D_OK) { ERR("found cached root sig\n"); - *root_signature = object; - d3d12_root_signature_AddRef(&object->ID3D12RootSignature_iface); + if (root_signature) + { + *root_signature = object; + d3d12_root_signature_AddRef(&object->ID3D12RootSignature_iface); + } + else + ERR("Why do I create a cached root sig twice?\n"); return S_OK; }
@@ -1574,8 +1580,29 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device, if (ret) ERR("papa!\n");
- *root_signature = object; - d3d12_root_signature_AddRef(&object->ID3D12RootSignature_iface); + /* Why the hash as key and d3d root signature description as value? Because we store + * the root signature hash in pipelines and need a way to look up the root signature + * when we recreate the pipelines. + * + * Alternatively we could use bytecode as key here and store a hash -> bytecode lookup + * at runtime in device->root_signature_cache. I am unsure for now. */ + object->hash = hash_key(bytecode, bytecode_length); + size = offsetof(struct vkd3d_shader_cache_root_signature, dxbc[bytecode_length]); + cache_value = vkd3d_malloc(size); + cache_value->header.vkd3d_revision = VKD3D_SHADER_CACHE_VKD3D_VERSION; + cache_value->header.type = SHADER_CACHE_ENTRY_ROOT_SIGNATURE; + memcpy(cache_value->dxbc, bytecode, bytecode_length); + ret = vkd3d_shader_cache_put(device->persistent_cache, &object->hash, sizeof(object->hash), + cache_value, size); + if (ret) + ERR("uncle!\n"); + vkd3d_free(cache_value); + + if (root_signature) + { + *root_signature = object; + d3d12_root_signature_AddRef(&object->ID3D12RootSignature_iface); + }
return S_OK; } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 13b031789..0705b5e7c 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -69,6 +69,7 @@ struct vkd3d_render_pass_key enum vkd3d_shader_cache_entry_type { SHADER_CACHE_ENTRY_RENDER_PASS = VKD3D_MAKE_TAG('R', 'P', 'A', 'S'), + SHADER_CACHE_ENTRY_ROOT_SIGNATURE = VKD3D_MAKE_TAG('R', 'O', 'O', 'T'), SHADER_CACHE_ENTRY_VULKAN_BLOB = VKD3D_MAKE_TAG('V', 'K', 'P', 'C'), };
@@ -84,8 +85,17 @@ struct vkd3d_shader_cache_vk_blob uint8_t blob[1]; };
+struct vkd3d_shader_cache_root_signature +{ + struct vkd3d_shader_cache_entry header; + uint8_t dxbc[1]; +}; + /* End shader data structures */
+/* FIXME: Better name. */ +uint64_t hash_key(const void *key, size_t size); + #define VK_CALL(f) (vk_procs->f)
#define VKD3D_DESCRIPTOR_MAGIC_FREE 0x00000000u @@ -1213,6 +1223,7 @@ struct d3d12_root_signature { ID3D12RootSignature ID3D12RootSignature_iface; LONG refcount; + uint64_t hash;
VkPipelineLayout vk_pipeline_layout; struct d3d12_descriptor_set_layout descriptor_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS];