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 2020
- 73 participants
- 1459 messages
[PATCH] ntdll/tests: Don't check the load address in the WoW64 case.
by Francois Gouget
It could sometimes be NULL, such as win32k.sys on Win <= 7.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
Something like this then?
dlls/ntdll/tests/info.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 5db7a800cbe..4379d8a84c6 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -490,7 +490,7 @@ static void test_query_module(void)
const SYSTEM_MODULE *module = &info->Modules[i];
ok(module->LoadOrderIndex == i, "%u: got index %u\n", i, module->LoadOrderIndex);
- ok(!!module->ImageBaseAddress, "%u: got NULL address\n", i);
+ ok(module->ImageBaseAddress || is_wow64, "%u: got NULL address for %s\n", i, module->Name);
ok(module->ImageSize, "%u: got 0 size\n", i);
ok(module->LoadCount, "%u: got 0 load count\n", i);
}
@@ -516,7 +516,7 @@ static void test_query_module(void)
const SYSTEM_MODULE *module = &infoex->BaseInfo;
ok(module->LoadOrderIndex == i, "%u: got index %u\n", i, module->LoadOrderIndex);
- ok(!!module->ImageBaseAddress, "%u: got NULL address\n", i);
+ ok(module->ImageBaseAddress || is_wow64, "%u: got NULL address for %s\n", i, module->Name);
ok(module->ImageSize, "%u: got 0 size\n", i);
ok(module->LoadCount, "%u: got 0 load count\n", i);
--
2.20.1
Nov. 30, 2020
Re: [PATCH 2/4] evr/tests: Avoid Vista crashes when testing the IMFVideoSampleAllocator interface.
by Francois Gouget
On Thu, 26 Nov 2020, Marvin wrote:
[...]
> === wvistau64 (32 bit report) ===
> === wvistau64 (64 bit report) ===
>
> evr:
> evr.c:1890: Test failed: Unexpected ratio 0 x 0.
> evr.c:1903: Test failed: Unexpected ratio 0 x 0.
> evr.c:1912: Test failed: Unexpected size 640 x 480.
> evr.c:1913: Test failed: Unexpected ratio 0 x 0.
> evr.c:2053: Test failed: Unexpected hr 0x80004002.
These are fixed after the crashes, in patch 4/4.
--
Francois Gouget <fgouget(a)codeweavers.com>
Nov. 30, 2020
Re: RFC ntoskrnl.exe:ntoskrnl crashes 32-bit Vista
by Francois Gouget
On Mon, 30 Nov 2020, Paul Gofman wrote:
> Yeah, it can happen the driver is missing something on Vista. I didn't
> have any Vista machine for running those tests at the moment of making
> them and also that time the testbot could not load any drivers on Vista.
Yes. I've been working on the TestBot VMs lately and I have just
put the Vista ones back online.
> The question is, do we care about the test (especially such specific
> ones as kernel drivers) succeeding on Vista?
I can't say. That's for the global Wine community and ultimately
Alexandre to decide.
--
Francois Gouget <fgouget(a)codeweavers.com>
Nov. 30, 2020
[PATCH] advapi32/tests: Don't check the display name if not in an English locale.
by Francois Gouget
Service display names are often translated.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
For instance:
service.c:2718: Test failed: got Windows-Ereignisprotokoll
service.c:2718: Test failed: got Journal d’événements Windows
dlls/advapi32/tests/service.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c
index d216e096207..cbe7fffbc7a 100644
--- a/dlls/advapi32/tests/service.c
+++ b/dlls/advapi32/tests/service.c
@@ -2678,6 +2678,26 @@ static void test_refcount(void)
CloseServiceHandle(scm_handle);
}
+static BOOL is_lang_english(void)
+{
+ static HMODULE hkernel32 = NULL;
+ static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
+ static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
+
+ if (!hkernel32)
+ {
+ hkernel32 = GetModuleHandleA("kernel32.dll");
+ pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
+ pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
+ }
+ if (pGetThreadUILanguage)
+ return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
+ if (pGetUserDefaultUILanguage)
+ return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
+
+ return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
+}
+
static void test_EventLog(void)
{
SC_HANDLE scm_handle, svc_handle;
@@ -2715,7 +2735,8 @@ todo_wine
ok(!strcmp(config->lpServiceStartName, "LocalSystem") /* XP */ ||
!strcmp(config->lpServiceStartName, "NT AUTHORITY\\LocalService"),
"got %s\n", config->lpServiceStartName);
- ok(!strcmp(config->lpDisplayName, "Event Log") /* XP */ ||
+ ok(!is_lang_english() || /* DisplayName is often translated */
+ !strcmp(config->lpDisplayName, "Event Log") /* XP */ ||
!strcmp(config->lpDisplayName, "Windows Event Log") /* Vista+ */, "got %s\n", config->lpDisplayName);
HeapFree(GetProcessHeap(), 0, config);
--
2.20.1
Nov. 30, 2020
Re: RFC ntoskrnl.exe:ntoskrnl crashes 32-bit Vista
by Paul Gofman
Yeah, it can happen the driver is missing something on Vista. I didn't
have any Vista machine for running those tests at the moment of making
them and also that time the testbot could not load any drivers on Vista.
The question is, do we care about the test (especially such specific
ones as kernel drivers) succeeding on Vista? As I understand, we are
close to dropping Vista compatibility in tests entirely, and fixing the
test driver for Vista might take a bit of effort. IMO it would be more
interesting to have drivers test working on newer Windows machines.
On 11/30/20 17:48, Francois Gouget wrote:
> ntoskrnl.exe:ntoskrnl causes the wvista VM to crash. More specifically
> it happens in test_driver4() on this line:
>
> device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
>
> which presumably is what triggers loading our driver so that makes
> sense (the patch below can be used to confirm this). The BSOD says:
>
> *** STOP: 0x0000008E (0xC000005,0x956E4AA0,0x922E0AAC,0x00000000)
> *** dri19512.tmp - Address 956E4AA0 bqse at 956E3000, DateStamp 5fc03305
>
> So likely a NULL pointer dereference. Could this be because of a bug in
> our test driver?
>
> For now I've set the TestBot so wvista runs WineTest wihout elevated
> privileges which causes it to skip this test: that's the wvistaadm
> variant.
>
> The other datapoint is that the wvistau64 VM does not crash when running
> the 64-bit test but I don't know if that's because of the bitness or
> some other subtle Windows version difference.
>
> wvista crash (truncated report, network connection loss, screenshot):
> https://testbot.winehq.org/JobDetails.pl?Key=82678#k101
>
> wvistau64 not crashing:
> https://testbot.winehq.org/JobDetails.pl?Key=82680#k101
>
>
>
> diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
> index c2285aef6fc..00b845dcb0e 100644
> --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
> +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
> @@ -702,6 +702,7 @@ static void test_driver4(void)
> DeleteFileA(filename);
> return;
> }
> + exit(0);
>
> device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
> ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
>
>
Nov. 30, 2020
RFC mfplat:mfplat crash on Windows 7
by Francois Gouget
So mfplat:mfplat crashes on Windows 7 (all available VMs):
https://test.winehq.org/data/tests/mfplat:mfplat.html
The culprit is this line:
615 get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
which calls
429 hr = IMFMediaEventGenerator_GetEvent(mediasource, 0, &event);
which crashes.
I applied the patch below to confirm the location of the crash and also
to confirm that the mediasource object does support the
IID_IMFMediaEventGenerator interface which it does.
https://testbot.winehq.org/JobDetails.pl?Key=82748
So that crash is pretty strange. The only theory I have is that this API
was new in Windows 7 and that it was still somewhat buggy. This theory
is based on the test.winehq.org website which says 'n/a' for
mfplat:mfplat which should mean the dll is 'missing'. That's confirmed
for Windows 2008 and also mostly for Vista since it is missing
MFCreateVideoMediaType() which prevents mfplat_test.exe from running. In
Windows 8 and 10 the test works... mostly (Windows 10 has timeouts).
Is the test doing something wron to cause this crah? Should we skip this
test on Windows 7? Should that be based on the Windows version or some
other characteristic?
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 474d6281f5f..6899f41b230 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -426,8 +426,10 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected
HRESULT hr, event_status;
IMFMediaEvent *event;
+ trace("generator=%p\n", generator);
hr = IMFMediaEventGenerator_GetEvent(generator, 0, &event);
ok(hr == S_OK, "Failed to get event, hr %#x.\n", hr);
+ trace("event=%p\n", event); /* (not reached on win7) */
hr = IMFMediaEvent_GetStatus(event, &event_status);
ok(hr == S_OK, "Failed to get status code, hr %#x.\n", hr);
@@ -477,6 +479,7 @@ static void test_source_resolver(void)
PROPVARIANT var;
HRESULT hr;
GUID guid;
+ IUnknown *unk;
if (!pMFCreateSourceResolver)
{
@@ -612,15 +615,25 @@ todo_wine
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
+ hr = IUnknown_QueryInterface(mediasource, &IID_IMFMediaEventGenerator, (void **)&unk);
+ trace("QueryInterface(IID_IMFMediaEventGenerator): hr = %#x\n", hr);
+ ok(hr == S_OK, "Got hr %#x\n", hr);
+
+ trace("\n");
get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
+ trace("\n"); /* not reached on win7 */
ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt);
video_stream = (IMFMediaStream *)var.punkVal;
- get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL);
+ get_event((IMFMediaEventGenerator *)unk, MESourceStarted, NULL);
/* Request samples, our file is 10 frames at 25fps */
get_event((IMFMediaEventGenerator *)video_stream, MEStreamStarted, NULL);
sample_count = 10;
+ trace("\n");
+
+ if (SUCCEEDED(hr))
+ IUnknown_Release(unk);
for (i = 0; i < sample_count; ++i)
{
--
2.20.1
Nov. 30, 2020
RFC ntoskrnl.exe:ntoskrnl crashes 32-bit Vista
by Francois Gouget
ntoskrnl.exe:ntoskrnl causes the wvista VM to crash. More specifically
it happens in test_driver4() on this line:
device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
which presumably is what triggers loading our driver so that makes
sense (the patch below can be used to confirm this). The BSOD says:
*** STOP: 0x0000008E (0xC000005,0x956E4AA0,0x922E0AAC,0x00000000)
*** dri19512.tmp - Address 956E4AA0 bqse at 956E3000, DateStamp 5fc03305
So likely a NULL pointer dereference. Could this be because of a bug in
our test driver?
For now I've set the TestBot so wvista runs WineTest wihout elevated
privileges which causes it to skip this test: that's the wvistaadm
variant.
The other datapoint is that the wvistau64 VM does not crash when running
the 64-bit test but I don't know if that's because of the bitness or
some other subtle Windows version difference.
wvista crash (truncated report, network connection loss, screenshot):
https://testbot.winehq.org/JobDetails.pl?Key=82678#k101
wvistau64 not crashing:
https://testbot.winehq.org/JobDetails.pl?Key=82680#k101
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index c2285aef6fc..00b845dcb0e 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -702,6 +702,7 @@ static void test_driver4(void)
DeleteFileA(filename);
return;
}
+ exit(0);
device = CreateFileA("\\\\.\\WineTestDriver4", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
ok(device != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
--
Francois Gouget <fgouget(a)codeweavers.com>
Nov. 30, 2020
[PATCH 5/5] wined3d: Use command buffer IDs for synchronisation in wined3d_buffer_gl_sync_apple().
by Henri Verbeet
Analogous to the Vulkan adapter. This is slightly awkward in OpenGL
because it doesn't have explicit command buffers like Vulkan, but
calling wined3d_context_gl_submit_command_fence() on swapchain present
works well enough in practice. The main advantage of this approach is that it
avoids using a separate fence for each usage of each bo.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 2 +
dlls/wined3d/buffer.c | 61 ++--------------
dlls/wined3d/context.c | 4 -
dlls/wined3d/context_gl.c | 130 +++++++++++++++++++++++++++------
dlls/wined3d/query.c | 2 +-
dlls/wined3d/swapchain.c | 1 +
dlls/wined3d/wined3d_private.h | 34 +++++++--
7 files changed, 146 insertions(+), 88 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index cb382cd6734..4781622d530 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4256,6 +4256,8 @@ static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wi
if (!(device_gl = heap_alloc_zero(sizeof(*device_gl))))
return E_OUTOFMEMORY;
+ device_gl->current_fence_id = 1;
+
if (FAILED(hr = wined3d_device_init(&device_gl->d, wined3d, adapter->ordinal, device_type, focus_window,
flags, surface_alignment, levels, level_count, adapter->gl_info.supported, device_parent)))
{
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 61e35dc1e45..82051453ef1 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -187,11 +187,6 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
buffer_gl->b.buffer_object = 0;
- if (buffer_gl->b.fence)
- {
- wined3d_fence_destroy(buffer_gl->b.fence);
- buffer_gl->b.fence = NULL;
- }
buffer_gl->b.flags &= ~WINED3D_BUFFER_APPLESYNC;
}
@@ -746,9 +741,9 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
uint32_t flags, struct wined3d_context_gl *context_gl)
{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(buffer_gl->b.resource.device);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
- enum wined3d_fence_result ret;
- HRESULT hr;
+ struct wined3d_bo_gl *bo = &buffer_gl->bo;
/* No fencing needs to be done if the app promises not to overwrite
* existing data. */
@@ -759,59 +754,17 @@ static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
{
wined3d_buffer_gl_bind(buffer_gl, context_gl);
- GL_EXTCALL(glBufferData(buffer_gl->bo.binding, buffer_gl->b.resource.size, NULL, buffer_gl->bo.usage));
+ GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage));
checkGLcall("glBufferData");
- return;
- }
-
- if (!buffer_gl->b.fence)
- {
- TRACE("Creating fence for buffer %p.\n", buffer_gl);
-
- if (FAILED(hr = wined3d_fence_create(buffer_gl->b.resource.device, &buffer_gl->b.fence)))
- {
- if (hr == WINED3DERR_NOTAVAILABLE)
- FIXME("Fences not supported, dropping async buffer locks.\n");
- else
- ERR("Failed to create fence, hr %#x.\n", hr);
- goto drop_fence;
- }
-
- /* Since we don't know about old draws a glFinish is needed once */
- gl_info->gl_ops.gl.p_glFinish();
+ bo->command_fence_id = 0;
return;
}
TRACE("Synchronizing buffer %p.\n", buffer_gl);
- ret = wined3d_fence_wait(buffer_gl->b.fence, buffer_gl->b.resource.device);
- switch (ret)
- {
- case WINED3D_FENCE_NOT_STARTED:
- case WINED3D_FENCE_OK:
- /* All done */
- return;
-
- case WINED3D_FENCE_WRONG_THREAD:
- WARN("Cannot synchronize buffer lock due to a thread conflict.\n");
- goto drop_fence;
-
- default:
- ERR("wined3d_fence_wait() returned %u, dropping async buffer locks.\n", ret);
- goto drop_fence;
- }
-drop_fence:
- if (buffer_gl->b.fence)
- {
- wined3d_fence_destroy(buffer_gl->b.fence);
- buffer_gl->b.fence = NULL;
- }
-
- gl_info->gl_ops.gl.p_glFinish();
- wined3d_buffer_gl_bind(buffer_gl, context_gl);
- GL_EXTCALL(glBufferParameteriAPPLE(buffer_gl->bo.binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
- checkGLcall("glBufferParameteriAPPLE(buffer_gl->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
- buffer_gl->b.flags &= ~WINED3D_BUFFER_APPLESYNC;
+ if (bo->command_fence_id == device_gl->current_fence_id)
+ wined3d_context_gl_submit_command_fence(context_gl);
+ wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id);
}
static void buffer_mark_used(struct wined3d_buffer *buffer)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index ee2659ce23a..b52df0bd11e 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -271,7 +271,6 @@ void context_update_stream_info(struct wined3d_context *context, const struct wi
wined3d_stream_info_from_declaration(stream_info, state, d3d_info);
stream_info->all_vbo = 1;
- context->buffer_fence_count = 0;
for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i)
{
struct wined3d_stream_info_element *element;
@@ -312,9 +311,6 @@ void context_update_stream_info(struct wined3d_context *context, const struct wi
if (!element->data.buffer_object)
stream_info->all_vbo = 0;
- if (buffer->fence)
- context->buffer_fences[context->buffer_fence_count++] = buffer->fence;
-
TRACE("Load array %u %s.\n", i, debug_bo_address(&element->data));
}
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 12e5e088713..ee1adfcf559 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -1374,6 +1374,10 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
if (context_gl->valid)
{
+ wined3d_context_gl_submit_command_fence(context_gl);
+ wined3d_context_gl_wait_command_fence(context_gl,
+ wined3d_device_gl(context_gl->c.device)->current_fence_id - 1);
+
if (context_gl->dummy_arbfp_prog)
GL_EXTCALL(glDeleteProgramsARB(1, &context_gl->dummy_arbfp_prog));
@@ -1422,6 +1426,7 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
checkGLcall("context cleanup");
}
+ heap_free(context_gl->submitted.fences);
heap_free(context_gl->free_pipeline_statistics_queries);
heap_free(context_gl->free_so_statistics_queries);
heap_free(context_gl->free_timestamp_queries);
@@ -2571,6 +2576,80 @@ void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl, GLen
checkGLcall("bind texture");
}
+static void wined3d_context_gl_poll_fences(struct wined3d_context_gl *context_gl)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ struct wined3d_command_fence_gl *f;
+ SIZE_T i;
+
+ for (i = 0; i < context_gl->submitted.fence_count; ++i)
+ {
+ f = &context_gl->submitted.fences[i];
+
+ if (f->id > device_gl->completed_fence_id)
+ {
+ if (wined3d_fence_test(f->fence, &device_gl->d, 0) != WINED3D_FENCE_OK)
+ continue;
+ device_gl->completed_fence_id = f->id;
+ }
+
+ wined3d_fence_destroy(f->fence);
+ if (i != context_gl->submitted.fence_count - 1)
+ *f = context_gl->submitted.fences[context_gl->submitted.fence_count - 1];
+ --context_gl->submitted.fence_count;
+ }
+}
+
+void wined3d_context_gl_wait_command_fence(struct wined3d_context_gl *context_gl, uint64_t id)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ enum wined3d_fence_result ret;
+ SIZE_T i;
+
+ if (id <= device_gl->completed_fence_id
+ || id > device_gl->current_fence_id) /* In case the fence ID wrapped. */
+ return;
+
+ for (i = 0; i < context_gl->submitted.fence_count; ++i)
+ {
+ if (context_gl->submitted.fences[i].id != id)
+ continue;
+
+ if ((ret = wined3d_fence_wait(context_gl->submitted.fences[i].fence, &device_gl->d)) != WINED3D_FENCE_OK)
+ ERR("Failed to wait for command fence with id 0x%s, ret %#x.\n", wine_dbgstr_longlong(id), ret);
+ wined3d_context_gl_poll_fences(context_gl);
+ return;
+ }
+
+ ERR("Failed to find fence for command fence with id 0x%s.\n", wine_dbgstr_longlong(id));
+}
+
+void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_gl)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+ struct wined3d_command_fence_gl *f;
+ HRESULT hr;
+
+ if (!wined3d_array_reserve((void **)&context_gl->submitted.fences, &context_gl->submitted.fences_size,
+ context_gl->submitted.fence_count + 1, sizeof(*context_gl->submitted.fences)))
+ ERR("Failed to grow submitted command buffer array.\n");
+
+ f = &context_gl->submitted.fences[context_gl->submitted.fence_count++];
+ f->id = device_gl->current_fence_id;
+ if (FAILED(hr = wined3d_fence_create(&device_gl->d, &f->fence)))
+ ERR("Failed to create fence, hr %#x.\n", hr);
+ wined3d_fence_issue(f->fence, &device_gl->d);
+
+ /* We don't expect this to ever happen, but handle it anyway. */
+ if (!++device_gl->current_fence_id)
+ {
+ wined3d_context_gl_wait_command_fence(context_gl, device_gl->current_fence_id - 1);
+ device_gl->completed_fence_id = 0;
+ device_gl->current_fence_id = 1;
+ }
+ wined3d_context_gl_poll_fences(context_gl);
+}
+
void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *data, size_t size, uint32_t flags)
{
@@ -2728,6 +2807,8 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
bo->id = id;
bo->binding = binding;
bo->usage = usage;
+ bo->command_fence_id = 0;
+
return true;
}
@@ -3605,7 +3686,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
const struct wined3d_fb_state *fb = &state->fb;
unsigned int i, base;
- WORD map;
+ uint32_t map;
context->uses_fbo_attached_resources = 0;
@@ -3638,24 +3719,36 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
{
context_update_stream_info(context, state);
}
- else
+
+ map = context->stream_info.use_map;
+ while (map)
{
- for (i = 0, map = context->stream_info.use_map; map; map >>= 1, ++i)
- {
- if (map & 1)
- wined3d_buffer_load(state->streams[context->stream_info.elements[i].stream_idx].buffer,
- context, state);
- }
- /* Loading the buffers above may have invalidated the stream info. */
- if (isStateDirty(context, STATE_STREAMSRC))
- context_update_stream_info(context, state);
+ const struct wined3d_stream_info_element *e;
+ struct wined3d_buffer_gl *buffer_gl;
+
+ e = &context->stream_info.elements[wined3d_bit_scan(&map)];
+ buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer);
+
+ wined3d_buffer_load(&buffer_gl->b, context, state);
+ wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
+ /* Loading the buffers above may have invalidated the stream info. */
+ if (wined3d_context_is_graphics_state_dirty(context, STATE_STREAMSRC))
+ context_update_stream_info(context, state);
+
if (indexed && state->index_buffer)
{
+ struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(state->index_buffer);
+
if (context->stream_info.all_vbo)
- wined3d_buffer_load(state->index_buffer, context, state);
+ {
+ wined3d_buffer_load(&buffer_gl->b, context, state);
+ wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ }
else
- wined3d_buffer_load_sysmem(state->index_buffer, context);
+ {
+ wined3d_buffer_load_sysmem(&buffer_gl->b, context);
+ }
}
for (i = 0, base = 0; i < ARRAY_SIZE(context->dirty_graphics_states); ++i)
@@ -4475,7 +4568,6 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
const struct wined3d_stream_info *stream_info;
struct wined3d_rendertarget_view *dsv, *rtv;
struct wined3d_stream_info si_emulated;
- struct wined3d_fence *ib_fence = NULL;
const struct wined3d_gl_info *gl_info;
struct wined3d_context_gl *context_gl;
struct wined3d_context *context;
@@ -4573,14 +4665,9 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
{
struct wined3d_buffer *index_buffer = state->index_buffer;
if (!index_buffer->buffer_object || !stream_info->all_vbo)
- {
idx_data = index_buffer->resource.heap_memory;
- }
else
- {
- ib_fence = index_buffer->fence;
idx_data = NULL;
- }
idx_data = (const BYTE *)idx_data + state->index_offset;
if (state->index_format == WINED3DFMT_R16_UINT)
@@ -4719,11 +4806,6 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
checkGLcall("disable rasterizer discard");
}
- if (ib_fence)
- wined3d_fence_issue(ib_fence, device);
- for (i = 0; i < context->buffer_fence_count; ++i)
- wined3d_fence_issue(context->buffer_fences[i], device);
-
context_release(context);
TRACE("Draw completed.\n");
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 5aca4a2c5a4..9e0e22b32e5 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -180,7 +180,7 @@ static BOOL wined3d_fence_supported(const struct wined3d_gl_info *gl_info)
return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE];
}
-static enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence,
+enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence,
struct wined3d_device *device, DWORD flags)
{
const struct wined3d_gl_info *gl_info;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 7e46e5c6150..ffffc18aa84 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -559,6 +559,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
/* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
gl_info->gl_ops.wgl.p_wglSwapBuffers(context_gl->dc);
+ wined3d_context_gl_submit_command_fence(context_gl);
wined3d_swapchain_gl_rotate(swapchain, context);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3dcd3e26846..a7baff857d0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1540,6 +1540,8 @@ struct wined3d_bo_gl
GLuint id;
GLenum binding;
GLenum usage;
+
+ uint64_t command_fence_id;
};
static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
@@ -1842,6 +1844,8 @@ void wined3d_fence_destroy(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
void wined3d_fence_issue(struct wined3d_fence *fence, struct wined3d_device *device) DECLSPEC_HIDDEN;
enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence,
struct wined3d_device *device) DECLSPEC_HIDDEN;
+enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence,
+ struct wined3d_device *device, DWORD flags) DECLSPEC_HIDDEN;
/* Direct3D terminology with little modifications. We do not have an issued
* state because only the driver knows about it, but we have a created state
@@ -2105,10 +2109,6 @@ struct wined3d_context
struct wined3d_stream_info stream_info;
- /* Fences for GL_APPLE_flush_buffer_range */
- struct wined3d_fence *buffer_fences[MAX_ATTRIBS];
- unsigned int buffer_fence_count;
-
unsigned int viewport_count;
unsigned int scissor_rect_count;
};
@@ -2127,6 +2127,12 @@ void context_update_stream_info(struct wined3d_context *context, const struct wi
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+struct wined3d_command_fence_gl
+{
+ uint64_t id;
+ struct wined3d_fence *fence;
+};
+
struct wined3d_context_gl
{
struct wined3d_context c;
@@ -2214,6 +2220,13 @@ struct wined3d_context_gl
GLfloat colour[4], fog_start, fog_end, fog_colour[4];
GLuint dummy_arbfp_prog;
+
+ struct
+ {
+ struct wined3d_command_fence_gl *fences;
+ SIZE_T fences_size;
+ SIZE_T fence_count;
+ } submitted;
};
static inline struct wined3d_context_gl *wined3d_context_gl(struct wined3d_context *context)
@@ -2287,6 +2300,7 @@ struct wined3d_context_gl *wined3d_context_gl_reacquire(struct wined3d_context_g
void wined3d_context_gl_release(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
BOOL wined3d_context_gl_set_current(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
void wined3d_context_gl_set_draw_buffer(struct wined3d_context_gl *context_gl, GLenum buffer) DECLSPEC_HIDDEN;
+void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
void wined3d_context_gl_texture_update(struct wined3d_context_gl *context_gl,
const struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN;
void wined3d_context_gl_unload_tex_coords(const struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
@@ -2294,6 +2308,7 @@ void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl,
unsigned int range_count, const struct wined3d_range *ranges) DECLSPEC_HIDDEN;
void wined3d_context_gl_update_stream_sources(struct wined3d_context_gl *context_gl,
const struct wined3d_state *state) DECLSPEC_HIDDEN;
+void wined3d_context_gl_wait_command_fence(struct wined3d_context_gl *context_gl, uint64_t id) DECLSPEC_HIDDEN;
struct wined3d_command_buffer_vk
{
@@ -3803,6 +3818,9 @@ struct wined3d_device_gl
/* Textures for when no other textures are bound. */
struct wined3d_dummy_textures dummy_textures;
+
+ uint64_t completed_fence_id;
+ uint64_t current_fence_id;
};
static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device)
@@ -4789,7 +4807,6 @@ struct wined3d_buffer
struct wined3d_range *maps;
SIZE_T maps_size, modified_areas;
- struct wined3d_fence *fence;
/* conversion stuff */
UINT decl_change_count, full_conversion_count;
@@ -6298,6 +6315,13 @@ static inline bool wined3d_primitive_type_is_list(enum wined3d_primitive_type t)
|| t == WINED3D_PT_PATCH;
}
+static inline void wined3d_context_gl_reference_bo(struct wined3d_context_gl *context_gl, struct wined3d_bo_gl *bo_gl)
+{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
+
+ bo_gl->command_fence_id = device_gl->current_fence_id;
+}
+
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
--
2.20.1
Nov. 30, 2020
[PATCH 4/5] wined3d: Use GL_ARB_buffer_storage if available.
by Henri Verbeet
From: Matteo Bruni <mbruni(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 4 +++-
dlls/wined3d/context_gl.c | 11 +++++++----
dlls/wined3d/resource.c | 15 +++++++++++++++
dlls/wined3d/texture.c | 4 ++--
dlls/wined3d/view.c | 4 ++--
dlls/wined3d/wined3d_private.h | 5 +++--
6 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 285ae7231ec..61e35dc1e45 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -201,6 +201,7 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
GLenum usage = GL_STATIC_DRAW;
+ GLbitfield gl_storage_flags;
struct wined3d_bo_gl *bo;
bool coherent = true;
GLsizeiptr size;
@@ -216,8 +217,9 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
usage = GL_STREAM_DRAW_ARB;
coherent = false;
}
+ gl_storage_flags = wined3d_resource_gl_storage_flags(&buffer_gl->b.resource);
bo = &buffer_gl->bo;
- if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, bo))
+ if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, gl_storage_flags, bo))
{
ERR("Failed to create OpenGL buffer object.\n");
buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO;
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 567d6ba56b7..12e5e088713 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2694,13 +2694,13 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
}
bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
- GLenum binding, GLenum usage, bool coherent, struct wined3d_bo_gl *bo)
+ GLenum binding, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
GLuint id = 0;
- TRACE("context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, bo %p.\n",
- context_gl, size, binding, usage, coherent, bo);
+ TRACE("context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, flags %#x, bo %p.\n",
+ context_gl, size, binding, usage, coherent, flags, bo);
GL_EXTCALL(glGenBuffers(1, &id));
if (!id)
@@ -2716,7 +2716,10 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
}
- GL_EXTCALL(glBufferData(binding, size, NULL, usage));
+ if (gl_info->supported[ARB_BUFFER_STORAGE])
+ GL_EXTCALL(glBufferStorage(binding, size, NULL, flags | GL_DYNAMIC_STORAGE_BIT));
+ else
+ GL_EXTCALL(glBufferData(binding, size, NULL, usage));
wined3d_context_gl_bind_bo(context_gl, binding, 0);
checkGLcall("buffer object creation");
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index c8d5fecf9d9..97b8b68374d 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -428,6 +428,21 @@ void wined3d_resource_free_sysmem(struct wined3d_resource *resource)
resource->heap_memory = NULL;
}
+GLbitfield wined3d_resource_gl_storage_flags(const struct wined3d_resource *resource)
+{
+ uint32_t access = resource->access;
+ GLbitfield flags = 0;
+
+ if (resource->usage & WINED3DUSAGE_DYNAMIC)
+ flags |= GL_CLIENT_STORAGE_BIT;
+ if (access & WINED3D_RESOURCE_ACCESS_MAP_W)
+ flags |= GL_MAP_WRITE_BIT;
+ if (access & WINED3D_RESOURCE_ACCESS_MAP_R)
+ flags |= GL_MAP_READ_BIT;
+
+ return flags;
+}
+
GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
{
GLbitfield ret = 0;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index b311df0f896..b84b68c592b 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1924,8 +1924,8 @@ static void wined3d_texture_gl_prepare_buffer_object(struct wined3d_texture_gl *
if (bo->id)
return;
- if (!wined3d_context_gl_create_bo(context_gl, sub_resource->size,
- GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW, true, bo))
+ if (!wined3d_context_gl_create_bo(context_gl, sub_resource->size, GL_PIXEL_UNPACK_BUFFER,
+ GL_STREAM_DRAW, true, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo))
return;
TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture_gl, sub_resource_idx);
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 1d77b0e44fb..4c85e2fefe4 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -1415,8 +1415,8 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
struct wined3d_bo_gl *bo = &view_gl->counter_bo;
view_gl->v.counter_bo = (uintptr_t)bo;
- wined3d_context_gl_create_bo(context_gl, sizeof(uint32_t),
- GL_ATOMIC_COUNTER_BUFFER, GL_STATIC_DRAW, true, bo);
+ wined3d_context_gl_create_bo(context_gl, sizeof(uint32_t), GL_ATOMIC_COUNTER_BUFFER,
+ GL_STATIC_DRAW, true, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_CLIENT_STORAGE_BIT, bo);
wined3d_unordered_access_view_set_counter(&view_gl->v, 0);
}
context_release(&context_gl->c);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9b12295ec52..3dcd3e26846 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2256,8 +2256,8 @@ void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl,
void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *context_gl, GLenum target) DECLSPEC_HIDDEN;
void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size) DECLSPEC_HIDDEN;
-bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
- GLenum binding, GLenum usage, bool coherent, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN;
+bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size, GLenum binding,
+ GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN;
void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN;
void wined3d_context_gl_draw_shaded_quad(struct wined3d_context_gl *context_gl, struct wined3d_texture_gl *texture_gl,
@@ -4049,6 +4049,7 @@ const struct wined3d_format *wined3d_resource_get_decompress_format(
unsigned int wined3d_resource_get_sample_count(const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
+GLbitfield wined3d_resource_gl_storage_flags(const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
--
2.20.1
Nov. 30, 2020
[PATCH 3/5] wined3d: Introduce wined3d_context_gl_create_bo().
by Henri Verbeet
From: Matteo Bruni <mbruni(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 77 ++++++++--------------------------
dlls/wined3d/context_gl.c | 35 ++++++++++++++++
dlls/wined3d/texture.c | 20 ++++-----
dlls/wined3d/view.c | 22 ++++------
dlls/wined3d/wined3d_private.h | 2 +
5 files changed, 72 insertions(+), 84 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 0caf933724a..285ae7231ec 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -200,79 +200,38 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
struct wined3d_context_gl *context_gl)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+ GLenum usage = GL_STATIC_DRAW;
struct wined3d_bo_gl *bo;
- GLenum error;
+ bool coherent = true;
+ GLsizeiptr size;
+ GLenum binding;
TRACE("Creating an OpenGL buffer object for wined3d buffer %p with usage %s.\n",
buffer_gl, debug_d3dusage(buffer_gl->b.resource.usage));
- /* Make sure that the gl error is cleared. Do not use checkGLcall
- * here because checkGLcall just prints a fixme and continues. However,
- * if an error during VBO creation occurs we can fall back to non-VBO operation
- * with full functionality(but performance loss).
- */
- while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR);
-
- /* Basically the FVF parameter passed to CreateVertexBuffer is no good.
- * The vertex declaration from the device determines how the data in the
- * buffer is interpreted. This means that on each draw call the buffer has
- * to be verified to check if the rhw and color values are in the correct
- * format. */
-
- bo = &buffer_gl->bo;
- GL_EXTCALL(glGenBuffers(1, &bo->id));
- bo->binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags);
- bo->usage = GL_STATIC_DRAW;
- buffer_gl->b.buffer_object = (uintptr_t)bo;
- error = gl_info->gl_ops.gl.p_glGetError();
- if (!bo->id || error != GL_NO_ERROR)
- {
- ERR("Failed to create a BO with error %s (%#x).\n", debug_glerror(error), error);
- goto fail;
- }
-
- wined3d_buffer_gl_bind(buffer_gl, context_gl);
- error = gl_info->gl_ops.gl.p_glGetError();
- if (error != GL_NO_ERROR)
- {
- ERR("Failed to bind the BO with error %s (%#x).\n", debug_glerror(error), error);
- goto fail;
- }
-
+ size = buffer_gl->b.resource.size;
+ binding = wined3d_buffer_gl_binding_from_bind_flags(gl_info, buffer_gl->b.resource.bind_flags);
if (buffer_gl->b.resource.usage & WINED3DUSAGE_DYNAMIC)
{
- TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n");
- bo->usage = GL_STREAM_DRAW_ARB;
-
- if (gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
- {
- GL_EXTCALL(glBufferParameteriAPPLE(bo->binding, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
- GL_EXTCALL(glBufferParameteriAPPLE(bo->binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
- checkGLcall("glBufferParameteriAPPLE");
- buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC;
- }
- /* No setup is needed here for GL_ARB_map_buffer_range. */
+ usage = GL_STREAM_DRAW_ARB;
+ coherent = false;
}
-
- GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage));
- error = gl_info->gl_ops.gl.p_glGetError();
- if (error != GL_NO_ERROR)
+ bo = &buffer_gl->bo;
+ if (!wined3d_context_gl_create_bo(context_gl, size, binding, usage, coherent, bo))
{
- ERR("glBufferData failed with error %s (%#x).\n", debug_glerror(error), error);
- goto fail;
+ ERR("Failed to create OpenGL buffer object.\n");
+ buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO;
+ buffer_clear_dirty_areas(&buffer_gl->b);
+ return FALSE;
}
+ if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
+ buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC;
+
+ buffer_gl->b.buffer_object = (uintptr_t)bo;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
return TRUE;
-
-fail:
- /* Clean up all BO init, but continue because we can work without a BO :-) */
- ERR("Failed to create a buffer object. Continuing, but performance issues may occur.\n");
- buffer_gl->b.flags &= ~WINED3D_BUFFER_USE_BO;
- wined3d_buffer_gl_destroy_buffer_object(buffer_gl, context_gl);
- buffer_clear_dirty_areas(&buffer_gl->b);
- return FALSE;
}
static BOOL buffer_process_converted_attribute(struct wined3d_buffer *buffer,
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 3a5718e6308..567d6ba56b7 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2693,6 +2693,41 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
bo->id = 0;
}
+bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
+ GLenum binding, GLenum usage, bool coherent, struct wined3d_bo_gl *bo)
+{
+ const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+ GLuint id = 0;
+
+ TRACE("context_gl %p, size %lu, binding %#x, usage %#x, coherent %#x, bo %p.\n",
+ context_gl, size, binding, usage, coherent, bo);
+
+ GL_EXTCALL(glGenBuffers(1, &id));
+ if (!id)
+ {
+ checkGLcall("buffer object creation");
+ return false;
+ }
+ wined3d_context_gl_bind_bo(context_gl, binding, id);
+
+ if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
+ GL_EXTCALL(glBufferParameteriAPPLE(binding, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
+ }
+
+ GL_EXTCALL(glBufferData(binding, size, NULL, usage));
+
+ wined3d_context_gl_bind_bo(context_gl, binding, 0);
+ checkGLcall("buffer object creation");
+
+ TRACE("Created buffer object %u.\n", id);
+ bo->id = id;
+ bo->binding = binding;
+ bo->usage = usage;
+ return true;
+}
+
static void wined3d_context_gl_set_render_offscreen(struct wined3d_context_gl *context_gl, BOOL offscreen)
{
if (context_gl->c.render_offscreen == offscreen)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 73821cc27a9..b311df0f896 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1913,26 +1913,22 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, unsig
}
/* Context activation is done by the caller. */
-static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
- unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
+static void wined3d_texture_gl_prepare_buffer_object(struct wined3d_texture_gl *texture_gl,
+ unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl)
{
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_bo_gl *bo;
- sub_resource = &texture->sub_resources[sub_resource_idx];
+ sub_resource = &texture_gl->t.sub_resources[sub_resource_idx];
bo = &sub_resource->bo;
if (bo->id)
return;
- GL_EXTCALL(glGenBuffers(1, &bo->id));
- bo->binding = GL_PIXEL_UNPACK_BUFFER;
- bo->usage = GL_STREAM_DRAW;
- GL_EXTCALL(glBindBuffer(bo->binding, bo->id));
- GL_EXTCALL(glBufferData(bo->binding, sub_resource->size, NULL, bo->usage));
- GL_EXTCALL(glBindBuffer(bo->binding, 0));
- checkGLcall("Create buffer object");
+ if (!wined3d_context_gl_create_bo(context_gl, sub_resource->size,
+ GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW, true, bo))
+ return;
- TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture, sub_resource_idx);
+ TRACE("Created buffer object %u for texture %p, sub-resource %u.\n", bo->id, texture_gl, sub_resource_idx);
}
static void wined3d_texture_force_reload(struct wined3d_texture *texture)
@@ -3135,7 +3131,7 @@ static BOOL wined3d_texture_gl_prepare_location(struct wined3d_texture *texture,
: wined3d_resource_prepare_sysmem(&texture->resource);
case WINED3D_LOCATION_BUFFER:
- wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context_gl->gl_info);
+ wined3d_texture_gl_prepare_buffer_object(texture_gl, sub_resource_idx, context_gl);
return TRUE;
case WINED3D_LOCATION_TEXTURE_RGB:
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index bf4c9ca5af1..1d77b0e44fb 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -1405,25 +1405,21 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
if (resource->type == WINED3D_RTYPE_BUFFER)
{
struct wined3d_buffer *buffer = buffer_from_resource(resource);
- struct wined3d_context *context;
+ struct wined3d_context_gl *context_gl;
- context = context_acquire(resource->device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_gl->v.format);
+ context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0));
+ gl_info = context_gl->gl_info;
+ create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format);
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
struct wined3d_bo_gl *bo = &view_gl->counter_bo;
- static const GLuint initial_value = 0;
-
- GL_EXTCALL(glGenBuffers(1, &bo->id));
- bo->binding = GL_ATOMIC_COUNTER_BUFFER;
- bo->usage = GL_STATIC_DRAW;
- GL_EXTCALL(glBindBuffer(bo->binding, bo->id));
- GL_EXTCALL(glBufferData(bo->binding, sizeof(initial_value), &initial_value, bo->usage));
- checkGLcall("create atomic counter buffer");
+
view_gl->v.counter_bo = (uintptr_t)bo;
+ wined3d_context_gl_create_bo(context_gl, sizeof(uint32_t),
+ GL_ATOMIC_COUNTER_BUFFER, GL_STATIC_DRAW, true, bo);
+ wined3d_unordered_access_view_set_counter(&view_gl->v, 0);
}
- context_release(context);
+ context_release(&context_gl->c);
}
else
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dbdb10a182a..9b12295ec52 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2256,6 +2256,8 @@ void wined3d_context_gl_bind_texture(struct wined3d_context_gl *context_gl,
void wined3d_context_gl_check_fbo_status(const struct wined3d_context_gl *context_gl, GLenum target) DECLSPEC_HIDDEN;
void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size) DECLSPEC_HIDDEN;
+bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
+ GLenum binding, GLenum usage, bool coherent, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN;
void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN;
void wined3d_context_gl_draw_shaded_quad(struct wined3d_context_gl *context_gl, struct wined3d_texture_gl *texture_gl,
--
2.20.1
Nov. 30, 2020