Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 2620 messages
[PATCH 1/5] wmvcore/tests: Add tests for asynchronous reader streaming.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wmvcore/tests/wmvcore.c | 291 ++++++++++++++++++++++++++++++++++-
1 file changed, 283 insertions(+), 8 deletions(-)
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c
index eae320c4d2e..ac4239f1d24 100644
--- a/dlls/wmvcore/tests/wmvcore.c
+++ b/dlls/wmvcore/tests/wmvcore.c
@@ -420,6 +420,14 @@ static const IStreamVtbl stream_vtbl =
stream_Clone,
};
+static void teststream_init(struct teststream *stream, HANDLE file)
+{
+ memset(stream, 0, sizeof(*stream));
+ stream->IStream_iface.lpVtbl = &stream_vtbl;
+ stream->refcount = 1;
+ stream->file = file;
+}
+
static void test_reader_attributes(IWMProfile *profile)
{
WORD size, stream_number, ret_stream_number;
@@ -578,7 +586,7 @@ static void test_sync_reader_streaming(void)
WORD stream_numbers[2], stream_number;
IWMStreamConfig *config, *config2;
bool eos[2] = {0}, first = true;
- struct teststream stream = {{0}};
+ struct teststream stream;
ULONG i, j, count, ref;
IWMSyncReader *reader;
IWMProfile *profile;
@@ -592,9 +600,7 @@ static void test_sync_reader_streaming(void)
file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", debugstr_w(file), GetLastError());
- stream.IStream_iface.lpVtbl = &stream_vtbl;
- stream.refcount = 1;
- stream.file = file;
+ teststream_init(&stream, file);
hr = WMCreateSyncReader(NULL, 0, &reader);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -816,7 +822,7 @@ static void test_sync_reader_types(void)
bool got_video = false, got_audio = false;
DWORD size, ret_size, output_number;
WORD stream_number, stream_number2;
- struct teststream stream = {{0}};
+ struct teststream stream;
IWMStreamConfig *config;
ULONG count, ref, i, j;
IWMSyncReader *reader;
@@ -829,9 +835,7 @@ static void test_sync_reader_types(void)
file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", debugstr_w(file), GetLastError());
- stream.IStream_iface.lpVtbl = &stream_vtbl;
- stream.refcount = 1;
- stream.file = file;
+ teststream_init(&stream, file);
hr = WMCreateSyncReader(NULL, 0, &reader);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1051,6 +1055,276 @@ static void test_sync_reader_file(void)
ok(ret, "Failed to delete %s, error %u.\n", debugstr_w(filename), GetLastError());
}
+struct callback
+{
+ IWMReaderCallback IWMReaderCallback_iface;
+ LONG refcount;
+ HANDLE got_opened, got_stopped, eof_event;
+ unsigned int got_closed, got_started, got_sample, got_end_of_streaming, got_eof;
+};
+
+static struct callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface)
+{
+ return CONTAINING_RECORD(iface, struct callback, IWMReaderCallback_iface);
+}
+
+static HRESULT WINAPI callback_QueryInterface(IWMReaderCallback *iface, REFIID iid, void **out)
+{
+ if (winetest_debug > 1)
+ trace("%04x: IWMReaderCallback::QueryInterface(%s)\n", GetCurrentThreadId(), debugstr_guid(iid));
+
+ if (!IsEqualGUID(iid, &IID_IWMReaderCallbackAdvanced) && !IsEqualGUID(iid, &IID_IWMCredentialCallback))
+ ok(0, "Unexpected IID %s.\n", debugstr_guid(iid));
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI callback_AddRef(IWMReaderCallback *iface)
+{
+ struct callback *callback = impl_from_IWMReaderCallback(iface);
+
+ return InterlockedIncrement(&callback->refcount);
+}
+
+static ULONG WINAPI callback_Release(IWMReaderCallback *iface)
+{
+ struct callback *callback = impl_from_IWMReaderCallback(iface);
+
+ return InterlockedDecrement(&callback->refcount);
+}
+
+static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS status,
+ HRESULT hr, WMT_ATTR_DATATYPE type, BYTE *value, void *context)
+{
+ struct callback *callback = impl_from_IWMReaderCallback(iface);
+
+ if (winetest_debug > 1)
+ trace("%u: %04x: IWMReaderCallback::OnStatus(status %u, hr %#x, type %#x, value %p)\n",
+ GetTickCount(), GetCurrentThreadId(), status, hr, type, value);
+
+ switch (status)
+ {
+ case WMT_OPENED:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xdeadbeef, "Got unexpected context %p.\n", context);
+ SetEvent(callback->got_opened);
+ break;
+
+ case WMT_STARTED:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ ++callback->got_started;
+ break;
+
+ case WMT_STOPPED:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ SetEvent(callback->got_stopped);
+ break;
+
+ case WMT_CLOSED:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ todo_wine ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ ++callback->got_closed;
+ break;
+
+ case WMT_END_OF_STREAMING:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
+ ++callback->got_end_of_streaming;
+ break;
+
+ case WMT_EOF:
+ ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type);
+ ok(!*(DWORD *)value, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ ok(callback->got_sample > 0, "Got no samples.\n");
+ ok(callback->got_end_of_streaming == 1, "Got %u WMT_END_OF_STREAMING callbacks.\n",
+ callback->got_end_of_streaming);
+ ++callback->got_eof;
+ SetEvent(callback->eof_event);
+ break;
+
+ /* Not sent when not using IWMReaderAdvanced::DeliverTime(). */
+ case WMT_END_OF_SEGMENT:
+ ok(type == WMT_TYPE_QWORD, "Got type %#x.\n", type);
+ ok(*(QWORD *)value == 3000, "Got value %#x.\n", *(DWORD *)value);
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+ ok(callback->got_sample > 0, "Got no samples.\n");
+ ok(callback->got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
+ break;
+
+ default:
+ ok(0, "Unexpected status %#x.\n", status);
+ }
+
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ return S_OK;
+}
+
+static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
+ QWORD time, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
+{
+ struct callback *callback = impl_from_IWMReaderCallback(iface);
+ HRESULT hr;
+ DWORD size;
+ BYTE *data;
+
+ if (winetest_debug > 1)
+ trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
+ GetTickCount(), GetCurrentThreadId(), output, time, duration, flags);
+
+ ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+
+ hr = INSSBuffer_GetBufferAndLength(sample, &data, &size);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ok(callback->got_started > 0, "Got %u WMT_STARTED callbacks.\n", callback->got_started);
+ ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
+ ++callback->got_sample;
+
+ return S_OK;
+}
+
+static const IWMReaderCallbackVtbl callback_vtbl =
+{
+ callback_QueryInterface,
+ callback_AddRef,
+ callback_Release,
+ callback_OnStatus,
+ callback_OnSample,
+};
+
+static void callback_init(struct callback *callback)
+{
+ memset(callback, 0, sizeof(*callback));
+ callback->IWMReaderCallback_iface.lpVtbl = &callback_vtbl;
+ callback->refcount = 1;
+ callback->got_opened = CreateEventW(NULL, FALSE, FALSE, NULL);
+ callback->got_stopped = CreateEventW(NULL, FALSE, FALSE, NULL);
+ callback->eof_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+}
+
+static void callback_cleanup(struct callback *callback)
+{
+ CloseHandle(callback->got_opened);
+ CloseHandle(callback->got_stopped);
+ CloseHandle(callback->eof_event);
+}
+
+static void test_async_reader_streaming(void)
+{
+ const WCHAR *filename = load_resource(L"test.wmv");
+ IWMReaderAdvanced2 *advanced;
+ struct teststream stream;
+ struct callback callback;
+ IWMStreamConfig *config;
+ WORD stream_numbers[2];
+ IWMProfile *profile;
+ ULONG i, count, ref;
+ IWMReader *reader;
+ HANDLE file;
+ HRESULT hr;
+ BOOL ret;
+
+ file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", debugstr_w(file), GetLastError());
+
+ teststream_init(&stream, file);
+ callback_init(&callback);
+
+ hr = WMCreateReader(NULL, 0, &reader);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ IWMReader_QueryInterface(reader, &IID_IWMProfile, (void **)&profile);
+ IWMReader_QueryInterface(reader, &IID_IWMReaderAdvanced2, (void **)&advanced);
+
+ hr = IWMReaderAdvanced2_OpenStream(advanced, &stream.IStream_iface, &callback.IWMReaderCallback_iface, (void **)0xdeadbeef);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ if (hr != S_OK)
+ goto out;
+ ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount);
+ ok(callback.refcount > 1, "Got refcount %d.\n", callback.refcount);
+ ret = WaitForSingleObject(callback.got_opened, 1000);
+ ok(!ret, "Wait timed out.\n");
+
+ count = 0xdeadbeef;
+ hr = IWMReader_GetOutputCount(reader, &count);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(count == 2, "Got count %u.\n", count);
+
+ for (i = 0; i < 2; ++i)
+ {
+ hr = IWMProfile_GetStream(profile, i, &config);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ stream_numbers[i] = 0xdead;
+ hr = IWMStreamConfig_GetStreamNumber(config, &stream_numbers[i]);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]);
+
+ ref = IWMStreamConfig_Release(config);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ }
+
+ hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ if (hr == S_OK)
+ {
+ /* By default the reader will time itself, and attempt to deliver samples
+ * according to their presentation time. Call DeliverTime with the file
+ * duration in order to request all samples as fast as possible. */
+ hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000);
+ ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr);
+ hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ret = WaitForSingleObject(callback.eof_event, 20000);
+ ok(!ret, "Wait timed out.\n");
+ ok(callback.got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback.got_eof);
+
+ hr = IWMReader_Stop(reader);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ret = WaitForSingleObject(callback.got_stopped, 5000);
+ ok(!ret, "Wait timed out.\n");
+
+ hr = IWMReader_Stop(reader);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ret = WaitForSingleObject(callback.got_stopped, 1000);
+ ok(!ret, "Wait timed out.\n");
+ }
+
+ test_reader_attributes(profile);
+
+ hr = IWMReader_Close(reader);
+ todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(callback.got_closed == 1, "Got %u WMT_CLOSED callbacks.\n", callback.got_closed);
+ ok(callback.refcount == 1, "Got outstanding refcount %d.\n", callback.refcount);
+ callback_cleanup(&callback);
+
+out:
+ ok(stream.refcount == 1, "Got outstanding refcount %d.\n", stream.refcount);
+ CloseHandle(stream.file);
+ ret = DeleteFileW(filename);
+ ok(ret, "Failed to delete %s, error %u.\n", debugstr_w(filename), GetLastError());
+
+ hr = IWMReader_Close(reader);
+ todo_wine ok(hr == NS_E_INVALID_REQUEST, "Got hr %#x.\n", hr);
+
+ IWMReaderAdvanced2_Release(advanced);
+ IWMProfile_Release(profile);
+ ref = IWMReader_Release(reader);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
+
START_TEST(wmvcore)
{
HRESULT hr;
@@ -1070,6 +1344,7 @@ START_TEST(wmvcore)
test_sync_reader_streaming();
test_sync_reader_types();
test_sync_reader_file();
+ test_async_reader_streaming();
CoUninitialize();
}
--
2.33.0
Nov. 3, 2021
[PATCH] dmime: Accept a DMUS_IO_SEGMENT_HEADER without rtPlayStart field
by Michael Stefaniuc
Tron 2.0 has a segment header of 56, so is missing the rtPlayStart field.
Based on a patch by Alistair Leslie-Hughes.
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
The demo shows the same problem. All 112 segments that get loaded for me
have a segment header of 56 bytes.
dlls/dmime/segment.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c
index f5dbf4b9959..326ffe98e18 100644
--- a/dlls/dmime/segment.c
+++ b/dlls/dmime/segment.c
@@ -727,7 +727,8 @@ static inline void dump_segment_header(DMUS_IO_SEGMENT_HEADER *h, DWORD size)
if (dx == 9) {
TRACE("\trtLoopStart: %s\n", wine_dbgstr_longlong(h->rtLoopStart));
TRACE("\trtLoopEnd: %s\n", wine_dbgstr_longlong(h->rtLoopEnd));
- TRACE("\trtPlayStart: %s\n", wine_dbgstr_longlong(h->rtPlayStart));
+ if (size > offsetof(DMUS_IO_SEGMENT_HEADER, rtPlayStart))
+ TRACE("\trtPlayStart: %s\n", wine_dbgstr_longlong(h->rtPlayStart));
}
}
@@ -742,8 +743,11 @@ static HRESULT parse_segment_form(IDirectMusicSegment8Impl *This, IStream *strea
while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) {
switch (chunk.id) {
case DMUS_FOURCC_SEGMENT_CHUNK:
+ /* DX9 without rtPlayStart field */
+ if (chunk.size == offsetof(DMUS_IO_SEGMENT_HEADER, rtPlayStart))
+ WARN("Missing rtPlayStart field in %s\n", debugstr_chunk(&chunk));
/* DX7, DX8 and DX9 structure sizes */
- if (chunk.size != offsetof(DMUS_IO_SEGMENT_HEADER, rtLength) &&
+ else if (chunk.size != offsetof(DMUS_IO_SEGMENT_HEADER, rtLength) &&
chunk.size != offsetof(DMUS_IO_SEGMENT_HEADER, rtLoopStart) &&
chunk.size != sizeof(DMUS_IO_SEGMENT_HEADER)) {
WARN("Invalid size of %s\n", debugstr_chunk(&chunk));
--
2.31.1
Nov. 2, 2021
[PATCH 8/8] wined3d: Try to allocate new Vulkan BOs from the client thread for DISCARD maps.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 7 ++++
dlls/wined3d/adapter_vk.c | 57 +++++++++++++++++++++++++++++++++
dlls/wined3d/buffer.c | 58 +++++++++++++++++++++++++++++++++-
dlls/wined3d/cs.c | 32 +++++++++++++++----
dlls/wined3d/directx.c | 7 ++++
dlls/wined3d/wined3d_private.h | 19 +++++++++++
6 files changed, 173 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index f1cdbffe718..37f055662ea 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4604,6 +4604,12 @@ static void adapter_gl_flush_bo_address(struct wined3d_context *context,
wined3d_context_gl_flush_bo_address(wined3d_context_gl(context), data, size);
}
+static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ return false;
+}
+
static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -5057,6 +5063,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
.adapter_unmap_bo_address = adapter_gl_unmap_bo_address,
.adapter_copy_bo_address = adapter_gl_copy_bo_address,
.adapter_flush_bo_address = adapter_gl_flush_bo_address,
+ .adapter_alloc_bo = adapter_gl_alloc_bo,
.adapter_create_swapchain = adapter_gl_create_swapchain,
.adapter_destroy_swapchain = adapter_gl_destroy_swapchain,
.adapter_create_buffer = adapter_gl_create_buffer,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 19763b49267..002d9e07a00 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -23,6 +23,7 @@
#include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
static const struct wined3d_state_entry_template misc_state_template_vk[] =
{
@@ -1205,6 +1206,61 @@ static void adapter_vk_flush_bo_address(struct wined3d_context *context,
flush_bo_range(context_vk, bo, (uintptr_t)data->addr, size);
}
+struct wined3d_client_bo_vk_map_ctx
+{
+ struct wined3d_device *device;
+ struct wined3d_client_bo_vk *client_bo;
+};
+
+static void wined3d_client_bo_vk_map_cs(void *object)
+{
+ const struct wined3d_client_bo_vk_map_ctx *ctx = object;
+ struct wined3d_context_vk *context_vk;
+
+ context_vk = wined3d_context_vk(context_acquire(ctx->device, NULL, 0));
+ if (!wined3d_bo_vk_map(&ctx->client_bo->bo, context_vk))
+ ERR("Failed to map bo.\n");
+ context_release(&context_vk->c);
+}
+
+static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ wined3d_not_from_cs(device->cs);
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource));
+ struct wined3d_client_bo_vk *client_bo;
+
+ if (!(client_bo = heap_alloc(sizeof(*client_bo))))
+ return false;
+
+ if (!wined3d_buffer_vk_create_buffer_object(buffer_vk, NULL, &client_bo->bo))
+ {
+ heap_free(client_bo);
+ return false;
+ }
+
+ if (!client_bo->bo.b.map_ptr)
+ {
+ struct wined3d_client_bo_vk_map_ctx ctx = {.device = device, .client_bo = client_bo};
+
+ WARN_(d3d_perf)("BO %p (chunk %p, slab %p) is not persistently mapped.\n", &client_bo->bo,
+ client_bo->bo.memory ? client_bo->bo.memory->chunk : NULL, client_bo->bo.slab);
+
+ wined3d_cs_map_object(device->cs, wined3d_client_bo_vk_map_cs, &ctx);
+ wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_MAP);
+ }
+
+ addr->buffer_object = (uintptr_t)&client_bo->bo;
+ addr->addr = NULL;
+ return true;
+ }
+
+ return false;
+}
+
static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -1858,6 +1914,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
.adapter_unmap_bo_address = adapter_vk_unmap_bo_address,
.adapter_copy_bo_address = adapter_vk_copy_bo_address,
.adapter_flush_bo_address = adapter_vk_flush_bo_address,
+ .adapter_alloc_bo = adapter_vk_alloc_bo,
.adapter_create_swapchain = adapter_vk_create_swapchain,
.adapter_destroy_swapchain = adapter_vk_destroy_swapchain,
.adapter_create_buffer = adapter_vk_create_buffer,
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 99a8683df48..fe7debfd92d 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1061,6 +1061,16 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou
return WINED3D_OK;
}
+void wined3d_buffer_rename(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ TRACE("buffer %p, context %p, bo %p.\n", buffer, context, bo);
+
+ buffer->buffer_ops->buffer_rename_bo(buffer, context, bo);
+ buffer->buffer_object = (uintptr_t)bo;
+ wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_BUFFER);
+ wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER);
+}
+
void wined3d_buffer_copy_bo_address(struct wined3d_buffer *dst_buffer, struct wined3d_context *context,
unsigned int dst_offset, const struct wined3d_const_bo_address *src_addr, unsigned int size)
{
@@ -1256,12 +1266,19 @@ static void wined3d_buffer_no3d_download_ranges(struct wined3d_buffer *buffer, s
FIXME("Not implemented.\n");
}
+static void wined3d_buffer_no3d_rename_bo(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ FIXME("Not implemented.\n");
+}
+
static const struct wined3d_buffer_ops wined3d_buffer_no3d_ops =
{
wined3d_buffer_no3d_prepare_location,
wined3d_buffer_no3d_unload_location,
wined3d_buffer_no3d_upload_ranges,
wined3d_buffer_no3d_download_ranges,
+ wined3d_buffer_no3d_rename_bo,
};
HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device,
@@ -1366,12 +1383,19 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
checkGLcall("buffer download");
}
+static void wined3d_buffer_gl_rename_bo(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ FIXME("Not implemented.\n");
+}
+
static const struct wined3d_buffer_ops wined3d_buffer_gl_ops =
{
wined3d_buffer_gl_prepare_location,
wined3d_buffer_gl_unload_location,
wined3d_buffer_gl_upload_ranges,
wined3d_buffer_gl_download_ranges,
+ wined3d_buffer_gl_rename_bo,
};
HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device,
@@ -1399,7 +1423,7 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops);
}
-static BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_vk *buffer_vk,
+BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_vk *buffer_vk,
struct wined3d_context_vk *context_vk, struct wined3d_bo_vk *bo)
{
const struct wined3d_resource *resource = &buffer_vk->b.resource;
@@ -1568,12 +1592,44 @@ static void wined3d_buffer_vk_download_ranges(struct wined3d_buffer *buffer, str
FIXME("Not implemented.\n");
}
+static void wined3d_buffer_vk_rename_bo(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, struct wined3d_bo *bo)
+{
+ struct wined3d_bo_vk *prev_bo = (struct wined3d_bo_vk *)buffer->buffer_object;
+ struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
+ struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer);
+ struct wined3d_bo_vk *bo_vk = wined3d_bo_vk(bo);
+
+ if (prev_bo)
+ {
+ struct wined3d_bo_user *bo_user;
+
+ LIST_FOR_EACH_ENTRY(bo_user, &prev_bo->b.users, struct wined3d_bo_user, entry)
+ bo_user->valid = false;
+ assert(list_empty(&bo_vk->b.users));
+ list_move_head(&bo_vk->b.users, &prev_bo->b.users);
+
+ if (prev_bo != &buffer_vk->bo)
+ {
+ struct wined3d_client_bo_vk *client_bo = CONTAINING_RECORD(prev_bo, struct wined3d_client_bo_vk, bo);
+
+ wined3d_context_vk_destroy_bo(context_vk, &client_bo->bo);
+ heap_free(client_bo);
+ }
+ }
+ else
+ {
+ list_add_head(&bo_vk->b.users, &buffer_vk->b.bo_user.entry);
+ }
+}
+
static const struct wined3d_buffer_ops wined3d_buffer_vk_ops =
{
wined3d_buffer_vk_prepare_location,
wined3d_buffer_vk_unload_location,
wined3d_buffer_vk_upload_ranges,
wined3d_buffer_vk_download_ranges,
+ wined3d_buffer_vk_rename_bo,
};
HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device,
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index e6ff448b028..6978e6bf3cb 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2304,26 +2304,32 @@ static void wined3d_cs_exec_callback(struct wined3d_cs *cs, const void *data)
op->callback(op->object);
}
-static void wined3d_cs_emit_callback(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
+static void wined3d_cs_emit_callback(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id,
+ void (*callback)(void *object), void *object)
{
struct wined3d_cs_callback *op;
- op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+ op = wined3d_device_context_require_space(&cs->c, sizeof(*op), queue_id);
op->opcode = WINED3D_CS_OP_CALLBACK;
op->callback = callback;
op->object = object;
- wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT);
+ wined3d_device_context_submit(&cs->c, queue_id);
}
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
{
- wined3d_cs_emit_callback(cs, callback, object);
+ wined3d_cs_emit_callback(cs, WINED3D_CS_QUEUE_DEFAULT, callback, object);
}
void wined3d_cs_init_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
{
- wined3d_cs_emit_callback(cs, callback, object);
+ wined3d_cs_emit_callback(cs, WINED3D_CS_QUEUE_DEFAULT, callback, object);
+}
+
+void wined3d_cs_map_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object)
+{
+ wined3d_cs_emit_callback(cs, WINED3D_CS_QUEUE_MAP, callback, object);
}
static void wined3d_cs_exec_query_issue(struct wined3d_cs *cs, const void *data)
@@ -2747,6 +2753,9 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi
struct wined3d_buffer *buffer = buffer_from_resource(resource);
size_t size = box->right - box->left;
+ if (op->bo.flags & UPLOAD_BO_RENAME_ON_UNMAP)
+ wined3d_buffer_rename(buffer, context, (struct wined3d_bo *)op->bo.addr.buffer_object);
+
if (op->bo.addr.buffer_object && op->bo.addr.buffer_object == buffer->buffer_object)
wined3d_context_flush_bo_address(context, &op->bo.addr, size);
else
@@ -3121,12 +3130,20 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
{
/* Limit NOOVERWRITE maps to buffers for now; there are too many ways that
* a texture can be invalidated to even count. */
- if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER && (flags & WINED3D_MAP_NOOVERWRITE))
+ if (wined3d_map_persistent() && resource->type == WINED3D_RTYPE_BUFFER
+ && (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
{
struct wined3d_client_resource *client = &resource->client;
+ struct wined3d_device *device = context->device;
const struct wined3d_bo *bo;
uint8_t *map_ptr;
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ if (!device->adapter->adapter_ops->adapter_alloc_bo(device, resource, sub_resource_idx, &client->addr))
+ return NULL;
+ }
+
bo = (const struct wined3d_bo *)client->addr.buffer_object;
map_ptr = bo ? bo->map_ptr : NULL;
map_ptr += (uintptr_t)client->addr.addr;
@@ -3150,6 +3167,9 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
}
map_desc->data = resource_offset_map_pointer(resource, sub_resource_idx, map_ptr, box);
+ if (flags & WINED3D_MAP_DISCARD)
+ client->mapped_upload.flags |= UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_RENAME_ON_UNMAP;
+
client->mapped_box = *box;
TRACE("Returning bo %s, flags %#x.\n", debug_const_bo_address(&client->mapped_upload.addr),
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index c265bdc8c95..f14f57fd3f4 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2805,6 +2805,12 @@ static void adapter_no3d_flush_bo_address(struct wined3d_context *context,
{
}
+static bool adapter_no3d_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
+{
+ return false;
+}
+
static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -3075,6 +3081,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
.adapter_unmap_bo_address = adapter_no3d_unmap_bo_address,
.adapter_copy_bo_address = adapter_no3d_copy_bo_address,
.adapter_flush_bo_address = adapter_no3d_flush_bo_address,
+ .adapter_alloc_bo = adapter_no3d_alloc_bo,
.adapter_create_swapchain = adapter_no3d_create_swapchain,
.adapter_destroy_swapchain = adapter_no3d_destroy_swapchain,
.adapter_create_buffer = adapter_no3d_create_buffer,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index fab1c755a81..568eebb5ace 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1639,6 +1639,16 @@ struct wined3d_bo_vk
bool host_synced;
};
+static inline struct wined3d_bo_vk *wined3d_bo_vk(struct wined3d_bo *bo)
+{
+ return CONTAINING_RECORD(bo, struct wined3d_bo_vk, b);
+}
+
+struct wined3d_client_bo_vk
+{
+ struct wined3d_bo_vk bo;
+};
+
struct wined3d_bo_slab_vk_key
{
VkMemoryPropertyFlags memory_type;
@@ -3335,6 +3345,7 @@ bool wined3d_driver_info_init(struct wined3d_driver_info *driver_info,
UINT64 vram_bytes, UINT64 sysmem_bytes) DECLSPEC_HIDDEN;
#define UPLOAD_BO_UPLOAD_ON_UNMAP 0x1
+#define UPLOAD_BO_RENAME_ON_UNMAP 0x2
struct upload_bo
{
@@ -3367,6 +3378,8 @@ struct wined3d_adapter_ops
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size);
void (*adapter_flush_bo_address)(struct wined3d_context *context,
const struct wined3d_const_bo_address *data, size_t size);
+ bool (*adapter_alloc_bo)(struct wined3d_device *device, struct wined3d_resource *resource,
+ unsigned int sub_resource_idx, struct wined3d_bo_address *addr);
HRESULT (*adapter_create_swapchain)(struct wined3d_device *device,
struct wined3d_swapchain_desc *desc,
struct wined3d_swapchain_state_parent *state_parent, void *parent,
@@ -4874,6 +4887,7 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs,
void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_cs_init_object(struct wined3d_cs *cs,
void (*callback)(void *object), void *object) DECLSPEC_HIDDEN;
+void wined3d_cs_map_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) DECLSPEC_HIDDEN;
static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id)
{
@@ -5002,6 +5016,7 @@ struct wined3d_buffer_ops
unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges);
void (*buffer_download_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, void *data,
unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges);
+ void (*buffer_rename_bo)(struct wined3d_buffer *buffer, struct wined3d_context *context, struct wined3d_bo *bo);
};
struct wined3d_buffer
@@ -5047,6 +5062,8 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location) DECLSPEC_HIDDEN;
+void wined3d_buffer_rename(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, struct wined3d_bo *bo) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_no3d_init(struct wined3d_buffer *buffer_no3d, struct wined3d_device *device,
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
@@ -5089,6 +5106,8 @@ static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer
void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
struct wined3d_context_vk *context_vk, uint32_t bind_mask) DECLSPEC_HIDDEN;
+BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_vk *buffer_vk,
+ struct wined3d_context_vk *context_vk, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device,
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
--
2.33.0
Nov. 2, 2021
[PATCH 7/8] wined3d: Avoid accessing the "bo" member of struct wined3d_buffer_vk.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 4 ++--
dlls/wined3d/buffer.c | 13 ++++++++-----
dlls/wined3d/context_vk.c | 8 ++++----
dlls/wined3d/view.c | 14 ++++++++++----
dlls/wined3d/wined3d_private.h | 2 +-
5 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 020a70b4ed4..19763b49267 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1735,7 +1735,7 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
if (parameters->indirect)
{
- struct wined3d_bo_vk *bo = &indirect_vk->bo;
+ struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object;
uint32_t stride, size;
wined3d_context_vk_reference_bo(context_vk, bo);
@@ -1807,7 +1807,7 @@ static void adapter_vk_dispatch_compute(struct wined3d_device *device,
if (parameters->indirect)
{
- struct wined3d_bo_vk *bo = &indirect_vk->bo;
+ struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)indirect_vk->b.buffer_object;
wined3d_context_vk_reference_bo(context_vk, bo);
VK_CALL(vkCmdDispatchIndirect(vk_command_buffer, bo->vk_buffer,
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 56cce00301e..99a8683df48 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1439,11 +1439,13 @@ static BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_v
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk)
{
+ struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+
if (buffer_vk->b.bo_user.valid)
return &buffer_vk->buffer_info;
- buffer_vk->buffer_info.buffer = buffer_vk->bo.vk_buffer;
- buffer_vk->buffer_info.offset = buffer_vk->bo.buffer_offset;
+ buffer_vk->buffer_info.buffer = bo->vk_buffer;
+ buffer_vk->buffer_info.offset = bo->buffer_offset;
buffer_vk->buffer_info.range = buffer_vk->b.resource.size;
buffer_vk->b.bo_user.valid = true;
@@ -1528,7 +1530,7 @@ static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struc
if (!ranges->offset && ranges->size == resource->size)
flags |= WINED3D_MAP_DISCARD;
- dst_bo = &wined3d_buffer_vk(buffer)->bo;
+ dst_bo = (struct wined3d_bo_vk *)buffer->buffer_object;
if (!(dst_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || (!(flags & WINED3D_MAP_DISCARD)
&& dst_bo->command_buffer_id > context_vk->completed_command_buffer_id))
{
@@ -1620,6 +1622,7 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
if (src_bind_mask)
{
+ const struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
VkBufferMemoryBarrier vk_barrier;
@@ -1634,8 +1637,8 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
vk_barrier.dstAccessMask = vk_access_mask_from_bind_flags(bind_mask);
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- vk_barrier.buffer = buffer_vk->bo.vk_buffer;
- vk_barrier.offset = buffer_vk->bo.buffer_offset;
+ vk_barrier.buffer = bo->vk_buffer;
+ vk_barrier.offset = bo->buffer_offset;
vk_barrier.size = buffer_vk->b.resource.size;
VK_CALL(vkCmdPipelineBarrier(wined3d_context_vk_get_command_buffer(context_vk),
vk_pipeline_stage_mask_from_bind_flags(src_bind_mask),
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 25c41a49c34..cbd108b01f2 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -2473,7 +2473,7 @@ static void wined3d_context_vk_bind_vertex_buffers(struct wined3d_context_vk *co
{
buffer_vk = wined3d_buffer_vk(buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
+ wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
buffers[count] = buffer_info->buffer;
offsets[count] = buffer_info->offset + stream->offset;
++count;
@@ -2512,7 +2512,7 @@ static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context
{
buffer_vk = wined3d_buffer_vk(buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
+ wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
buffers[count] = buffer_info->buffer;
if ((offsets[count] = stream->offset) == ~0u)
{
@@ -2714,7 +2714,7 @@ static bool wined3d_shader_descriptor_writes_vk_add_cbv_write(struct wined3d_sha
if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set,
binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, buffer_info, NULL, NULL))
return false;
- wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
+ wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer->buffer_object);
return true;
}
@@ -3362,7 +3362,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
idx_type = VK_INDEX_TYPE_UINT32;
buffer_vk = wined3d_buffer_vk(state->index_buffer);
buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk);
- wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo);
+ wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_vk->b.buffer_object);
VK_CALL(vkCmdBindIndexBuffer(vk_command_buffer, buffer_info->buffer,
buffer_info->offset + state->index_offset, idx_type));
}
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 6a88286b861..5018899e181 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -672,17 +672,19 @@ static VkBufferView wined3d_view_vk_create_vk_buffer_view(struct wined3d_context
struct wined3d_device_vk *device_vk;
VkBufferView vk_buffer_view;
unsigned int offset, size;
+ struct wined3d_bo_vk *bo;
VkResult vr;
get_buffer_view_range(&buffer_vk->b, desc, &view_format_vk->f, &offset, &size);
wined3d_buffer_prepare_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER);
+ bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
create_info.pNext = NULL;
create_info.flags = 0;
- create_info.buffer = buffer_vk->bo.vk_buffer;
+ create_info.buffer = bo->vk_buffer;
create_info.format = view_format_vk->vk_format;
- create_info.offset = buffer_vk->bo.buffer_offset + offset;
+ create_info.offset = bo->buffer_offset + offset;
create_info.range = size;
device_vk = wined3d_device_vk(buffer_vk->b.resource.device);
@@ -1082,6 +1084,7 @@ static void wined3d_shader_resource_view_vk_cs_init(void *object)
VkBufferView vk_buffer_view;
uint32_t default_flags = 0;
VkImageView vk_image_view;
+ struct wined3d_bo_vk *bo;
TRACE("srv_vk %p.\n", srv_vk);
@@ -1099,12 +1102,13 @@ static void wined3d_shader_resource_view_vk_cs_init(void *object)
if (!vk_buffer_view)
return;
+ bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
srv_vk->view_vk.u.vk_buffer_view = vk_buffer_view;
srv_vk->view_vk.bo_user.valid = true;
- list_add_head(&buffer_vk->bo.b.users, &srv_vk->view_vk.bo_user.entry);
+ list_add_head(&bo->b.users, &srv_vk->view_vk.bo_user.entry);
return;
}
@@ -2204,11 +2208,13 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
if ((vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, desc, buffer_vk, format_vk)))
{
+ struct wined3d_bo_vk *bo = (struct wined3d_bo_vk *)buffer_vk->b.buffer_object;
+
TRACE("Created buffer view 0x%s.\n", wine_dbgstr_longlong(vk_buffer_view));
uav_vk->view_vk.u.vk_buffer_view = vk_buffer_view;
uav_vk->view_vk.bo_user.valid = true;
- list_add_head(&buffer_vk->bo.b.users, &view_vk->bo_user.entry);
+ list_add_head(&bo->b.users, &view_vk->bo_user.entry);
}
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 21b4ef2e103..fab1c755a81 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -6289,7 +6289,7 @@ static inline void wined3d_context_vk_reference_resource(const struct wined3d_co
struct wined3d_resource *resource)
{
if (resource->type == WINED3D_RTYPE_BUFFER)
- wined3d_context_vk_reference_bo(context_vk, &wined3d_buffer_vk(buffer_from_resource(resource))->bo);
+ wined3d_context_vk_reference_bo(context_vk, (struct wined3d_bo_vk *)buffer_from_resource(resource)->buffer_object);
else
wined3d_context_vk_reference_texture(context_vk, wined3d_texture_vk(texture_from_resource(resource)));
}
--
2.33.0
Nov. 2, 2021
[PATCH 6/8] wined3d: Allow passing a NULL context to wined3d_device_vk_create_bo().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/context_vk.c | 19 +++++++------------
dlls/wined3d/utils.c | 3 +++
2 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 21239bd74b9..25c41a49c34 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -314,14 +314,14 @@ static struct wined3d_allocator_block *wined3d_device_vk_allocate_memory(struct
EnterCriticalSection(&device_vk->allocator_cs);
- if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
+ if (context_vk && size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
{
*vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
LeaveCriticalSection(&device_vk->allocator_cs);
return NULL;
}
- if (!(block = wined3d_allocator_allocate(allocator, &context_vk->c, memory_type, size)))
+ if (!(block = wined3d_allocator_allocate(allocator, context_vk ? &context_vk->c : NULL, memory_type, size)))
{
LeaveCriticalSection(&device_vk->allocator_cs);
*vk_memory = VK_NULL_HANDLE;
@@ -345,13 +345,14 @@ static void wined3d_device_vk_free_memory(struct wined3d_device_vk *device_vk, s
static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
- const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
+ const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(device_vk->d.adapter);
const VkPhysicalDeviceLimits *limits = &adapter_vk->device_limits;
struct wined3d_bo_slab_vk_key key;
struct wined3d_bo_slab_vk *slab;
struct wine_rb_entry *entry;
size_t object_size, idx;
size_t alignment;
+ int ret;
if (size > WINED3D_ALLOCATOR_MIN_BLOCK_SIZE / 2)
return false;
@@ -398,14 +399,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
}
slab->map = ~0u;
- if (wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry) < 0)
- {
- ERR("Failed to add slab to available tree.\n");
- wined3d_context_vk_destroy_bo(context_vk, &slab->bo);
- heap_free(slab);
- return false;
- }
-
+ ret = wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry);
+ assert(!ret);
TRACE("Created new bo slab %p.\n", slab);
}
@@ -445,7 +440,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
- const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
VkMemoryRequirements memory_requirements;
struct wined3d_adapter_vk *adapter_vk;
VkBufferCreateInfo create_info;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 29326668e07..3746eff270b 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -7408,6 +7408,9 @@ struct wined3d_allocator_block *wined3d_allocator_allocate(struct wined3d_alloca
return block;
}
+ if (!context)
+ return NULL;
+
if (!(chunk = allocator->ops->allocator_create_chunk(allocator,
context, memory_type, WINED3D_ALLOCATOR_CHUNK_SIZE)))
return NULL;
--
2.33.0
Nov. 2, 2021
[PATCH 5/8] wined3d: Protect access to the Vulkan wined3d_allocator with a critical section.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 9 +++++++++
dlls/wined3d/context_vk.c | 31 +++++++++++++++++++++++++++----
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 218b7dc74ba..020a70b4ed4 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -517,6 +517,10 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
#undef VK_DEVICE_EXT_PFN
#undef VK_DEVICE_PFN
+ InitializeCriticalSection(&device_vk->allocator_cs);
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wined3d_device_vk.allocator_cs");
+
if (!wined3d_allocator_init(&device_vk->allocator,
adapter_vk->memory_properties.memoryTypeCount, &wined3d_allocator_vk_ops))
{
@@ -551,6 +555,11 @@ static void adapter_vk_destroy_device(struct wined3d_device *device)
wined3d_device_cleanup(&device_vk->d);
wined3d_allocator_cleanup(&device_vk->allocator);
+
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&device_vk->allocator_cs);
+
VK_CALL(vkDestroyDevice(device_vk->vk_device, NULL));
heap_free(device_vk);
}
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index a6a2ea8a44b..21239bd74b9 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -312,23 +312,36 @@ static struct wined3d_allocator_block *wined3d_device_vk_allocate_memory(struct
struct wined3d_allocator *allocator = &device_vk->allocator;
struct wined3d_allocator_block *block;
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
{
*vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
+ LeaveCriticalSection(&device_vk->allocator_cs);
return NULL;
}
if (!(block = wined3d_allocator_allocate(allocator, &context_vk->c, memory_type, size)))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
*vk_memory = VK_NULL_HANDLE;
return NULL;
}
*vk_memory = wined3d_allocator_chunk_vk(block->chunk)->vk_memory;
+ LeaveCriticalSection(&device_vk->allocator_cs);
return block;
}
+static void wined3d_device_vk_free_memory(struct wined3d_device_vk *device_vk, struct wined3d_allocator_block *block)
+{
+ assert(block->chunk->allocator == &device_vk->allocator);
+ EnterCriticalSection(&device_vk->allocator_cs);
+ wined3d_allocator_block_free(block);
+ LeaveCriticalSection(&device_vk->allocator_cs);
+}
+
static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
@@ -359,6 +372,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
key.usage = usage;
key.size = 32 * object_size;
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if ((entry = wine_rb_get(&device_vk->bo_slab_available, &key)))
{
slab = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
@@ -368,6 +383,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
{
if (!(slab = heap_alloc_zero(sizeof(*slab))))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
ERR("Failed to allocate bo slab.\n");
return false;
}
@@ -375,6 +391,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
slab->requested_memory_type = memory_type;
if (!wined3d_device_vk_create_bo(device_vk, context_vk, key.size, usage, memory_type, &slab->bo))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
ERR("Failed to create slab bo.\n");
heap_free(slab);
return false;
@@ -406,6 +423,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
}
}
+ LeaveCriticalSection(&device_vk->allocator_cs);
+
*bo = slab->bo;
bo->memory = NULL;
bo->slab = slab;
@@ -478,7 +497,7 @@ BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct win
{
ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
if (bo->memory)
- wined3d_allocator_block_free(bo->memory);
+ wined3d_device_vk_free_memory(device_vk, bo->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL));
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
@@ -572,7 +591,7 @@ BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkIm
{
VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
if (image->memory)
- wined3d_allocator_block_free(image->memory);
+ wined3d_device_vk_free_memory(device_vk, image->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, image->vk_memory, NULL));
ERR("Failed to bind image memory, vr %s.\n", wined3d_debug_vkresult(vr));
@@ -686,7 +705,7 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
if (context_vk->completed_command_buffer_id > command_buffer_id)
{
- wined3d_allocator_block_free(block);
+ wined3d_device_vk_free_memory(wined3d_device_vk(context_vk->c.device), block);
TRACE("Freed block %p.\n", block);
return;
}
@@ -711,6 +730,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
TRACE("slab %p, idx %lu, context_vk %p.\n", slab, idx, context_vk);
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if (!slab->map)
{
key.memory_type = slab->requested_memory_type;
@@ -728,6 +749,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
}
}
slab->map |= 1u << idx;
+
+ LeaveCriticalSection(&device_vk->allocator_cs);
}
static void wined3d_context_vk_destroy_bo_slab_slice(struct wined3d_context_vk *context_vk,
@@ -999,7 +1022,7 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
case WINED3D_RETIRED_ALLOCATOR_BLOCK_VK:
TRACE("Destroying block %p.\n", o->u.block);
- wined3d_allocator_block_free(o->u.block);
+ wined3d_device_vk_free_memory(device_vk, o->u.block);
break;
case WINED3D_RETIRED_BO_SLAB_SLICE_VK:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d8b16c0d074..21b4ef2e103 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4081,6 +4081,7 @@ struct wined3d_device_vk
struct wined3d_null_resources_vk null_resources_vk;
struct wined3d_null_views_vk null_views_vk;
+ CRITICAL_SECTION allocator_cs;
struct wined3d_allocator allocator;
struct wined3d_uav_clear_state_vk uav_clear_state;
--
2.33.0
Nov. 2, 2021
[PATCH 4/8] wined3d: Pass a wined3d_bo_vk pointer to wined3d_buffer_vk_create_buffer_object().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index d4efecb2241..56cce00301e 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1399,10 +1399,10 @@ HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined
return wined3d_buffer_init(&buffer_gl->b, device, desc, data, parent, parent_ops, &wined3d_buffer_gl_ops);
}
-static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buffer_vk,
- struct wined3d_context_vk *context_vk)
+static BOOL wined3d_buffer_vk_create_buffer_object(const struct wined3d_buffer_vk *buffer_vk,
+ struct wined3d_context_vk *context_vk, struct wined3d_bo_vk *bo)
{
- struct wined3d_resource *resource = &buffer_vk->b.resource;
+ const struct wined3d_resource *resource = &buffer_vk->b.resource;
uint32_t bind_flags = resource->bind_flags;
VkMemoryPropertyFlags memory_type;
VkBufferUsageFlags usage;
@@ -1433,19 +1433,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- if (!(wined3d_device_vk_create_bo(wined3d_device_vk(resource->device),
- context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
- {
- WARN("Failed to create Vulkan buffer.\n");
- return FALSE;
- }
-
- list_init(&buffer_vk->b.bo_user.entry);
- list_add_head(&buffer_vk->bo.b.users, &buffer_vk->b.bo_user.entry);
- buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
- buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
-
- return TRUE;
+ return wined3d_device_vk_create_bo(wined3d_device_vk(resource->device),
+ context_vk, resource->size, usage, memory_type, bo);
}
const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk)
@@ -1464,6 +1453,8 @@ const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_b
static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location)
{
+ struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer);
+
switch (location)
{
case WINED3D_LOCATION_SYSMEM:
@@ -1473,7 +1464,16 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
if (buffer->buffer_object)
return TRUE;
- return wined3d_buffer_vk_create_buffer_object(wined3d_buffer_vk(buffer), wined3d_context_vk(context));
+ if (!wined3d_buffer_vk_create_buffer_object(buffer_vk, wined3d_context_vk(context), &buffer_vk->bo))
+ {
+ WARN("Failed to create Vulkan buffer.\n");
+ return FALSE;
+ }
+
+ list_add_head(&buffer_vk->bo.b.users, &buffer_vk->b.bo_user.entry);
+ buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo;
+ buffer_invalidate_bo_range(&buffer_vk->b, 0, 0);
+ return TRUE;
default:
FIXME("Unhandled location %s.\n", wined3d_debug_location(location));
--
2.33.0
Nov. 2, 2021
[PATCH 3/8] wined3d: Move the bo_slab_available field to struct wined3d_device_vk.
by Zebediah Figura
In order to allow slab allocation from the client thread.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 13 +++++++++++++
dlls/wined3d/context_vk.c | 30 +++++++++---------------------
dlls/wined3d/wined3d_private.h | 2 +-
3 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index da1302265ca..218b7dc74ba 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -397,6 +397,18 @@ static const struct wined3d_allocator_ops wined3d_allocator_vk_ops =
.allocator_destroy_chunk = wined3d_allocator_vk_destroy_chunk,
};
+static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry);
+ const struct wined3d_bo_slab_vk_key *k = key;
+
+ if (k->memory_type != slab->requested_memory_type)
+ return k->memory_type - slab->requested_memory_type;
+ if (k->usage != slab->bo.usage)
+ return k->usage - slab->bo.usage;
+ return k->size - slab->bo.size;
+}
+
static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
const enum wined3d_feature_level *levels, unsigned int level_count,
@@ -512,6 +524,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
hr = E_FAIL;
goto fail;
}
+ wine_rb_init(&device_vk->bo_slab_available, wined3d_bo_slab_vk_compare);
if (FAILED(hr = wined3d_device_init(&device_vk->d, wined3d, adapter->ordinal, device_type, focus_window,
flags, surface_alignment, levels, level_count, vk_info->supported, device_parent)))
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 9854ca70ef0..a6a2ea8a44b 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -359,7 +359,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
key.usage = usage;
key.size = 32 * object_size;
- if ((entry = wine_rb_get(&context_vk->bo_slab_available, &key)))
+ if ((entry = wine_rb_get(&device_vk->bo_slab_available, &key)))
{
slab = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
TRACE("Using existing bo slab %p.\n", slab);
@@ -381,7 +381,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
}
slab->map = ~0u;
- if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
+ if (wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry) < 0)
{
ERR("Failed to add slab to available tree.\n");
wined3d_context_vk_destroy_bo(context_vk, &slab->bo);
@@ -397,12 +397,12 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
{
if (slab->next)
{
- wine_rb_replace(&context_vk->bo_slab_available, &slab->entry, &slab->next->entry);
+ wine_rb_replace(&device_vk->bo_slab_available, &slab->entry, &slab->next->entry);
slab->next = NULL;
}
else
{
- wine_rb_remove(&context_vk->bo_slab_available, &slab->entry);
+ wine_rb_remove(&device_vk->bo_slab_available, &slab->entry);
}
}
@@ -705,6 +705,7 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
SIZE_T idx, struct wined3d_context_vk *context_vk)
{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
struct wined3d_bo_slab_vk_key key;
struct wine_rb_entry *entry;
@@ -716,12 +717,12 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
key.usage = slab->bo.usage;
key.size = slab->bo.size;
- if ((entry = wine_rb_get(&context_vk->bo_slab_available, &key)))
+ if ((entry = wine_rb_get(&device_vk->bo_slab_available, &key)))
{
slab->next = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
- wine_rb_replace(&context_vk->bo_slab_available, entry, &slab->entry);
+ wine_rb_replace(&device_vk->bo_slab_available, entry, &slab->entry);
}
- else if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
+ else if (wine_rb_put(&device_vk->bo_slab_available, &key, &slab->entry) < 0)
{
ERR("Unable to return slab %p (map 0x%08x) to available tree.\n", slab, slab->map);
}
@@ -1458,7 +1459,7 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_timestamp_query_pools);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_pipeline_statistics_query_pools);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_stream_output_statistics_query_pools);
- wine_rb_destroy(&context_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk);
+ wine_rb_destroy(&device_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk);
heap_free(context_vk->pending_queries.queries);
heap_free(context_vk->submitted.buffers);
heap_free(context_vk->retired.objects);
@@ -1825,18 +1826,6 @@ static int wined3d_graphics_pipeline_vk_compare(const void *key, const struct wi
return 0;
}
-static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry)
-{
- const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry);
- const struct wined3d_bo_slab_vk_key *k = key;
-
- if (k->memory_type != slab->requested_memory_type)
- return k->memory_type - slab->requested_memory_type;
- if (k->usage != slab->bo.usage)
- return k->usage - slab->bo.usage;
- return k->size - slab->bo.size;
-}
-
static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context_vk *context_vk)
{
struct wined3d_graphics_pipeline_key_vk *key;
@@ -3508,7 +3497,6 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare);
wine_rb_init(&context_vk->graphics_pipelines, wined3d_graphics_pipeline_vk_compare);
- wine_rb_init(&context_vk->bo_slab_available, wined3d_bo_slab_vk_compare);
return WINED3D_OK;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b2525110adc..d8b16c0d074 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2622,7 +2622,6 @@ struct wined3d_context_vk
struct wine_rb_tree render_passes;
struct wine_rb_tree pipeline_layouts;
struct wine_rb_tree graphics_pipelines;
- struct wine_rb_tree bo_slab_available;
};
static inline struct wined3d_context_vk *wined3d_context_vk(struct wined3d_context *context)
@@ -4085,6 +4084,7 @@ struct wined3d_device_vk
struct wined3d_allocator allocator;
struct wined3d_uav_clear_state_vk uav_clear_state;
+ struct wine_rb_tree bo_slab_available;
};
static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device *device)
--
2.33.0
Nov. 2, 2021
[PATCH 2/8] wined3d: Pass a wined3d_device_vk to wined3d_context_vk_allocate_memory().
by Zebediah Figura
With the goal of making the context_vk parameter optional, so that we can
allocate new BOs from the client thread.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/context_vk.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 63de2f0f052..9854ca70ef0 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -306,10 +306,9 @@ VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_cont
return vk_memory;
}
-static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk,
- unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory)
+static struct wined3d_allocator_block *wined3d_device_vk_allocate_memory(struct wined3d_device_vk *device_vk,
+ struct wined3d_context_vk *context_vk, unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory)
{
- struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
struct wined3d_allocator *allocator = &device_vk->allocator;
struct wined3d_allocator_block *block;
@@ -330,7 +329,7 @@ static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct
return block;
}
-static bool wined3d_context_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
+static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
@@ -434,7 +433,7 @@ BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct win
unsigned int memory_type_idx;
VkResult vr;
- if (wined3d_context_vk_create_slab_bo(device_vk, context_vk, size, usage, memory_type, bo))
+ if (wined3d_device_vk_create_slab_bo(device_vk, context_vk, size, usage, memory_type, bo))
return TRUE;
adapter_vk = wined3d_adapter_vk(device_vk->d.adapter);
@@ -464,7 +463,7 @@ BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct win
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
return FALSE;
}
- bo->memory = wined3d_context_vk_allocate_memory(context_vk,
+ bo->memory = wined3d_device_vk_allocate_memory(device_vk, context_vk,
memory_type_idx, memory_requirements.size, &bo->vk_memory);
if (!bo->vk_memory)
{
@@ -557,7 +556,7 @@ BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkIm
return FALSE;
}
- image->memory = wined3d_context_vk_allocate_memory(context_vk, memory_type_idx,
+ image->memory = wined3d_device_vk_allocate_memory(device_vk, context_vk, memory_type_idx,
memory_requirements.size, &image->vk_memory);
if (!image->vk_memory)
{
--
2.33.0
Nov. 2, 2021
[PATCH 1/8] wined3d: Pass a wined3d_device_vk to wined3d_context_vk_create_bo().
by Zebediah Figura
With the goal of making the context_vk parameter optional, so that we can
allocate new BOs from the client thread.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 10 ++++++----
dlls/wined3d/buffer.c | 3 ++-
dlls/wined3d/context_vk.c | 11 +++++------
dlls/wined3d/device.c | 2 +-
dlls/wined3d/texture.c | 9 ++++++---
dlls/wined3d/view.c | 6 +++---
dlls/wined3d/wined3d_private.h | 5 +++--
7 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 02a359c4f07..da1302265ca 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -936,7 +936,7 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
if ((map_flags & WINED3D_MAP_DISCARD) && bo->command_buffer_id > context_vk->completed_command_buffer_id)
{
- if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
+ if (wined3d_device_vk_create_bo(device_vk, context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
{
bool host_synced = bo->host_synced;
list_move_head(&tmp.b.users, &bo->b.users);
@@ -1045,6 +1045,7 @@ static void adapter_vk_unmap_bo_address(struct wined3d_context *context,
void adapter_vk_copy_bo_address(struct wined3d_context *context,
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size)
{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context->device);
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
struct wined3d_bo_vk staging_bo, *src_bo, *dst_bo;
@@ -1122,7 +1123,7 @@ void adapter_vk_copy_bo_address(struct wined3d_context *context,
if (src_bo && !(src_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
{
- if (!(wined3d_context_vk_create_bo(context_vk, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
+ if (!(wined3d_device_vk_create_bo(device_vk, context_vk, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo)))
{
ERR("Failed to create staging bo.\n");
@@ -1142,7 +1143,7 @@ void adapter_vk_copy_bo_address(struct wined3d_context *context,
if (dst_bo && (!(dst_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || (!(map_flags & WINED3D_MAP_DISCARD)
&& dst_bo->command_buffer_id > context_vk->completed_command_buffer_id)))
{
- if (!(wined3d_context_vk_create_bo(context_vk, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+ if (!(wined3d_device_vk_create_bo(device_vk, context_vk, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo)))
{
ERR("Failed to create staging bo.\n");
@@ -1691,7 +1692,8 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
{
struct wined3d_bo_vk *bo = &context_vk->vk_so_counter_bo;
- if (!wined3d_context_vk_create_bo(context_vk, ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2,
+ if (!wined3d_device_vk_create_bo(wined3d_device_vk(device), context_vk,
+ ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2,
VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo))
ERR("Failed to create counter BO.\n");
for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 55dcd9e67e8..d4efecb2241 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1433,7 +1433,8 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf
else if (!(resource->usage & WINED3DUSAGE_DYNAMIC))
memory_type |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- if (!(wined3d_context_vk_create_bo(context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
+ if (!(wined3d_device_vk_create_bo(wined3d_device_vk(resource->device),
+ context_vk, resource->size, usage, memory_type, &buffer_vk->bo)))
{
WARN("Failed to create Vulkan buffer.\n");
return FALSE;
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index ad7b0a8ba86..63de2f0f052 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -330,7 +330,7 @@ static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct
return block;
}
-static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context_vk,
+static bool wined3d_context_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
@@ -374,7 +374,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
}
slab->requested_memory_type = memory_type;
- if (!wined3d_context_vk_create_bo(context_vk, key.size, usage, memory_type, &slab->bo))
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, key.size, usage, memory_type, &slab->bo))
{
ERR("Failed to create slab bo.\n");
heap_free(slab);
@@ -424,10 +424,9 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
return true;
}
-BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size,
- VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
+BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
+ VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
- struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
VkMemoryRequirements memory_requirements;
struct wined3d_adapter_vk *adapter_vk;
@@ -435,7 +434,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
unsigned int memory_type_idx;
VkResult vr;
- if (wined3d_context_vk_create_slab_bo(context_vk, size, usage, memory_type, bo))
+ if (wined3d_context_vk_create_slab_bo(device_vk, context_vk, size, usage, memory_type, bo))
return TRUE;
adapter_vk = wined3d_adapter_vk(device_vk->d.adapter);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c5de58c29c9..cdea0ec42cf 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -655,7 +655,7 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk
usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
memory_type = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
- if (!wined3d_context_vk_create_bo(context_vk, 16, usage, memory_type, &r->bo))
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, 16, usage, memory_type, &r->bo))
return false;
VK_CALL(vkCmdFillBuffer(vk_command_buffer, r->bo.vk_buffer, r->bo.buffer_offset, r->bo.size, 0x00000000u));
r->buffer_info.buffer = r->bo.vk_buffer;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index df42f2d766b..02a5d96346f 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -4647,6 +4647,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
unsigned int dst_x, unsigned int dst_y, unsigned int dst_z)
{
struct wined3d_texture_vk *dst_texture_vk = wined3d_texture_vk(dst_texture);
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context->device);
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
unsigned int dst_level, dst_row_pitch, dst_slice_pitch;
struct wined3d_texture_sub_resource *sub_resource;
@@ -4722,7 +4723,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
if (!(src_bo = (struct wined3d_bo_vk *)src_bo_addr->buffer_object))
{
- if (!wined3d_context_vk_create_bo(context_vk, sub_resource->size,
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, sub_resource->size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo))
{
ERR("Failed to create staging bo.\n");
@@ -4833,6 +4834,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
unsigned int dst_row_pitch, unsigned int dst_slice_pitch)
{
struct wined3d_texture_vk *src_texture_vk = wined3d_texture_vk(src_texture);
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context->device);
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
unsigned int src_level, src_width, src_height, src_depth;
struct wined3d_texture_sub_resource *sub_resource;
@@ -4919,7 +4921,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
if (!(dst_bo = (struct wined3d_bo_vk *)dst_bo_addr->buffer_object))
{
- if (!wined3d_context_vk_create_bo(context_vk, sub_resource->size,
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, sub_resource->size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo))
{
ERR("Failed to create staging bo.\n");
@@ -5191,6 +5193,7 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
static BOOL wined3d_texture_vk_prepare_buffer_object(struct wined3d_texture_vk *texture_vk,
unsigned int sub_resource_idx, struct wined3d_context_vk *context_vk)
{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_bo_vk *bo;
@@ -5199,7 +5202,7 @@ static BOOL wined3d_texture_vk_prepare_buffer_object(struct wined3d_texture_vk *
if (bo->vk_buffer)
return TRUE;
- if (!wined3d_context_vk_create_bo(context_vk, sub_resource->size,
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, sub_resource->size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo))
return FALSE;
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 374e693b17d..6a88286b861 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -2078,8 +2078,8 @@ void wined3d_unordered_access_view_vk_clear(struct wined3d_unordered_access_view
vk_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
vk_writes[1].pBufferInfo = &buffer_info;
- if (!wined3d_context_vk_create_bo(context_vk, sizeof(constants), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &constants_bo))
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, sizeof(constants),
+ VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &constants_bo))
{
ERR("Failed to create constants BO.\n");
goto out;
@@ -2213,7 +2213,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
- if (!wined3d_context_vk_create_bo(context_vk, sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT
+ if (!wined3d_device_vk_create_bo(device_vk, context_vk, sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &uav_vk->counter_bo))
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aa8974366a6..b2525110adc 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2642,8 +2642,6 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *context_vk,
const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk, bool indexed) DECLSPEC_HIDDEN;
void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
-BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size,
- VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkImageType vk_image_type,
VkImageUsageFlags usage, VkFormat vk_format, unsigned int width, unsigned int height, unsigned int depth,
unsigned int sample_count, unsigned int mip_levels, unsigned int layer_count, unsigned int flags,
@@ -4094,6 +4092,9 @@ static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device
return CONTAINING_RECORD(device, struct wined3d_device_vk, d);
}
+BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
+ VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type,
+ struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk,
--
2.33.0
Nov. 2, 2021