diff --git a/Makefile.am b/Makefile.am index 995f70b2..876b4f52 100644 --- a/Makefile.am +++ b/Makefile.am @@ -356,6 +356,7 @@ libvkd3d_la_SOURCES = \ include/vkd3d_d3d12.idl \ include/vkd3d_d3dcommon.idl \ include/vkd3d_unknown.idl \ + libs/vkd3d/cache.c \ libs/vkd3d/command.c \ libs/vkd3d/device.c \ libs/vkd3d/resource.c \ diff --git a/libs/vkd3d/cache.c b/libs/vkd3d/cache.c new file mode 100644 index 00000000..56ba6990 --- /dev/null +++ b/libs/vkd3d/cache.c @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Stefan Dösinger for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vkd3d_private.h" + +struct vkd3d_shader_cache +{ + unsigned int refcount; +}; + +int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache) +{ + struct vkd3d_shader_cache *object; + + TRACE("%p.\n", cache); + + object = vkd3d_malloc(sizeof(*object)); + if (!object) + return VKD3D_ERROR_OUT_OF_MEMORY; + + object->refcount = 1; + *cache = object; + + return VKD3D_OK; +} + +unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache) +{ + unsigned int refcount = vkd3d_atomic_increment_u32(&cache->refcount); + TRACE("cache %p refcount %u.\n", cache, refcount); + return refcount; +} + +unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache) +{ + unsigned int refcount = vkd3d_atomic_decrement_u32(&cache->refcount); + TRACE("cache %p refcount %u.\n", cache, refcount); + + if (refcount) + return refcount; + + vkd3d_free(cache); + return 0; +} diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 65db8b70..266465e0 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2532,6 +2532,7 @@ struct d3d12_cache_session struct d3d12_device *device; struct vkd3d_private_store private_store; D3D12_SHADER_CACHE_SESSION_DESC desc; + struct vkd3d_shader_cache *cache; }; static inline struct d3d12_cache_session *impl_from_ID3D12ShaderCacheSession(ID3D12ShaderCacheSession *iface) @@ -2582,6 +2583,7 @@ static void d3d12_cache_session_destroy(struct d3d12_cache_session *session) TRACE("Destroying cache session %p.\n", session); + vkd3d_shader_cache_decref(session->cache); vkd3d_private_store_destroy(&session->private_store); vkd3d_free(session); @@ -2707,6 +2709,7 @@ static const struct ID3D12ShaderCacheSessionVtbl d3d12_cache_session_vtbl = static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session, struct d3d12_device *device, const D3D12_SHADER_CACHE_SESSION_DESC *desc) { + enum vkd3d_result ret; HRESULT hr; session->ID3D12ShaderCacheSession_iface.lpVtbl = &d3d12_cache_session_vtbl; @@ -2723,6 +2726,17 @@ static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session, if (FAILED(hr = vkd3d_private_store_init(&session->private_store))) return hr; + if (session->desc.Mode == D3D12_SHADER_CACHE_MODE_DISK) + FIXME("Disk caches are not yet implemented.\n"); + + ret = vkd3d_shader_open_cache(&session->cache); + if (ret) + { + WARN("Failed to open shader cache.\n"); + vkd3d_private_store_destroy(&session->private_store); + return hresult_from_vkd3d_result(ret); + } + d3d12_device_add_ref(session->device = device); return S_OK; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index d5e12ee3..91ffa6e9 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1927,4 +1927,10 @@ static inline void vkd3d_prepend_struct(void *header, void *structure) vkd3d_header->next = vkd3d_structure; } +struct vkd3d_shader_cache; + +int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache); +unsigned int vkd3d_shader_cache_incref(struct vkd3d_shader_cache *cache); +unsigned int vkd3d_shader_cache_decref(struct vkd3d_shader_cache *cache); + #endif /* __VKD3D_PRIVATE_H */