mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d: Implement reopening existing caches.
This commit is contained in:
parent
f24005507c
commit
a7860ae752
Notes:
Alexandre Julliard
2024-04-11 17:04:06 -05:00
Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/766
@ -438,6 +438,12 @@ struct vkd3d_mutex
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#define VKD3D_MUTEX_INITIALIZER {{NULL, -1, 0, 0, 0, 0}}
|
||||
#else
|
||||
#define VKD3D_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
|
||||
static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -2529,12 +2529,17 @@ struct d3d12_cache_session
|
||||
ID3D12ShaderCacheSession ID3D12ShaderCacheSession_iface;
|
||||
unsigned int refcount;
|
||||
|
||||
struct list cache_list_entry;
|
||||
|
||||
struct d3d12_device *device;
|
||||
struct vkd3d_private_store private_store;
|
||||
D3D12_SHADER_CACHE_SESSION_DESC desc;
|
||||
struct vkd3d_shader_cache *cache;
|
||||
};
|
||||
|
||||
static struct vkd3d_mutex cache_list_mutex = VKD3D_MUTEX_INITIALIZER;
|
||||
static struct list cache_list = LIST_INIT(cache_list);
|
||||
|
||||
static inline struct d3d12_cache_session *impl_from_ID3D12ShaderCacheSession(ID3D12ShaderCacheSession *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct d3d12_cache_session, ID3D12ShaderCacheSession_iface);
|
||||
@ -2583,6 +2588,10 @@ static void d3d12_cache_session_destroy(struct d3d12_cache_session *session)
|
||||
|
||||
TRACE("Destroying cache session %p.\n", session);
|
||||
|
||||
vkd3d_mutex_lock(&cache_list_mutex);
|
||||
list_remove(&session->cache_list_entry);
|
||||
vkd3d_mutex_unlock(&cache_list_mutex);
|
||||
|
||||
vkd3d_shader_cache_decref(session->cache);
|
||||
vkd3d_private_store_destroy(&session->private_store);
|
||||
vkd3d_free(session);
|
||||
@ -2709,12 +2718,14 @@ 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)
|
||||
{
|
||||
struct d3d12_cache_session *i;
|
||||
enum vkd3d_result ret;
|
||||
HRESULT hr;
|
||||
|
||||
session->ID3D12ShaderCacheSession_iface.lpVtbl = &d3d12_cache_session_vtbl;
|
||||
session->refcount = 1;
|
||||
session->desc = *desc;
|
||||
session->cache = NULL;
|
||||
|
||||
if (!session->desc.MaximumValueFileSizeBytes)
|
||||
session->desc.MaximumValueFileSizeBytes = 128 * 1024 * 1024;
|
||||
@ -2726,6 +2737,32 @@ static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session,
|
||||
if (FAILED(hr = vkd3d_private_store_init(&session->private_store)))
|
||||
return hr;
|
||||
|
||||
vkd3d_mutex_lock(&cache_list_mutex);
|
||||
|
||||
/* We expect the number of open caches to be small. */
|
||||
LIST_FOR_EACH_ENTRY(i, &cache_list, struct d3d12_cache_session, cache_list_entry)
|
||||
{
|
||||
if (!memcmp(&i->desc.Identifier, &desc->Identifier, sizeof(desc->Identifier)))
|
||||
{
|
||||
TRACE("Found an existing cache %p from session %p.\n", i->cache, i);
|
||||
if (desc->Version == i->desc.Version)
|
||||
{
|
||||
session->desc = i->desc;
|
||||
vkd3d_shader_cache_incref(session->cache = i->cache);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("version mismatch: Existing %"PRIu64" new %"PRIu64".\n",
|
||||
i->desc.Version, desc->Version);
|
||||
hr = DXGI_ERROR_ALREADY_EXISTS;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!session->cache)
|
||||
{
|
||||
if (session->desc.Mode == D3D12_SHADER_CACHE_MODE_DISK)
|
||||
FIXME("Disk caches are not yet implemented.\n");
|
||||
|
||||
@ -2733,13 +2770,23 @@ static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session,
|
||||
if (ret)
|
||||
{
|
||||
WARN("Failed to open shader cache.\n");
|
||||
vkd3d_private_store_destroy(&session->private_store);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
hr = hresult_from_vkd3d_result(ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add it to the list even if we reused an existing cache. The other session might be destroyed,
|
||||
* but the cache stays alive and can be opened a third time. */
|
||||
list_add_tail(&cache_list, &session->cache_list_entry);
|
||||
d3d12_device_add_ref(session->device = device);
|
||||
|
||||
vkd3d_mutex_unlock(&cache_list_mutex);
|
||||
return S_OK;
|
||||
|
||||
error:
|
||||
vkd3d_private_store_destroy(&session->private_store);
|
||||
vkd3d_mutex_unlock(&cache_list_mutex);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* ID3D12Device */
|
||||
@ -4888,6 +4935,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateShaderCacheSession(ID3D12Dev
|
||||
WARN("No output pointer, returning S_FALSE.\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
*session = NULL;
|
||||
|
||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -38477,10 +38477,8 @@ static void test_shader_cache(void)
|
||||
session2 = (void *)0xdeadbeef;
|
||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
||||
&IID_ID3D12ShaderCacheSession, (void **)&session2);
|
||||
todo ok(hr == DXGI_ERROR_ALREADY_EXISTS, "Got unexpected hr %#x.\n", hr);
|
||||
todo ok(!session2, "Got unexpected pointer %p.\n", session2);
|
||||
if (session2)
|
||||
ID3D12ShaderCacheSession_Release(session2);
|
||||
ok(hr == DXGI_ERROR_ALREADY_EXISTS, "Got unexpected hr %#x.\n", hr);
|
||||
ok(!session2, "Got unexpected pointer %p.\n", session2);
|
||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc, &IID_IUnknown, NULL);
|
||||
ok(hr == S_FALSE, "NULL outptr: Got hr %#x.\n", hr);
|
||||
|
||||
@ -38489,9 +38487,16 @@ static void test_shader_cache(void)
|
||||
refcount = get_refcount(device);
|
||||
ok(refcount == base_refcount, "Got unexpected refcount %u.\n", refcount);
|
||||
|
||||
/* Create two sessions with the same cache GUID. */
|
||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
||||
&IID_ID3D12ShaderCacheSession, (void **)&session);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
||||
&IID_ID3D12ShaderCacheSession, (void **)&session2);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
ok(session2 != session, "Expected different interface pointers, got %p for both.\n",
|
||||
session);
|
||||
ID3D12ShaderCacheSession_Release(session2);
|
||||
ID3D12ShaderCacheSession_Release(session);
|
||||
|
||||
ID3D12Device9_Release(device);
|
||||
|
Loading…
Reference in New Issue
Block a user