This commit replaces the SampleGrabberSink with a dedicated Video Sink,
referred to as the Simple Video Renderer (SVR).
This brings it more inline with Windows and provides the benefit of
having direct access to the IMFSample, removing the need to copy the
sample data.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5924
The `viewWillDraw` warning was introduced recently in ceefcca7ad4cf8dee0dd1344b22b90d6e2344973 ("Update OpenGL context immediately after the window content view is visible.").
For the other one, `CGWindowListCreateImageFromArray()` is insane and takes a CFArray of window numbers (`CGWindowID`/32-bit signed integers) expanded to pointer size (*not* boxed in CFNumber). At some point clang started warning about this:
```
../dlls/winemac.drv/cocoa_window.m:2344:32: warning: cast to 'const void *' from smaller integer type 'CGWindowID' (aka 'unsigned int') [-Wint-to-void-pointer-cast]
2344 | const void* windowID = (const void*)(CGWindowID)window.windowNumber;
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5922
Mostly race condition fixes.
"winegstreamer: Do waits for samples on stream-specific work queues." works around a Gstreamer bug that I'll try to write a minimal reproducer for and submit to their bug tracker. For now, doing sample waits actually concurrently works around the problem.
"winegstreamer: Fixate caps in autoplug_continue_cb." so far I've only seen relevant when the source is a uridecodebin (in Proton), but I though it couldn't hurt to upstream it too.
--
v2: winegstreamer: Handle Gstreamer pipeline flushes gracefully in the media source.
winegstreamer: Ignore an assert in wg_parser.
winegstreamer: Don't only accept segment events when streams are enabled.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5917
--
v2: ntdll: Buffer pagemap reads in fill_working_set_info().
ntdll: Fill range of output in fill_working_set_info().
ntdll: Limit vprot scan range to the needed interval in get_working_set_ex().
ntdll: Iterate views instead of requested addresses in get_working_set_ex().
https://gitlab.winehq.org/wine/wine/-/merge_requests/5907
With [`VK_EXT_device_address_binding_report`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_device_address_binding_report.html) we can get [debug_util](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/ht… callbacks used to track memory bindings. Since it's the host's implementation that starts the callback we have to be sure that we have a way of converting it to the client side's variant before it's added to the handle map - i.e. we don't know the host handle at that time yet.
This is [used by vkd3d-proton](https://github.com/HansKristian-Work/vkd3d-proton/pull/1962). Requires Mesa with https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28649.
before (note the missing BIND for VkDevice which actually means `VkDeviceMemory`):
```
vkd3d-proton % VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
after:
```
% VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
[The spec guarantees](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/v… the following:
> An application can receive multiple callbacks if multiple VkDebugUtilsMessengerEXT objects are created. A callback will always be executed in the same thread as the originating Vulkan call.
As of TLS I went with a suggestion from IRC:
```
<ivyl_> There's an issue with how we handle callbacks related to VK_EXT_debug_utils and VK_EXT_debug_report. In wine_vkAllocateMemory() we call device->funcs.p_vkAllocateMemory() which may execute callback.
<ivyl_> At this point we still don't have handle mapping added because we don't know what host_memory handle will be.
<ivyl_> AFAIU there's a spec guarantee that callback will be executed in the same thread as the call causing it, so I was thinking about maybe keeping `memory` in a tls (if enable_wrapper_list) and using that?
<ivyl_> but that's I don't see any precedent of using thread local storage on the unix side
<ivyl_> tls value would be short-lived in such case - only for the duration of the call to `device->funcs.p_vkAllocateMemory()`
<jacekc_> we usually use teb on unix side, see ntuser_thread_info
```
--
v4: winevulkan: Make device memory wrapper available in callbacks.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5658
IIUC atexit isn't exported by ucrtbase, but still exists (maybe as a builtin) and is resolved to a module-local symbol which can be used to register functions executed on module process detach. It is called implicitly by C++ compilers to register static destructors.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5915
Adds the registry key
HKEY_CURRENT_USER\\Software\\Wine\\Wayland Driver\\rawinput
witch allows mouse raw input. This makes it easier
to calculate the same sensitivity in different games,
use sensitivity calculators, and easily change values
when changing mouse DPI and do not depend on the compositor or OS.
For example, you want to set the sensitivity to half as much,
but sensitivity curves in libinput are more difficult
to calculate than mouse sensitivity in the games.
Implementation of ideas written in the comments: https://gitlab.winehq.org/wine/wine/-/merge_requests/4698
--
v5: winewayland.drv: Add mouse rawinput support
server: Add send_hardware_message flags for rawinput translation.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5869
This is part IX of cmd.exe' parse engine rewrite.
It does some code cleanup and factorization for reading next line of input.
It tidies up parse time variable expansion and
starts beefing up the new parser.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5913
Additional tests reveal that RTL_QUERY_REGISTRY_DIRECT does work with
non-string default values, it just requires a pointer to the value and
it doesn't infer the size automatically. That means that the same code
can be used to handle both default and non-default values.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5911
Additional tests reveal that RTL_QUERY_REGISTRY_DIRECT does work with
non-string default values, it just requires a pointer to the value and
it doesn't infer the size automatically. That means that the same code
can be used to handle both default and non-default values.
--
v2: ntdll: Don't special-case default values in RtlQueryRegistryValues.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5911
This MR adds support for creating file mapping objects backed by large pages on Linux, by making the following changes:
## wineserver
* On Linux, `create_temp_file` will first attempt to use memfds as the backing fd. If it fails, it'll return to the current codepath, creating a temporary file in either the server or config directory.
* The created memfd will be sealed against writes, if the caller requesting the appropriate page protection flags.
* This removes the requirement that FDs be only created on filesystems/directories that aren't `noexec`.
* In the server method `create_mapping` , if large pages have been requested by the caller, hold that the calling thread's token holds `SeLockMemoryPrivilege` .
* Additionally, add `SeLockMemoryPrivilege` to the list of privileges enabled for the Administrator.
## `ntdll`
* Add `virtual_get_min_large_page_size` and its exported wrapper `wine_unix_get_min_large_page_size`.
* On Linux, the minimum page size is determined by going through `/sys/kernel/mm/hugepages`. If hugepage support was not detected, `STATUS_NOT_SUPPORTED` is returned instead. On other platforms, the older hard-coded value of 2\*1024\*1024 is returned instead.
* `NtCreateSection` will validate certain parameters if large pages are requested. Specifically, it will return STATUS_INVALID_PARAMETER if the requested mapping is not anonymous/unnamed, or the size is not a multiple of the minimum supported page size.
## `kernelbase`
* `GetLargePageMinimum` will use `wine_unix_get_min_large_page_size`.
## `kernel32/tests`
* Add new test test_large_page_file_mapping, which validates privilege enforcements and parameter validation while creating large pages backed file mapping obejcts. The tests are skipped if `GetLargePageMinimum` returns 0.
--
v24: ntdll: Use PAGEMAP_SCAN to implement get_working_set_ex, if available.
kernel32: Add tests for large page mapping support.
ntdll: Support creating and mapping files backed by large pages (SEC_LARGE_PAGES).
server: Use memfd to back anonymous mappings on Linux.
kernelbase: Implement GetLargePageMinimum by returning the value of LargePageMinimum in _KUSER_SHARED_DATA.
server: Set LargePageMinimum in _KUSER_SHARED_DATA on Linux.
server: Require SeLockMemoryPrivilege to create large page mappings.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5769
If the script cache was already freed before ScriptTextOut() runs and
hence the sfnt member is not available, use the definition from
init_script_cache() to conditionally apply the ETO_GLYPH_INDEX flag.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5893
On Mon May 22 19:01:15 2023 +0000, Davide Beatrici wrote:
> Mmm... looks like a debugging leftover. @julliard
> In any case, I'm going to set it back to `DefaultPeriod`. We can always
> fix it in a dedicated commit.
Done in 5c6e63bac21d3cbeed56ad76f45f16fa8fc76518.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/2868#note_73995
To reproduce it, I moved gripper left and right to hide some buttons, then brought it back. On the first image chevron didn't disappear as expected. On the second one chevron went away as I applied fix.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5706#note_73935
Xcode 15.3 adds a new linker flag (`-no_huge`) which allows the loader to use zero-fill sections to reserve the areas currently being reserved by the preloader.
This means the preloader is no longer needed (a good thing, since it's heavily dependent on private APIs).
The preloader will still be used when Xcode <15.3 is being used, or when building for i386 (32-bit for 10.14 and earlier).
I've also tested a 64-bit wineloader built with Xcode 15.3 on macOS 10.13 and found that it works correctly.
The only user-visible change I've found is that `setprogname()` now correctly changes the process name, so a `ps` listing will now show (for example) `C:\windows\regedit.exe` (as it does on Linux) instead of `/Users/bshanks/wine/build64/loader/wine-preloader C:\windows\regedit.exe`.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5884
With [`VK_EXT_device_address_binding_report`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_device_address_binding_report.html) we can get [debug_util](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/ht… callbacks used to track memory bindings. Since it's the host's implementation that starts the callback we have to be sure that we have a way of converting it to the client side's variant before it's added to the handle map - i.e. we don't know the host handle at that time yet.
This is [used by vkd3d-proton](https://github.com/HansKristian-Work/vkd3d-proton/pull/1962). Requires Mesa with https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28649.
before (note the missing BIND for VkDevice which actually means `VkDeviceMemory`):
```
vkd3d-proton % VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
after:
```
% VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
[The spec guarantees](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/v… the following:
> An application can receive multiple callbacks if multiple VkDebugUtilsMessengerEXT objects are created. A callback will always be executed in the same thread as the originating Vulkan call.
As of TLS I went with a suggestion from IRC:
```
<ivyl_> There's an issue with how we handle callbacks related to VK_EXT_debug_utils and VK_EXT_debug_report. In wine_vkAllocateMemory() we call device->funcs.p_vkAllocateMemory() which may execute callback.
<ivyl_> At this point we still don't have handle mapping added because we don't know what host_memory handle will be.
<ivyl_> AFAIU there's a spec guarantee that callback will be executed in the same thread as the call causing it, so I was thinking about maybe keeping `memory` in a tls (if enable_wrapper_list) and using that?
<ivyl_> but that's I don't see any precedent of using thread local storage on the unix side
<ivyl_> tls value would be short-lived in such case - only for the duration of the call to `device->funcs.p_vkAllocateMemory()`
<jacekc_> we usually use teb on unix side, see ntuser_thread_info
```
--
v3: winevulkan: Make device memory wrapper available in callbacks.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5658
Rémi Bernon (@rbernon) commented about dlls/winemac.drv/keyboard.c:
> done:
> /* Null-terminate the buffer, if there's room. MSDN clearly states that the
> caller must not assume this is done, but some programs (e.g. Audiosurf) do. */
> - if (1 <= ret && ret < bufW_size)
> - bufW[ret] = 0;
> + if (0 <= len && len < bufW_size)
```suggestion:-0+0
if (len < bufW_size)
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5319#note_73910
Rémi Bernon (@rbernon) commented about dlls/winemac.drv/keyboard.c:
> &savedDeadKeyState, bufW_size, &len, bufW);
> if (status != noErr)
> {
> - ERR_(key)("Couldn't translate keycode 0x%04x, status %d\n", keyc, status);
> + ERR_(key)("Couldn't translate dead keycode 0x%04x, status %d\n", keyc, status);
> goto done;
> }
>
> + if (len >= 1)
Same, doesn't seem to be necessary? If len is 0, and dead = TRUE, we just return 0 anyway?
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5319#note_73909
This is part VIII of cmd engine rewrite.
It covers:
- introduction of a token based parser. For now, it produces the same
(degenerated) list of commands as we currently do.
Note: I opted for a pull mode for the parser while the lexer is in
push mode. Long term plan is to move the lexer into pull mode too
(and also converge the two different current methods of
argument/token access).
- introduction of return codes. It's not obvious from current tests
that lots of these codes are actually the kernel32 ones, but tests
in later MRs will clearly show it.
- starting changing 'exit' and 'goto' builtin implementations to use
return code. All builtins will have to adopt that scheme for
command chaining to be properly supported.
- add delayed expansion for IF command. That's not needed for now
(as single command execution already takes care of it), but will be
needed when we move IF and FOR commands out of single command in yet
to come MR.
Includes some test to cover that part.
(in case someone asks, it was needed in previous MR regarding the
FOR command, as the delayed expansion was only called on the body
of the FOR command, not the control block)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5903
With [`VK_EXT_device_address_binding_report`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_device_address_binding_report.html) we can get [debug_util](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/ht… callbacks used to track memory bindings. Since it's the host's implementation that starts the callback we have to be sure that we have a way of converting it to the client side's variant before it's added to the handle map - i.e. we don't know the host handle at that time yet.
This is [used by vkd3d-proton](https://github.com/HansKristian-Work/vkd3d-proton/pull/1962). Requires Mesa with https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28649.
before (note the missing BIND for VkDevice which actually means `VkDeviceMemory`):
```
vkd3d-proton % VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232285.553:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
after:
```
% VKD3D_TEST_FILTER=create_placed_resource_size VKD3D_CONFIG=fault VKD3D_DEBUG=trace ~/src/wine/build/wine ./tests/d3d12.exe 2>&1 | grep vkd3d_address_binding_callback
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.036:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkImage || VA ffff800100200000 || size 000000000019a000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: BIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkBuffer || VA ffff800100200000 || size 0000000001000000.
232338.037:0020:0024:trace:vkd3d-proton:vkd3d_address_binding_callback: UNBIND || VkDevice || VA ffff800100200000 || size 0000000001000000.
```
[The spec guarantees](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/v… the following:
> An application can receive multiple callbacks if multiple VkDebugUtilsMessengerEXT objects are created. A callback will always be executed in the same thread as the originating Vulkan call.
As of TLS I went with a suggestion from IRC:
```
<ivyl_> There's an issue with how we handle callbacks related to VK_EXT_debug_utils and VK_EXT_debug_report. In wine_vkAllocateMemory() we call device->funcs.p_vkAllocateMemory() which may execute callback.
<ivyl_> At this point we still don't have handle mapping added because we don't know what host_memory handle will be.
<ivyl_> AFAIU there's a spec guarantee that callback will be executed in the same thread as the call causing it, so I was thinking about maybe keeping `memory` in a tls (if enable_wrapper_list) and using that?
<ivyl_> but that's I don't see any precedent of using thread local storage on the unix side
<ivyl_> tls value would be short-lived in such case - only for the duration of the call to `device->funcs.p_vkAllocateMemory()`
<jacekc_> we usually use teb on unix side, see ntuser_thread_info
```
--
v2: winevulkan: Make device memory wrapper available in callbacks.
https://gitlab.winehq.org/wine/wine/-/merge_requests/5658
The current implementation enqueues the vkQueuePresentKHR() command after waiting on a fence which was enqueued where this command should go. However, this occurs in a worker thread to avoid deadlock, so an arbitrary number of additional commands may be enqueued before vkQueuePresentKHR(). I haven't found a specific scenario where this is a problem, but it is not desirable if we can avoid it.
This new implementation is just an RFC; it won't build because the vkd3d function is missing. That can be found [here](https://gitlab.winehq.org/cmccarthy/vkd3d/-/blob/present/libs/vkd3d/c… but I haven't raised an MR. The DXGI side meets all requirements: vkAcquireNextImageKHR() blocks there, but the driver unblocks it so deadlock is not possible. The vkd3d function waits only for the command queue op mutex and cannot deadlock either. The overall implementation should be less fragile, and doesn't need a worker thread.
A few days ago I saw a performance increase in HZD from reverting DXGI to before the worker was added, but have never seen this again. Performance differences are minimal between old, current and this one.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5851
On Fri Jun 21 05:51:22 2024 +0000, Conor McCarthy wrote:
> changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/5830/diffs?diff_id=118898&start_sha=0a098294aa1607350d8e382416546fe945fac98b#b8e9f5f67cc13143a0928d1e76d7519d0bab1bc3_1773_1764)
I removed this from the MR as I think it should be separate. We need one semaphore per Vulkan image. Indexing the semaphore array is an issue because we have no `vk_image_index`, but `frame_number % swapchain->buffer_count` may be ok.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5830#note_73880
On Mon Jun 17 17:07:40 2024 +0000, Elizabeth Figura wrote:
> Without doing any research myself... the other side is going to try to
> enter the logic immediately [within SleepConditionVariableCS()] assuming
> it's waiting, and I think usually wakes are fast enough [at least on
> Linux] that the other thread will generally start executing before you
> even return from the wake function.
> Besides a poorly communicated warning that doesn't apply here, the first
> comment in [1] also claims that it defeats a "wait morphing"
> optimization, where instead of actually waking threads they're just
> moved from the CV waitqueue to the mutex wait queue [if their associated
> mutex is locked [by the calling thread?]]. That's not something we
> currently implement in Wine; it may be possible to implement later though...
> [1] https://stackoverflow.com/questions/52503361/unlock-the-mutex-after-conditi…
I do see a small but measurable performance gain in HZD. It's only 0.7%, but that shoud be weighed that against the very simple change needed to gain it.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5830#note_73878
On Fri Jun 21 05:51:23 2024 +0000, Conor McCarthy wrote:
> changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/5830/diffs?diff_id=118898&start_sha=0a098294aa1607350d8e382416546fe945fac98b#b8e9f5f67cc13143a0928d1e76d7519d0bab1bc3_1282_1269)
I replaced this with a wait for the blit before returning from `d3d12_swapchain_present()`. After a call to Present() returns, the client can render to the next buffer in sequence, so we must wait for completion of the blit read of that buffer. The old version using `vkAcquireNextImageKHR()` is not strict enough. HZD with vsync has frame pacing issues in some parts of the benchmark even on the old implementation, and this makes it a little bit worse. We can't really avoid that though, and the best fix is to improve frame times in vkd3d.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5830#note_73879
The last commit fixes glitches in Horizon Zero Dawn with vsync on, for reasons stated in the comment there.
The wined3d implementation already blocks the client's call to `Present()` when `vkAcquireNextImageKHR()` blocks, so is roughly equivalent to this when frame latency and buffer count are equal. It has a frame latency implementation which unblocks after calling `vkQueuePresentKHR()`, rather than waiting for its execution to complete. I think the d3d12 implementation is supposed to do the latter, though using `KHR_present_wait` may be unnecessary overkill. Waiting on queue execution comes with a performance cost either way, so without a compelling reason for a strict implementation, something similar to wined3d makes sense.
Another potential issue is after the call to `ID3D12CommandQueue_Signal()` in `d3d12_swapchain_present()`, the client is free to enqueue more commands when `Present()` returns, so by the time the signal is executed and the swapchain worker blits the image and calls `vkQueuePresentKHR()`, these commands are not necessarily enqueued immediately after the `Signal()`. This may not always be harmless.
--
v2: dxgi: Wait for completion of a pending read of the next buffer before returning from d3d12_swapchain_Present().
dxgi: Wake the condition variable after leaving the critical section in d3d12_swapchain_resize_buffers().
dxgi: Wake the condition variable after leaving the critical section in d3d12_swapchain_present().
https://gitlab.winehq.org/wine/wine/-/merge_requests/5830
Huh. Okay.
I've seen some of those discussions, and something in them did indeed feel strange. (I never understood the context well enough to determine exactly what, and it's not my place to question that, anyways.)
I'll miss you 💔
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/5886#note_73870