=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: libs/vkd3d: Mark device as removed when command list in recording state is executed.

Alexandre Julliard julliard at winehq.org
Mon Apr 16 15:25:57 CDT 2018


Module: vkd3d
Branch: master
Commit: f0a1e1411363da4c139fc75bcb9fcc0171cb5d32
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=f0a1e1411363da4c139fc75bcb9fcc0171cb5d32

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Mon Apr 16 12:16:21 2018 +0200

libs/vkd3d: Mark device as removed when command list in recording state is executed.

Fixes a GPU hang in test_device_removed_reason() on RADV.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/private/vkd3d_debug.h |  3 +++
 libs/vkd3d-common/debug.c     | 17 ++++++++++++-----
 libs/vkd3d/command.c          | 13 ++++++++++++-
 libs/vkd3d/device.c           | 21 +++++++++++++++++++--
 libs/vkd3d/vkd3d_private.h    |  4 ++++
 tests/d3d12.c                 |  4 ++--
 6 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/include/private/vkd3d_debug.h b/include/private/vkd3d_debug.h
index b9d4bcd..e5e938d 100644
--- a/include/private/vkd3d_debug.h
+++ b/include/private/vkd3d_debug.h
@@ -21,6 +21,8 @@
 
 #include "vkd3d_common.h"
 
+#include <stdarg.h>
+
 enum vkd3d_dbg_level
 {
     VKD3D_DBG_LEVEL_NONE,
@@ -36,6 +38,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function,
         const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN;
 
 const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2) DECLSPEC_HIDDEN;
+const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args) DECLSPEC_HIDDEN;
 const char *debugstr_a(const char *str) DECLSPEC_HIDDEN;
 const char *debugstr_w(const WCHAR *wstr, size_t wchar_size) DECLSPEC_HIDDEN;
 
diff --git a/libs/vkd3d-common/debug.c b/libs/vkd3d-common/debug.c
index 9cdf2a9..b838045 100644
--- a/libs/vkd3d-common/debug.c
+++ b/libs/vkd3d-common/debug.c
@@ -20,7 +20,6 @@
 
 #include <assert.h>
 #include <ctype.h>
-#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -89,19 +88,27 @@ static char *get_buffer(void)
     return buffers[current_index];
 }
 
-const char *vkd3d_dbg_sprintf(const char *fmt, ...)
+const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args)
 {
     char *buffer;
-    va_list args;
 
     buffer = get_buffer();
-    va_start(args, fmt);
     vsnprintf(buffer, VKD3D_DEBUG_BUFFER_SIZE, fmt, args);
-    va_end(args);
     buffer[VKD3D_DEBUG_BUFFER_SIZE - 1] = '\0';
     return buffer;
 }
 
+const char *vkd3d_dbg_sprintf(const char *fmt, ...)
+{
+    const char *buffer;
+    va_list args;
+
+    va_start(args, fmt);
+    buffer = vkd3d_dbg_vsprintf(fmt, args);
+    va_end(args);
+    return buffer;
+}
+
 const char *debugstr_a(const char *str)
 {
     char *buffer, *ptr;
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index b7b774b..82a99fd 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -4191,6 +4191,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
 {
     struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
     const struct vkd3d_vk_device_procs *vk_procs;
+    struct d3d12_command_list *cmd_list;
     struct VkSubmitInfo submit_desc;
     VkCommandBuffer *buffers;
     VkQueue vk_queue;
@@ -4210,7 +4211,17 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
 
     for (i = 0; i < command_list_count; ++i)
     {
-        buffers[i] = unsafe_impl_from_ID3D12CommandList(command_lists[i])->vk_command_buffer;
+        cmd_list = unsafe_impl_from_ID3D12CommandList(command_lists[i]);
+
+        if (cmd_list->is_recording)
+        {
+            d3d12_device_mark_as_removed(command_queue->device, DXGI_ERROR_INVALID_CALL,
+                    "Command list %p is in recording state.\n", command_lists[i]);
+            vkd3d_free(buffers);
+            return;
+        }
+
+        buffers[i] = cmd_list->vk_command_buffer;
     }
 
     submit_desc.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 805d477..48ad7c5 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1943,9 +1943,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface,
 
 static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface)
 {
-    FIXME("iface %p stub!\n", iface);
+    struct d3d12_device *device = impl_from_ID3D12Device(iface);
 
-    return S_OK;
+    TRACE("iface %p.\n", iface);
+
+    return device->removed_reason;
 }
 
 static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *iface,
@@ -2245,6 +2247,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     if ((device->parent = create_info->parent))
         IUnknown_AddRef(device->parent);
 
+    device->removed_reason = S_OK;
+
     return S_OK;
 }
 
@@ -2270,6 +2274,19 @@ HRESULT d3d12_device_create(struct vkd3d_instance *instance,
     return S_OK;
 }
 
+void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
+        const char *message, ...)
+{
+    va_list args;
+
+    va_start(args, message);
+    WARN("Device %p is lost (reason %#x, message \"%s\").\n",
+            device, reason, vkd3d_dbg_vsprintf(message, args));
+    va_end(args);
+
+    device->removed_reason = reason;
+}
+
 IUnknown *vkd3d_get_device_parent(ID3D12Device *device)
 {
     struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 246c42b..4a359db 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -683,10 +683,14 @@ struct d3d12_device
 
     IUnknown *parent;
     LUID adapter_luid;
+
+    HRESULT removed_reason;
 };
 
 HRESULT d3d12_device_create(struct vkd3d_instance *instance,
         const struct vkd3d_device_create_info *create_info, struct d3d12_device **device) DECLSPEC_HIDDEN;
+void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
+        const char *message, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN;
 struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) DECLSPEC_HIDDEN;
 
 HRESULT vkd3d_create_buffer(struct d3d12_device *device,
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 7dfee87..ea7d24d 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -4598,7 +4598,7 @@ static void test_device_removed_reason(void)
     exec_command_list(queue, command_list);
 
     hr = ID3D12Device_GetDeviceRemovedReason(device);
-    todo(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
 
     hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc,
             &IID_ID3D12CommandQueue, (void **)&tmp_queue);
@@ -4607,7 +4607,7 @@ static void test_device_removed_reason(void)
         ID3D12CommandQueue_Release(tmp_queue);
 
     hr = ID3D12Device_GetDeviceRemovedReason(device);
-    todo(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+    ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
 
     ID3D12GraphicsCommandList_Release(command_list);
     ID3D12CommandAllocator_Release(command_allocator);




More information about the wine-cvs mailing list