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
|
#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)
|
static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -2529,12 +2529,17 @@ struct d3d12_cache_session
|
|||||||
ID3D12ShaderCacheSession ID3D12ShaderCacheSession_iface;
|
ID3D12ShaderCacheSession ID3D12ShaderCacheSession_iface;
|
||||||
unsigned int refcount;
|
unsigned int refcount;
|
||||||
|
|
||||||
|
struct list cache_list_entry;
|
||||||
|
|
||||||
struct d3d12_device *device;
|
struct d3d12_device *device;
|
||||||
struct vkd3d_private_store private_store;
|
struct vkd3d_private_store private_store;
|
||||||
D3D12_SHADER_CACHE_SESSION_DESC desc;
|
D3D12_SHADER_CACHE_SESSION_DESC desc;
|
||||||
struct vkd3d_shader_cache *cache;
|
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)
|
static inline struct d3d12_cache_session *impl_from_ID3D12ShaderCacheSession(ID3D12ShaderCacheSession *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct d3d12_cache_session, 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);
|
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_shader_cache_decref(session->cache);
|
||||||
vkd3d_private_store_destroy(&session->private_store);
|
vkd3d_private_store_destroy(&session->private_store);
|
||||||
vkd3d_free(session);
|
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,
|
static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session,
|
||||||
struct d3d12_device *device, const D3D12_SHADER_CACHE_SESSION_DESC *desc)
|
struct d3d12_device *device, const D3D12_SHADER_CACHE_SESSION_DESC *desc)
|
||||||
{
|
{
|
||||||
|
struct d3d12_cache_session *i;
|
||||||
enum vkd3d_result ret;
|
enum vkd3d_result ret;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
session->ID3D12ShaderCacheSession_iface.lpVtbl = &d3d12_cache_session_vtbl;
|
session->ID3D12ShaderCacheSession_iface.lpVtbl = &d3d12_cache_session_vtbl;
|
||||||
session->refcount = 1;
|
session->refcount = 1;
|
||||||
session->desc = *desc;
|
session->desc = *desc;
|
||||||
|
session->cache = NULL;
|
||||||
|
|
||||||
if (!session->desc.MaximumValueFileSizeBytes)
|
if (!session->desc.MaximumValueFileSizeBytes)
|
||||||
session->desc.MaximumValueFileSizeBytes = 128 * 1024 * 1024;
|
session->desc.MaximumValueFileSizeBytes = 128 * 1024 * 1024;
|
||||||
@ -2726,20 +2737,56 @@ static HRESULT d3d12_cache_session_init(struct d3d12_cache_session *session,
|
|||||||
if (FAILED(hr = vkd3d_private_store_init(&session->private_store)))
|
if (FAILED(hr = vkd3d_private_store_init(&session->private_store)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (session->desc.Mode == D3D12_SHADER_CACHE_MODE_DISK)
|
vkd3d_mutex_lock(&cache_list_mutex);
|
||||||
FIXME("Disk caches are not yet implemented.\n");
|
|
||||||
|
|
||||||
ret = vkd3d_shader_open_cache(&session->cache);
|
/* We expect the number of open caches to be small. */
|
||||||
if (ret)
|
LIST_FOR_EACH_ENTRY(i, &cache_list, struct d3d12_cache_session, cache_list_entry)
|
||||||
{
|
{
|
||||||
WARN("Failed to open shader cache.\n");
|
if (!memcmp(&i->desc.Identifier, &desc->Identifier, sizeof(desc->Identifier)))
|
||||||
vkd3d_private_store_destroy(&session->private_store);
|
{
|
||||||
return hresult_from_vkd3d_result(ret);
|
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");
|
||||||
|
|
||||||
|
ret = vkd3d_shader_open_cache(&session->cache);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
WARN("Failed to open shader cache.\n");
|
||||||
|
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);
|
d3d12_device_add_ref(session->device = device);
|
||||||
|
|
||||||
|
vkd3d_mutex_unlock(&cache_list_mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
vkd3d_private_store_destroy(&session->private_store);
|
||||||
|
vkd3d_mutex_unlock(&cache_list_mutex);
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID3D12Device */
|
/* ID3D12Device */
|
||||||
@ -4888,6 +4935,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateShaderCacheSession(ID3D12Dev
|
|||||||
WARN("No output pointer, returning S_FALSE.\n");
|
WARN("No output pointer, returning S_FALSE.\n");
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
*session = NULL;
|
||||||
|
|
||||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
@ -38477,10 +38477,8 @@ static void test_shader_cache(void)
|
|||||||
session2 = (void *)0xdeadbeef;
|
session2 = (void *)0xdeadbeef;
|
||||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
||||||
&IID_ID3D12ShaderCacheSession, (void **)&session2);
|
&IID_ID3D12ShaderCacheSession, (void **)&session2);
|
||||||
todo ok(hr == DXGI_ERROR_ALREADY_EXISTS, "Got unexpected hr %#x.\n", hr);
|
ok(hr == DXGI_ERROR_ALREADY_EXISTS, "Got unexpected hr %#x.\n", hr);
|
||||||
todo ok(!session2, "Got unexpected pointer %p.\n", session2);
|
ok(!session2, "Got unexpected pointer %p.\n", session2);
|
||||||
if (session2)
|
|
||||||
ID3D12ShaderCacheSession_Release(session2);
|
|
||||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc, &IID_IUnknown, NULL);
|
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc, &IID_IUnknown, NULL);
|
||||||
ok(hr == S_FALSE, "NULL outptr: Got hr %#x.\n", hr);
|
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);
|
refcount = get_refcount(device);
|
||||||
ok(refcount == base_refcount, "Got unexpected refcount %u.\n", refcount);
|
ok(refcount == base_refcount, "Got unexpected refcount %u.\n", refcount);
|
||||||
|
|
||||||
|
/* Create two sessions with the same cache GUID. */
|
||||||
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
hr = ID3D12Device9_CreateShaderCacheSession(device, &desc,
|
||||||
&IID_ID3D12ShaderCacheSession, (void **)&session);
|
&IID_ID3D12ShaderCacheSession, (void **)&session);
|
||||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
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);
|
ID3D12ShaderCacheSession_Release(session);
|
||||||
|
|
||||||
ID3D12Device9_Release(device);
|
ID3D12Device9_Release(device);
|
||||||
|
Loading…
Reference in New Issue
Block a user