Used by Hitman 2.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- .../api-ms-win-core-processthreads-l1-1-3.spec | 2 +- dlls/kernel32/kernel32.spec | 1 + dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/thread.c | 10 ++++++++++ 4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/api-ms-win-core-processthreads-l1-1-3/api-ms-win-core-processthreads-l1-1-3.spec b/dlls/api-ms-win-core-processthreads-l1-1-3/api-ms-win-core-processthreads-l1-1-3.spec index 3b57e1c8..6f0c4fa7 100644 --- a/dlls/api-ms-win-core-processthreads-l1-1-3/api-ms-win-core-processthreads-l1-1-3.spec +++ b/dlls/api-ms-win-core-processthreads-l1-1-3/api-ms-win-core-processthreads-l1-1-3.spec @@ -5,6 +5,6 @@ @ stub GetThreadSelectedCpuSets @ stub SetProcessDefaultCpuSets @ stub SetProcessInformation -@ stub SetThreadDescription +@ stdcall SetThreadDescription(ptr wstr) kernel32.SetThreadDescription @ stdcall SetThreadIdealProcessor(long long) kernel32.SetThreadIdealProcessor @ stub SetThreadSelectedCpuSets diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 23c25b7a..88708845 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1447,6 +1447,7 @@ @ stdcall SetTermsrvAppInstallMode(long) @ stdcall SetThreadAffinityMask(long long) @ stdcall -import SetThreadContext(long ptr) +@ stdcall -import SetThreadDescription(ptr wstr) @ stdcall -import SetThreadErrorMode(long ptr) @ stdcall SetThreadExecutionState(long) @ stdcall -import SetThreadGroupAffinity(long ptr ptr) diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index c1fa4795..a86a3fe2 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1478,7 +1478,7 @@ @ stdcall SetSystemTime(ptr) @ stdcall SetSystemTimeAdjustment(long long) kernel32.SetSystemTimeAdjustment @ stdcall SetThreadContext(long ptr) -# @ stub SetThreadDescription +@ stdcall SetThreadDescription(ptr wstr) @ stdcall SetThreadErrorMode(long ptr) @ stdcall SetThreadGroupAffinity(long ptr ptr) @ stdcall SetThreadIdealProcessor(long long) diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index 0cac2b69..4775f69c 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -387,6 +387,16 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetThreadContext( HANDLE thread, const CONTEXT *co }
+/*********************************************************************** + * SetThreadDescription (kernelbase.@) + */ +HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription( HANDLE thread, PCWSTR description ) +{ + FIXME( "(%p %s): stub\n", thread, wine_dbgstr_w( description ) ); + return E_NOTIMPL; +} + + /*********************************************************************** * SetThreadErrorMode (kernelbase.@) */
Used by Hitman 2. Multiple nodes and command queues are not supported.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/swapchain.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 9e620e0b..004bd145 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2311,17 +2311,13 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc(IDXGISwapChain3 *iface, return S_OK; }
-static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 *iface, +static HRESULT d3d12_swapchain_resize_buffers(struct d3d12_swapchain *swapchain, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) { - struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); DXGI_SWAP_CHAIN_DESC1 *desc, new_desc; unsigned int i; ULONG refcount;
- TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n", - iface, buffer_count, width, height, debug_dxgi_format(format), flags); - if (flags) FIXME("Ignoring flags %#x.\n", flags);
@@ -2373,6 +2369,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 * return d3d12_swapchain_recreate_vulkan_swapchain(swapchain); }
+static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 *iface, + UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) +{ + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + + TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n", + iface, buffer_count, width, height, debug_dxgi_format(format), flags); + + return d3d12_swapchain_resize_buffers(swapchain, buffer_count, width, height, format, flags); +} + static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface, const DXGI_MODE_DESC *target_mode_desc) { @@ -2642,11 +2649,26 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers1(IDXGISwapChain3 UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags, const UINT *node_mask, IUnknown * const *present_queue) { - FIXME("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x, " - "node_mask %p, present_queue %p stub!\n", + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); + size_t i, count; + + TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x, " + "node_mask %p, present_queue %p.\n", iface, buffer_count, width, height, debug_dxgi_format(format), flags, node_mask, present_queue);
- return E_NOTIMPL; + if (!node_mask || !present_queue) + return DXGI_ERROR_INVALID_CALL; + + count = buffer_count ? buffer_count : swapchain->desc.BufferCount; + for (i = 0; i < count; ++i) + { + if (node_mask[i] > 1 || !present_queue[i]) + return DXGI_ERROR_INVALID_CALL; + if ((ID3D12CommandQueue*)present_queue[i] != swapchain->command_queue) + FIXME("Ignoring present queue %p.\n", present_queue[i]); + } + + return d3d12_swapchain_resize_buffers(swapchain, buffer_count, width, height, format, flags); }
static const struct IDXGISwapChain3Vtbl d3d12_swapchain_vtbl =
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59524
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/adapter_gl.c | 4 +++- dlls/wined3d/adapter_vk.c | 4 +++- dlls/wined3d/device.c | 6 +++--- dlls/wined3d/directx.c | 11 +++++++---- dlls/wined3d/wined3d_private.h | 10 +++++++++- 5 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 52f0fd7a..a8dca54c 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -3879,7 +3879,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n", driver_info->version_high, driver_info->version_low);
- adapter->vram_bytes_used = 0; + memset(&adapter->memory_usage, 0, sizeof(adapter->memory_usage)); + adapter->memory_events = NULL; + adapter->event_count = 0; TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(driver_info->vram_bytes));
if (gl_info->supported[EXT_MEMORY_OBJECT]) diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 21163a20..81526ade 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1180,7 +1180,9 @@ static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, VK_CALL(vkGetPhysicalDeviceMemoryProperties(adapter_vk->physical_device, &memory_properties));
adapter_vk_init_driver_info(adapter, &properties2.properties, &memory_properties); - adapter->vram_bytes_used = 0; + memset(&adapter->memory_usage, 0, sizeof(adapter->memory_usage)); + adapter->memory_events = NULL; + adapter->event_count = 0; TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->driver_info.vram_bytes));
memcpy(&adapter->driver_uuid, id_properties.driverUUID, sizeof(adapter->driver_uuid)); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2a4d3778..3f525e8e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1202,10 +1202,10 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device
TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n", wine_dbgstr_longlong(driver_info->vram_bytes), - wine_dbgstr_longlong(device->adapter->vram_bytes_used), - wine_dbgstr_longlong(driver_info->vram_bytes - device->adapter->vram_bytes_used)); + wine_dbgstr_longlong(device->adapter->memory_usage[0].bytes_used), + wine_dbgstr_longlong(driver_info->vram_bytes - device->adapter->memory_usage[0].bytes_used));
- return min(UINT_MAX, driver_info->vram_bytes - device->adapter->vram_bytes_used); + return min(UINT_MAX, driver_info->vram_bytes - device->adapter->memory_usage[0].bytes_used); }
void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 0688e49c..bf4fad31 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -146,16 +146,17 @@ static HRESULT wined3d_output_init(struct wined3d_output *output, const WCHAR *d /* Adjust the amount of used texture memory */ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) { - adapter->vram_bytes_used += amount; + adapter->memory_usage[0].bytes_used += amount; TRACE("Adjusted used adapter memory by 0x%s to 0x%s.\n", wine_dbgstr_longlong(amount), - wine_dbgstr_longlong(adapter->vram_bytes_used)); - return adapter->vram_bytes_used; + wine_dbgstr_longlong(adapter->memory_usage[0].bytes_used)); + return adapter->memory_usage[0].bytes_used; }
void wined3d_adapter_cleanup(struct wined3d_adapter *adapter) { wined3d_output_cleanup(&adapter->output); + heap_free(adapter->memory_events); heap_free(adapter->formats); }
@@ -2777,7 +2778,9 @@ static struct wined3d_adapter *wined3d_adapter_no3d_create(unsigned int ordinal, return NULL;
wined3d_driver_info_init(&adapter->driver_info, &gpu_description, 0, 0); - adapter->vram_bytes_used = 0; + memset(&adapter->memory_usage, 0, sizeof(adapter->memory_usage)); + adapter->memory_events = NULL; + adapter->event_count = 0; TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->driver_info.vram_bytes));
if (!wined3d_adapter_init(adapter, ordinal, &wined3d_adapter_no3d_ops)) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 61096a03..f2eab0aa 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2867,6 +2867,12 @@ struct wined3d_output D3DDDI_VIDEO_PRESENT_SOURCE_ID vidpn_source_id; };
+struct wined3d_adapter_memory_usage +{ + UINT64 bytes_used; + UINT64 bytes_reserved; +}; + /* The adapter structure */ struct wined3d_adapter { @@ -2878,7 +2884,9 @@ struct wined3d_adapter struct wined3d_d3d_info d3d_info; struct wined3d_driver_info driver_info; struct wined3d_output output; - UINT64 vram_bytes_used; + struct wined3d_adapter_memory_usage memory_usage[2]; + HANDLE *memory_events; + DWORD event_count; GUID driver_uuid; GUID device_uuid; LUID luid;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59525
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit Chinese:China report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger: Timeout
=== debian10 (64 bit WoW report) ===
kernel32: debugger: Timeout
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/wined3d/directx.c | 178 ++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 5 ++ include/wine/wined3d.h | 17 ++++ 3 files changed, 200 insertions(+)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index bf4fad31..ee6715ca 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1377,6 +1377,184 @@ fail: return WINED3DERR_INVALIDCALL; }
+HRESULT CDECL wined3d_update_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used) +{ + struct wined3d_adapter *adapter; + DWORD i; + + wined3d_mutex_lock(); + + if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage)) + goto fail; + + adapter = wined3d->adapters[adapter_idx]; + adapter->memory_usage[non_local].bytes_used = bytes_used; + if (non_local) + adapter->driver_info.sysmem_bytes = bytes_total; + else + adapter->driver_info.vram_bytes = bytes_total; + + for (i = 0; i < adapter->event_count; ++i) + if (adapter->memory_events[i]) + SetEvent(adapter->memory_events[i]); + + wined3d_mutex_unlock(); + + return WINED3D_OK; + +fail: + wined3d_mutex_unlock(); + return E_INVALIDARG; +} + +HRESULT CDECL wined3d_get_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, struct wined3d_adapter_memory_info *info) +{ + const struct wined3d_adapter *adapter; + + TRACE("wined3d %p, adapter_idx %u, non_local %u, info %p.\n", + wined3d, adapter_idx, non_local, info); + + wined3d_mutex_lock(); + + if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage)) + goto fail; + + adapter = wined3d->adapters[adapter_idx]; + + /* vram_bytes may be zero for a UMA adapter. DXGI defines all memory as local for UMA adapters. */ + if (!adapter->driver_info.vram_bytes) + info->total = non_local ? 0 : adapter->driver_info.sysmem_bytes; + else + info->total = non_local ? adapter->driver_info.sysmem_bytes : adapter->driver_info.vram_bytes; + info->used = adapter->memory_usage[non_local].bytes_used; + info->reserved = adapter->memory_usage[non_local].bytes_reserved; + + wined3d_mutex_unlock(); + + return WINED3D_OK; + +fail: + wined3d_mutex_unlock(); + return E_INVALIDARG; +} + +HRESULT CDECL wined3d_set_adapter_reserved_memory(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, UINT64 reservation) +{ + struct wined3d_adapter_memory_info memory_info; + struct wined3d_adapter *adapter; + HRESULT hr; + + TRACE("wined3d %p, adapter_idx %u, non_local %u, reservation 0x%s.\n", + wined3d, adapter_idx, non_local, wine_dbgstr_longlong(reservation)); + + if (FAILED(hr = wined3d_get_adapter_memory_info(wined3d, adapter_idx, non_local, &memory_info))) + return hr; + if (memory_info.total && reservation > memory_info.total) + return E_INVALIDARG; + + /* FIXME: Windows returns E_INVALIDARG if non-local and a non-zero reservation are specified for + * a UMA adapter. UMA status is unknown unless adapter->driver_info.vram_bytes is zero. */ + + wined3d_mutex_lock(); + + if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage)) + goto fail; + + FIXME("Memory reservation sizes are returned if queried but otherwise are ignored.\n"); + adapter = wined3d->adapters[adapter_idx]; + adapter->memory_usage[non_local].bytes_reserved = reservation; + + wined3d_mutex_unlock(); + + return WINED3D_OK; + +fail: + wined3d_mutex_unlock(); + return E_INVALIDARG; +} + +static BOOL wined3d_set_unused_event_handle(struct wined3d_adapter *adapter, HANDLE event, DWORD *cookie) +{ + DWORD i; + for (i = 0; i < adapter->event_count; ++i) + { + if (!adapter->memory_events[i]) + { + adapter->memory_events[i] = event; + *cookie = i; + return TRUE; + } + } + return FALSE; +} + +HRESULT CDECL wined3d_register_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx, + HANDLE event, DWORD *cookie) +{ + HRESULT hr = E_INVALIDARG; + struct wined3d_adapter *adapter; + HANDLE *new_buffer; + + TRACE("wined3d %p, adapter_idx %u, event %p, cookie %p.\n", + wined3d, adapter_idx, event, cookie); + + if (!cookie) + return E_INVALIDARG; + + wined3d_mutex_lock(); + + if (adapter_idx >= wined3d->adapter_count) + goto done; + + adapter = wined3d->adapters[adapter_idx]; + if (!wined3d_set_unused_event_handle(adapter, event, cookie)) + { + if(!(new_buffer = heap_realloc(adapter->memory_events, (adapter->event_count + 1) * sizeof(*adapter->memory_events)))) + { + hr = E_OUTOFMEMORY; + goto done; + } + adapter->memory_events = new_buffer; + adapter->memory_events[adapter->event_count] = event; + *cookie = adapter->event_count++; + } + + hr = WINED3D_OK; + +done: + wined3d_mutex_unlock(); + return hr; +} + +HRESULT CDECL wined3d_unregister_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx, + DWORD cookie) +{ + struct wined3d_adapter *adapter; + + TRACE("wined3d %p, adapter_idx %u, cookie %u.\n", wined3d, adapter_idx, cookie); + + wined3d_mutex_lock(); + + if (adapter_idx >= wined3d->adapter_count) + goto fail; + + adapter = wined3d->adapters[adapter_idx]; + if (cookie >= adapter->event_count) + goto fail; + adapter->memory_events[cookie] = NULL; + + wined3d_mutex_unlock(); + + return WINED3D_OK; + +fail: + wined3d_mutex_unlock(); + return E_INVALIDARG; +} + HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx, struct wined3d_raster_status *raster_status) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 4f3cdf9b..24b80df8 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -14,15 +14,20 @@ @ cdecl wined3d_get_adapter_count(ptr) @ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr) @ cdecl wined3d_get_adapter_identifier(ptr long long ptr) +@ cdecl wined3d_get_adapter_memory_info(ptr long long ptr) @ cdecl wined3d_get_adapter_mode_count(ptr long long long) @ cdecl wined3d_get_adapter_output(ptr long ptr) @ cdecl wined3d_get_adapter_raster_status(ptr long ptr) @ cdecl wined3d_get_device_caps(ptr long long ptr) @ cdecl wined3d_get_output_desc(ptr long ptr) @ cdecl wined3d_incref(ptr) +@ cdecl wined3d_register_adapter_memory_event(ptr long ptr ptr) @ cdecl wined3d_register_software_device(ptr ptr) @ cdecl wined3d_register_window(ptr ptr ptr long) @ cdecl wined3d_set_adapter_display_mode(ptr long ptr) +@ cdecl wined3d_set_adapter_reserved_memory(ptr long long int64); +@ cdecl wined3d_unregister_adapter_memory_event(ptr long long); +@ cdecl wined3d_update_adapter_memory_info(ptr long long int64 int64); @ cdecl wined3d_unregister_windows(ptr)
@ cdecl wined3d_blend_state_create(ptr ptr ptr ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0b535475..0dca0b76 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1742,6 +1742,13 @@ struct wined3d_adapter_identifier SIZE_T shared_system_memory; };
+struct wined3d_adapter_memory_info +{ + UINT64 total; + UINT64 used; + UINT64 reserved; +}; + struct wined3d_swapchain_desc { unsigned int backbuffer_width; @@ -2206,6 +2213,8 @@ HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d, struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation); HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier); +HRESULT __cdecl wined3d_get_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, struct wined3d_adapter_memory_info *info); UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx, enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering); struct wined3d_output * __cdecl wined3d_get_adapter_output(const struct wined3d *wined3d, unsigned int adapter_idx); @@ -2216,11 +2225,19 @@ HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, unsigned HRESULT __cdecl wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_output_desc *desc); ULONG __cdecl wined3d_incref(struct wined3d *wined3d); +HRESULT __cdecl wined3d_register_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx, + HANDLE event, DWORD *cookie); HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function); BOOL __cdecl wined3d_register_window(struct wined3d *wined3d, HWND window, struct wined3d_device *device, unsigned int flags); HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d, UINT adapter_idx, const struct wined3d_display_mode *mode); +HRESULT __cdecl wined3d_set_adapter_reserved_memory(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, UINT64 reservation); +HRESULT __cdecl wined3d_unregister_adapter_memory_event(const struct wined3d *wined3d, unsigned int adapter_idx, + DWORD cookie); +HRESULT __cdecl wined3d_update_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx, + unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used); void __cdecl wined3d_unregister_windows(struct wined3d *wined3d);
HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59526
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit Chinese:China report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty
On Thu, 7 Nov 2019 at 18:25, Conor McCarthy cmccarthy@codeweavers.com wrote:
+HRESULT CDECL wined3d_update_adapter_memory_info(const struct wined3d *wined3d, unsigned int adapter_idx,
unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used)
+{
- struct wined3d_adapter *adapter;
- DWORD i;
- wined3d_mutex_lock();
- if (adapter_idx >= wined3d->adapter_count || non_local >= ARRAY_SIZE(adapter->memory_usage))
goto fail;
- adapter = wined3d->adapters[adapter_idx];
- adapter->memory_usage[non_local].bytes_used = bytes_used;
This would override any accounting done by adapter_adjust_memory(), and potentially unbalance allocations and frees done through there.
Used by Hitman 2.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/adapter.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index d2fc629c..d277dfd5 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -294,41 +294,33 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryVideoMemoryInfo(IWineDXGIAdap UINT node_index, DXGI_MEMORY_SEGMENT_GROUP segment_group, DXGI_QUERY_VIDEO_MEMORY_INFO *info) { struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); - struct wined3d_adapter_identifier adapter_id; + struct wined3d_adapter_memory_info memory_info; static unsigned int once; HRESULT hr;
TRACE("iface %p, node_index %u, segment_group %#x, info %p.\n", iface, node_index, segment_group, info);
+ if (segment_group > DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL) + { + WARN("Invalid memory segment group 0x%x.\n", segment_group); + return E_INVALIDARG; + } + if (!once++) - FIXME("Returning fake video memory info.\n"); + FIXME("Returning fake or estimated video memory info.\n");
if (node_index) FIXME("Ignoring node index %u.\n", node_index);
- adapter_id.driver_size = 0; - adapter_id.description_size = 0; - adapter_id.device_name_size = 0; - - if (FAILED(hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id))) + if (FAILED(hr = wined3d_get_adapter_memory_info(adapter->factory->wined3d, adapter->ordinal, segment_group, &memory_info))) return hr;
- switch (segment_group) - { - case DXGI_MEMORY_SEGMENT_GROUP_LOCAL: - info->Budget = adapter_id.video_memory; - info->CurrentUsage = 0; - info->AvailableForReservation = adapter_id.video_memory / 2; - info->CurrentReservation = 0; - break; - case DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL: - memset(info, 0, sizeof(*info)); - break; - default: - WARN("Invalid memory segment group %#x.\n", segment_group); - return E_INVALIDARG; - } + /* Budget must leave a little extra space. In Windows this seems to always be about total/6.5 if total <= 8 Gb. */ + info->Budget = memory_info.total - memory_info.total / 7u; + info->CurrentUsage = memory_info.used; + info->AvailableForReservation = memory_info.total / 2u; + info->CurrentReservation = memory_info.reserved;
TRACE("Budget 0x%s, usage 0x%s, available for reservation 0x%s, reservation 0x%s.\n", wine_dbgstr_longlong(info->Budget), wine_dbgstr_longlong(info->CurrentUsage),
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59527
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit Chinese:China report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit WoW report) ===
kernel32: debugger: Timeout
Used by Hitman 2. Reservations are recorded but nothing is actually reserved.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/adapter.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index d277dfd5..5507790c 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -332,10 +332,12 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryVideoMemoryInfo(IWineDXGIAdap static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetVideoMemoryReservation(IWineDXGIAdapter *iface, UINT node_index, DXGI_MEMORY_SEGMENT_GROUP segment_group, UINT64 reservation) { - FIXME("iface %p, node_index %u, segment_group %#x, reservation 0x%s stub!\n", + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + FIXME("iface %p, node_index %u, segment_group %#x, reservation 0x%s partial stub!\n", iface, node_index, segment_group, wine_dbgstr_longlong(reservation));
- return S_OK; + return wined3d_set_adapter_reserved_memory(adapter->factory->wined3d, adapter->ordinal, segment_group, reservation); }
static HRESULT STDMETHODCALLTYPE dxgi_adapter_RegisterVideoMemoryBudgetChangeNotificationEvent(
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59528
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit Chinese:China report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty
=== debian10 (64 bit WoW report) ===
kernel32: debugger: Timeout
Used by Hitman 2. Also implements the unregister function. Events will only be signalled by updates sent from vkd3d.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/adapter.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 5507790c..31b2d5b4 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -343,15 +343,23 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetVideoMemoryReservation(IWineDXG static HRESULT STDMETHODCALLTYPE dxgi_adapter_RegisterVideoMemoryBudgetChangeNotificationEvent( IWineDXGIAdapter *iface, HANDLE event, DWORD *cookie) { - FIXME("iface %p, event %p, cookie %p stub!\n", iface, event, cookie); + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface);
- return E_NOTIMPL; + TRACE("iface %p, event %p, cookie %p.\n", iface, event, cookie); + + return wined3d_register_adapter_memory_event(adapter->factory->wined3d, adapter->ordinal, event, cookie); }
static void STDMETHODCALLTYPE dxgi_adapter_UnregisterVideoMemoryBudgetChangeNotification( IWineDXGIAdapter *iface, DWORD cookie) { - FIXME("iface %p, cookie %#x stub!\n", iface, cookie); + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + HRESULT hr; + + TRACE("iface %p, cookie %#x.\n", iface, cookie); + + if (FAILED(hr = wined3d_unregister_adapter_memory_event(adapter->factory->wined3d, adapter->ordinal, cookie))) + ERR("Failed to unregister notification, hr %#x.\n", hr); }
static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc3(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC3 *desc)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59529
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger.c:320: Test failed: GetThreadContext failed: 5
To be used by future patched vkd3d and Wine d3d12 modules.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/adapter.c | 12 ++++++++++++ include/wine/winedxgi.idl | 5 +++++ 2 files changed, 17 insertions(+)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 31b2d5b4..017a5712 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -396,6 +396,17 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_get_adapter_info(IWineDXGIAdapter return hr; }
+static void STDMETHODCALLTYPE dxgi_adapter_update_memory_usage(IWineDXGIAdapter *iface, + unsigned int non_local, UINT64 bytes_total, UINT64 bytes_used) +{ + struct dxgi_adapter *adapter = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, non_local %u, bytes_total 0x%s, bytes_used 0x%s.\n", iface, non_local, + wine_dbgstr_longlong(bytes_total), wine_dbgstr_longlong(bytes_used)); + + wined3d_update_adapter_memory_info(adapter->factory->wined3d, adapter->ordinal, non_local, bytes_total, bytes_used); +} + static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = { dxgi_adapter_QueryInterface, @@ -424,6 +435,7 @@ static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = dxgi_adapter_GetDesc3, /* IWineDXGIAdapter methods */ dxgi_adapter_get_adapter_info, + dxgi_adapter_update_memory_usage, };
struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 070ac2fd..237454e6 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -82,6 +82,11 @@ struct wine_dxgi_adapter_info interface IWineDXGIAdapter : IDXGIAdapter4 { HRESULT get_adapter_info([out] struct wine_dxgi_adapter_info *info); + void update_memory_usage( + [in] unsigned int non_local, + [in] UINT64 bytes_total, + [in] UINT64 bytes_used + ); }
[
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59530
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger: Timeout
=== debian10 (64 bit WoW report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5 debugger.c:320: Test failed: GetThreadContext failed: 5
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index b05e7f8b..874c39b8 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3534,6 +3534,8 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; DXGI_SWAP_EFFECT swap_effect; + IDXGISwapChain3 *swapchain3; + IUnknown *present_queue[2]; IDXGISwapChain *swapchain; ID3D12Resource *resource; ID3D10Texture2D *texture; @@ -3541,6 +3543,7 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) IDXGISurface *surface; IDXGIFactory *factory; RECT client_rect, r; + UINT node_mask[2]; ULONG refcount; HWND window; BOOL ret; @@ -3803,6 +3806,41 @@ static void test_swapchain_resize(IUnknown *device, BOOL is_d3d12) ok(!swapchain_desc.Flags, "Got unexpected Flags %#x.\n", swapchain_desc.Flags);
+ node_mask[0] = 1; + node_mask[1] = 1; + present_queue[0] = device; + present_queue[1] = device; + if (IDXGISwapChain_QueryInterface(swapchain, &IID_IDXGISwapChain3, (void **)&swapchain3) == E_NOINTERFACE) + { + skip("IDXGISwapChain3 is not supported.\n"); + } + else if (!is_d3d12) + { + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, node_mask, present_queue); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + IDXGISwapChain3_Release(swapchain3); + } + else + { + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, node_mask, present_queue); + ok(hr == S_OK, "Failed to resize buffers, hr %#x.\n", hr); + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, NULL, present_queue); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, NULL, NULL); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 0, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, NULL, NULL); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + node_mask[0] = 2; + node_mask[1] = 2; + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 2, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, node_mask, present_queue); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + /* Windows validates node masks even when the buffer count is zero. It defaults to the current buffer count. + * NULL queues cause some Windows versions to crash. */ + hr = IDXGISwapChain3_ResizeBuffers1(swapchain3, 0, 320, 240, DXGI_FORMAT_B8G8R8A8_UNORM, 0, node_mask, present_queue); + ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got hr %#x.\n", hr); + IDXGISwapChain3_Release(swapchain3); + } + IDXGISwapChain_Release(swapchain); DestroyWindow(window); refcount = IDXGIFactory_Release(factory);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59531
Your paranoid android.
=== w1064v1809_2scr (32 bit report) ===
dxgi: dxgi.c:2814: Test failed: CreateSwapChain failed, hr 0x8007000e. 1ab8:dxgi: unhandled exception c0000005 at 0040E942
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty debugger: Timeout
=== debian10 (64 bit WoW report) ===
kernel32: debugger: Timeout
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- dlls/dxgi/tests/dxgi.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 874c39b8..ef221b52 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -941,11 +941,12 @@ static void test_adapter_luid(void) static void test_query_video_memory_info(void) { DXGI_QUERY_VIDEO_MEMORY_INFO memory_info; + const UINT64 reservation = 0x100000; + HRESULT hr, non_local_hr; IDXGIAdapter3 *adapter3; IDXGIAdapter *adapter; IDXGIDevice *device; ULONG refcount; - HRESULT hr;
if (!(device = create_device(0))) { @@ -981,6 +982,23 @@ static void test_query_video_memory_info(void) hr = IDXGIAdapter3_QueryVideoMemoryInfo(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL + 1, &memory_info); ok(hr == E_INVALIDARG, "Failed to query video memory info, hr %#x.\n", hr);
+ hr = IDXGIAdapter3_SetVideoMemoryReservation(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, reservation); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = IDXGIAdapter3_SetVideoMemoryReservation(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, 0); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + non_local_hr = IDXGIAdapter3_SetVideoMemoryReservation(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, reservation); + ok(non_local_hr == S_OK || non_local_hr == E_INVALIDARG, "Got unexpected hr %#x.\n", non_local_hr); + + hr = IDXGIAdapter3_QueryVideoMemoryInfo(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &memory_info); + ok(hr == S_OK, "Failed to query video memory info, hr %#x.\n", hr); + ok(memory_info.CurrentReservation == reservation, "Got unexpected current reservation 0x%s.\n", + wine_dbgstr_longlong(memory_info.CurrentReservation)); + + hr = IDXGIAdapter3_QueryVideoMemoryInfo(adapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &memory_info); + ok(hr == S_OK || hr == E_INVALIDARG, "Failed to query video memory info, hr %#x.\n", hr); + ok(memory_info.CurrentReservation == reservation || non_local_hr == E_INVALIDARG, "Got unexpected current reservation 0x%s.\n", + wine_dbgstr_longlong(memory_info.CurrentReservation)); + IDXGIAdapter3_Release(adapter3);
done:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59532
Your paranoid android.
=== w1064v1507 (64 bit report) ===
dxgi: dxgi.c:4927: Test failed: Got unexpected message 0x31f, hwnd 00000000000F004E, wparam 0x1, lparam 0.
=== debian10 (32 bit report) ===
kernel32: debugger: Timeout
=== debian10 (32 bit WoW report) ===
kernel32: comm.c:919: Test failed: OutQueue should not be empty
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59523
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5
=== debian10 (32 bit WoW report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5