With [`VK_EXT_device_address_binding_report`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_dev...) we can get [debug_util](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_deb...) 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/vkspec.html#de...) 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.