Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/dxgi/swapchain.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 57862ac689b2..a775df2446e5 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -847,6 +847,21 @@ struct dxgi_vk_funcs PFN_vkDestroyFence p_vkDestroyFence; };
+static HRESULT hresult_from_vk_result(VkResult vr) +{ + switch (vr) + { + case VK_SUCCESS: + return S_OK; + case VK_ERROR_OUT_OF_HOST_MEMORY: + case VK_ERROR_OUT_OF_DEVICE_MEMORY: + return E_OUTOFMEMORY; + default: + FIXME("Unhandled VkResult %d.\n", vr); + return E_FAIL; + } +} + struct d3d12_swapchain { IDXGISwapChain3 IDXGISwapChain3_iface; @@ -1187,18 +1202,18 @@ static HRESULT d3d12_swapchain_acquire_next_image(struct d3d12_swapchain *swapch VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer_index)) < 0) { ERR("Failed to acquire next Vulkan image, vr %d.\n", vr); - return E_FAIL; + return hresult_from_vk_result(vr); }
- if ((vr = vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX)) < 0) + if ((vr = vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX)) != VK_SUCCESS) { - ERR("Failed to wait for fences, vr %d.\n", vr); - return E_FAIL; + ERR("Failed to wait for fence, vr %d.\n", vr); + return hresult_from_vk_result(vr); } if ((vr = vk_funcs->p_vkResetFences(vk_device, 1, &vk_fence)) < 0) { ERR("Failed to reset fence, vr %d.\n", vr); - return E_FAIL; + return hresult_from_vk_result(vr); }
return S_OK; @@ -1574,7 +1589,7 @@ static HRESULT select_vk_format(const struct dxgi_vk_funcs *vk_funcs, { WARN("Failed to enumerate supported surface formats, vr %d.\n", vr); heap_free(formats); - return DXGI_ERROR_INVALID_CALL; + return hresult_from_vk_result(vr); }
for (i = 0; i < format_count; ++i) @@ -1612,11 +1627,11 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI VkFenceCreateInfo fence_desc; uint32_t queue_family_index; VkInstance vk_instance; - HRESULT hr = E_FAIL; VkBool32 supported; VkDevice vk_device; VkFormat vk_format; VkResult vr; + HRESULT hr;
swapchain->IDXGISwapChain3_iface.lpVtbl = &d3d12_swapchain_vtbl; swapchain->refcount = 1; @@ -1674,6 +1689,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if ((vr = vk_funcs->p_vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface)) < 0) { WARN("Failed to create Vulkan surface, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; }
@@ -1682,17 +1698,18 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI queue_family_index, vk_surface, &supported)) < 0 || !supported) { FIXME("Queue family does not support presentation, vr %d.\n", vr); + hr = DXGI_ERROR_UNSUPPORTED; goto fail; }
if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, vk_surface, swapchain_desc, &vk_format))) goto fail; - hr = E_FAIL;
if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device, vk_surface, &surface_caps)) < 0) { WARN("Failed to get surface capabilities, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; }
@@ -1701,6 +1718,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI { WARN("Buffer count %u is not supported (%u-%u).\n", swapchain_desc->BufferCount, surface_caps.minImageCount, surface_caps.maxImageCount); + hr = DXGI_ERROR_UNSUPPORTED; goto fail; }
@@ -1718,6 +1736,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)) { FIXME("Unsupported alpha mode.\n"); + hr = DXGI_ERROR_UNSUPPORTED; goto fail; }
@@ -1743,6 +1762,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if ((vr = vk_funcs->p_vkCreateSwapchainKHR(vk_device, &vk_swapchain_desc, NULL, &vk_swapchain)) < 0) { WARN("Failed to create Vulkan swapchain, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; }
@@ -1752,21 +1772,27 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if ((vr = vk_funcs->p_vkCreateFence(vk_device, &fence_desc, NULL, &vk_fence)) < 0) { WARN("Failed to create Vulkan fence, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; }
if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL)) < 0) { WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; } if (image_count != swapchain_desc->BufferCount) FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain_desc->BufferCount); if (image_count > ARRAY_SIZE(vk_images)) + { + hr = E_FAIL; goto fail; + } if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images)) < 0) { WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); goto fail; }
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/dxgi/tests/device.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 8ad4935b1622..e67883e3338f 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -3534,6 +3534,95 @@ static void test_swapchain_present(void) ok(!refcount, "Factory has %u references left.\n", refcount); }
+static void test_swapchain_backbuffer_index(void) +{ + DXGI_SWAP_CHAIN_DESC swapchain_desc; + unsigned int backbuffer_index; + IDXGISwapChain3 *swapchain3; + IDXGISwapChain *swapchain; + IDXGIAdapter *adapter; + IDXGIFactory *factory; + IDXGIDevice *device; + unsigned int i, j; + ULONG refcount; + HRESULT hr; + RECT rect; + BOOL ret; + + static const DXGI_SWAP_EFFECT swap_effects[] = + { + DXGI_SWAP_EFFECT_DISCARD, + DXGI_SWAP_EFFECT_SEQUENTIAL, + DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, + DXGI_SWAP_EFFECT_FLIP_DISCARD, + }; + + if (!(device = create_device(0))) + { + skip("Failed to create device.\n"); + return; + } + + hr = IDXGIDevice_GetAdapter(device, &adapter); + ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); + ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); + IDXGIAdapter_Release(adapter); + + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 60; + swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 4; + swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + ret = GetClientRect(swapchain_desc.OutputWindow, &rect); + ok(ret, "Failed to get client rect.\n"); + swapchain_desc.BufferDesc.Width = rect.right; + swapchain_desc.BufferDesc.Height = rect.bottom; + + for (i = 0; i < ARRAY_SIZE(swap_effects); ++i) + { + swapchain_desc.SwapEffect = swap_effects[i]; + hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); + ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr); + + hr = IDXGISwapChain_QueryInterface(swapchain, &IID_IDXGISwapChain3, (void **)&swapchain3); + if (hr == E_NOINTERFACE) + { + skip("IDXGISwapChain3 is not supported.\n"); + IDXGISwapChain_Release(swapchain); + goto done; + } + + for (j = 0; j < swapchain_desc.BufferCount; ++j) + { + backbuffer_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); + ok(!backbuffer_index, "Got unexpected back buffer index %u.\n", backbuffer_index); + hr = IDXGISwapChain3_Present(swapchain3, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + } + + IDXGISwapChain3_Release(swapchain3); + refcount = IDXGISwapChain_Release(swapchain); + ok(!refcount, "Swapchain has %u references left.\n", refcount); + } + +done: + refcount = IDXGIDevice_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(swapchain_desc.OutputWindow); + refcount = IDXGIFactory_Release(factory); + ok(!refcount, "Factory has %u references left.\n", refcount); +} + static void test_maximum_frame_latency(void) { IDXGIDevice1 *device1; @@ -3852,6 +3941,7 @@ START_TEST(device) test_swapchain_resize(); test_swapchain_parameters(); test_swapchain_present(); + test_swapchain_backbuffer_index(); test_maximum_frame_latency(); test_output_desc(); test_object_wrapping();
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- include/d3d12.idl | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/d3d12.idl b/include/d3d12.idl index e9dd22158036..69220e674cd7 100644 --- a/include/d3d12.idl +++ b/include/d3d12.idl @@ -2171,6 +2171,9 @@ interface ID3D12RootSignatureDeserializer : IUnknown const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *root_signature_desc, ID3DBlob **blob, ID3DBlob **error_blob);
+typedef HRESULT (__stdcall *PFN_D3D12_CREATE_DEVICE)(IUnknown *adapter, + D3D_FEATURE_LEVEL minmum_feature_level, REFIID iid, void **device); + [local] HRESULT __stdcall D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/dxgi/tests/device.c | 172 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 140 insertions(+), 32 deletions(-)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index e67883e3338f..2e68511137a7 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -21,6 +21,7 @@ #include "initguid.h" #include "dxgi1_6.h" #include "d3d11.h" +#include "d3d12.h" #include "wine/heap.h" #include "wine/test.h"
@@ -35,6 +36,8 @@ static DEVMODEW registry_mode; static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory); static HRESULT (WINAPI *pCreateDXGIFactory2)(UINT flags, REFIID iid, void **factory);
+static PFN_D3D12_CREATE_DEVICE pD3D12CreateDevice; + static ULONG get_refcount(IUnknown *iface) { IUnknown_AddRef(iface); @@ -464,6 +467,64 @@ success: return dxgi_device; }
+static ID3D12Device *create_d3d12_device(void) +{ + IDXGIAdapter *adapter; + ID3D12Device *device; + HRESULT hr; + + if (!pD3D12CreateDevice) + return NULL; + + adapter = create_adapter(); + hr = pD3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device); + if (adapter) + IDXGIAdapter_Release(adapter); + if (FAILED(hr)) + return NULL; + + return device; +} + +static ID3D12CommandQueue *create_d3d12_direct_queue(ID3D12Device *device) +{ + D3D12_COMMAND_QUEUE_DESC command_queue_desc; + ID3D12CommandQueue *queue; + HRESULT hr; + + command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; + command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + command_queue_desc.NodeMask = 0; + hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc, + &IID_ID3D12CommandQueue, (void **)&queue); + ok(hr == S_OK, "Failed to create command queue, hr %#x.\n", hr); + return queue; +} + +#define get_factory(a, b, c) get_factory_(__LINE__, a, b, c) +static void get_factory_(unsigned int line, IUnknown *device, BOOL is_d3d12, IDXGIFactory **factory) +{ + IDXGIDevice *dxgi_device; + IDXGIAdapter *adapter; + HRESULT hr; + + if (is_d3d12) + { + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)factory); + ok_(__FILE__, line)(hr == S_OK, "Failed to create factory, hr %#x.\n", hr); + } + else + { + dxgi_device = (IDXGIDevice *)device; + hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter); + ok_(__FILE__, line)(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); + hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)factory); + ok_(__FILE__, line)(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); + IDXGIAdapter_Release(adapter); + } +} + static void test_adapter_desc(void) { DXGI_ADAPTER_DESC1 desc1; @@ -3534,40 +3595,33 @@ static void test_swapchain_present(void) ok(!refcount, "Factory has %u references left.\n", refcount); }
-static void test_swapchain_backbuffer_index(void) +static void test_swapchain_backbuffer_index(IUnknown *device, BOOL is_d3d12) { DXGI_SWAP_CHAIN_DESC swapchain_desc; - unsigned int backbuffer_index; + unsigned int index, expected_index; IDXGISwapChain3 *swapchain3; IDXGISwapChain *swapchain; - IDXGIAdapter *adapter; + HRESULT hr, expected_hr; IDXGIFactory *factory; - IDXGIDevice *device; unsigned int i, j; ULONG refcount; - HRESULT hr; RECT rect; BOOL ret;
- static const DXGI_SWAP_EFFECT swap_effects[] = - { - DXGI_SWAP_EFFECT_DISCARD, - DXGI_SWAP_EFFECT_SEQUENTIAL, - DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, - DXGI_SWAP_EFFECT_FLIP_DISCARD, - }; - - if (!(device = create_device(0))) + static const struct { - skip("Failed to create device.\n"); - return; + DXGI_SWAP_EFFECT swap_effect; + BOOL supported_in_d3d12; } + tests[] = + { + {DXGI_SWAP_EFFECT_DISCARD, FALSE}, + {DXGI_SWAP_EFFECT_SEQUENTIAL, FALSE}, + {DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, TRUE}, + {DXGI_SWAP_EFFECT_FLIP_DISCARD, TRUE}, + };
- hr = IDXGIDevice_GetAdapter(device, &adapter); - ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr); - hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); - ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr); - IDXGIAdapter_Release(adapter); + get_factory(device, is_d3d12, &factory);
swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; swapchain_desc.BufferDesc.RefreshRate.Denominator = 60; @@ -3588,11 +3642,15 @@ static void test_swapchain_backbuffer_index(void) swapchain_desc.BufferDesc.Width = rect.right; swapchain_desc.BufferDesc.Height = rect.bottom;
- for (i = 0; i < ARRAY_SIZE(swap_effects); ++i) + for (i = 0; i < ARRAY_SIZE(tests); ++i) { - swapchain_desc.SwapEffect = swap_effects[i]; + swapchain_desc.SwapEffect = tests[i].swap_effect; + expected_hr = !is_d3d12 || tests[i].supported_in_d3d12 ? S_OK : DXGI_ERROR_INVALID_CALL; hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain); - ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr); + todo_wine_if(is_d3d12 && tests[i].supported_in_d3d12) + ok(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (FAILED(hr)) + continue;
hr = IDXGISwapChain_QueryInterface(swapchain, &IID_IDXGISwapChain3, (void **)&swapchain3); if (hr == E_NOINTERFACE) @@ -3602,10 +3660,11 @@ static void test_swapchain_backbuffer_index(void) goto done; }
- for (j = 0; j < swapchain_desc.BufferCount; ++j) + for (j = 0; j < 2 * swapchain_desc.BufferCount; ++j) { - backbuffer_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); - ok(!backbuffer_index, "Got unexpected back buffer index %u.\n", backbuffer_index); + index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain3); + expected_index = is_d3d12 ? j % swapchain_desc.BufferCount : 0; + ok(index == expected_index, "Got back buffer index %u, expected %u.\n", index, expected_index); hr = IDXGISwapChain3_Present(swapchain3, 0, 0); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); } @@ -3616,11 +3675,9 @@ static void test_swapchain_backbuffer_index(void) }
done: - refcount = IDXGIDevice_Release(device); - ok(!refcount, "Device has %u references left.\n", refcount); DestroyWindow(swapchain_desc.OutputWindow); refcount = IDXGIFactory_Release(factory); - ok(!refcount, "Factory has %u references left.\n", refcount); + ok(refcount == !is_d3d12, "Got unexpected refcount %u.\n", refcount); }
static void test_maximum_frame_latency(void) @@ -3901,10 +3958,49 @@ static void test_object_wrapping(void) ok(!refcount, "Factory has %u references left.\n", refcount); }
+static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12)) +{ + IDXGIDevice *device; + ULONG refcount; + + if (!(device = create_device(0))) + { + skip("Failed to create Direct3D 10 device.\n"); + return; + } + + test_func((IUnknown *)device, FALSE); + + refcount = IDXGIDevice_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + +static void run_on_d3d12(void (*test_func)(IUnknown *device, BOOL is_d3d12)) +{ + ID3D12CommandQueue *queue; + ID3D12Device *device; + ULONG refcount; + + if (!(device = create_d3d12_device())) + { + skip("Failed to create Direct3D 12 device.\n"); + return; + } + + queue = create_d3d12_direct_queue(device); + + test_func((IUnknown *)queue, TRUE); + + refcount = ID3D12CommandQueue_Release(queue); + ok(!refcount, "Command queue has %u references left.\n", refcount); + refcount = ID3D12Device_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); +} + START_TEST(device) { + HMODULE dxgi_module, d3d12_module; unsigned int argc, i; - HMODULE dxgi_module; char **argv;
dxgi_module = GetModuleHandleA("dxgi.dll"); @@ -3941,8 +4037,20 @@ START_TEST(device) test_swapchain_resize(); test_swapchain_parameters(); test_swapchain_present(); - test_swapchain_backbuffer_index(); + run_on_d3d10(test_swapchain_backbuffer_index); test_maximum_frame_latency(); test_output_desc(); test_object_wrapping(); + + if (!(d3d12_module = LoadLibraryA("d3d12.dll"))) + { + skip("Direct3D 12 is not available.\n"); + return; + } + + pD3D12CreateDevice = (void *)GetProcAddress(d3d12_module, "D3D12CreateDevice"); + + run_on_d3d12(test_swapchain_backbuffer_index); + + FreeLibrary(d3d12_module); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d12/tests/Makefile.in | 2 +- dlls/d3d12/tests/d3d12.c | 96 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d12/tests/Makefile.in b/dlls/d3d12/tests/Makefile.in index d055aba108ad..b3406f9e6c11 100644 --- a/dlls/d3d12/tests/Makefile.in +++ b/dlls/d3d12/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = d3d12.dll -IMPORTS = d3d12 +IMPORTS = d3d12 dxgi user32
C_SRCS = \ d3d12.c diff --git a/dlls/d3d12/tests/d3d12.c b/dlls/d3d12/tests/d3d12.c index 27a6b2798265..c8f17f314ce1 100644 --- a/dlls/d3d12/tests/d3d12.c +++ b/dlls/d3d12/tests/d3d12.c @@ -237,7 +237,7 @@ static void create_render_target_(unsigned int line, struct test_context *contex resource_desc.Height = 32; resource_desc.DepthOrArraySize = 1; resource_desc.MipLevels = 1; - resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + resource_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; resource_desc.SampleDesc.Count = 1; resource_desc.SampleDesc.Quality = 0; resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; @@ -443,6 +443,46 @@ static ID3D12Resource *create_readback_buffer_(unsigned int line, ID3D12Device * D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST); }
+static HWND create_window(DWORD style) +{ + return CreateWindowA("static", "d3d12_test", style, 0, 0, 256, 256, NULL, NULL, NULL, NULL); +} + +static IDXGISwapChain3 *create_swapchain(ID3D12CommandQueue *queue, HWND window, + unsigned int width, unsigned int height) +{ + IDXGISwapChain1 *swapchain1; + DXGI_SWAP_CHAIN_DESC1 desc; + IDXGISwapChain3 *swapchain; + IDXGIFactory4 *factory; + HRESULT hr; + + hr = CreateDXGIFactory2(0, &IID_IDXGIFactory4, (void **)&factory); + ok(hr == S_OK, "Failed to create factory, hr %#x.\n", hr); + + desc.Width = width; + desc.Height = height; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.Stereo = FALSE; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.BufferCount = 2; + desc.Scaling = DXGI_SCALING_STRETCH; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + desc.Flags = 0; + hr = IDXGIFactory4_CreateSwapChainForHwnd(factory, (IUnknown *)queue, window, &desc, NULL, NULL, &swapchain1); + ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr); + + IDXGIFactory4_Release(factory); + + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain); + ok(hr == S_OK, "Failed to query IDXGISwapChain3, hr %#x.\n", hr); + IDXGISwapChain1_Release(swapchain1); + return swapchain; +} + struct resource_readback { unsigned int width; @@ -651,8 +691,62 @@ static void test_draw(void) destroy_test_context(&context); }
+static void test_swapchain_draw(void) +{ + static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + ID3D12GraphicsCommandList *command_list; + struct test_context context; + ID3D12Resource *backbuffer; + IDXGISwapChain3 *swapchain; + ID3D12CommandQueue *queue; + unsigned int index; + ULONG refcount; + HWND window; + HRESULT hr; + RECT rect; + BOOL ret; + + if (!init_test_context(&context)) + return; + command_list = context.list; + queue = context.queue; + + window = create_window(0); + ret = GetClientRect(window, &rect); + ok(ret, "Failed to get client rect.\n"); + set_viewport(&context.viewport, 0.0f, 0.0f, rect.right, rect.bottom, 0.0f, 1.0f); + swapchain = create_swapchain(queue, window, rect.right, rect.bottom); + index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); + hr = IDXGISwapChain3_GetBuffer(swapchain, index, &IID_ID3D12Resource, (void **)&backbuffer); + ok(hr == S_OK, "Failed to get swapchain buffer %u, hr %#x.\n", index, hr); + ID3D12Device_CreateRenderTargetView(context.device, backbuffer, NULL, context.rtv); + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature); + ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &rect); + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_sub_resource_state(command_list, backbuffer, 0, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + + check_sub_resource_uint(backbuffer, 0, queue, command_list, 0xff00ff00, 0); + + refcount = ID3D12Resource_Release(backbuffer); + ok(!refcount, "Backbuffer has %u references left.\n", refcount); + refcount = IDXGISwapChain3_Release(swapchain); + ok(!refcount, "Swapchain has %u references left.\n", refcount); + DestroyWindow(window); + destroy_test_context(&context); +} + START_TEST(d3d12) { test_interfaces(); test_draw(); + test_swapchain_draw(); }
Hi,
While running your changed tests on Windows, 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=38891
Your paranoid android.
=== build (build) === Could not determine the test executable's base name
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com