From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 122 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index e0465b90ed0..5173a474195 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -7581,6 +7581,126 @@ done: ok(!refcount, "Device has %lu references left.\n", refcount); }
+static void test_composition_swapchain(IUnknown *device, BOOL is_d3d12) +{ + DXGI_SWAP_CHAIN_DESC1 swapchain_desc; + IDXGISwapChain1 *swapchain1; + IDXGIFactory2 *factory2; + IDXGIFactory *factory; + DXGI_MODE_DESC mode; + IDXGIOutput *output; + IUnknown *unknown; + ULONG ref_count; + HWND window; + HRESULT hr; + + get_factory(device, is_d3d12, &factory); + + hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory2, (void**)&factory2); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + win_skip("IDXGIFactory2 not available.\n"); + return; + } + + swapchain_desc.Width = 640; + swapchain_desc.Height = 480; + swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapchain_desc.Stereo = FALSE; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 2; + swapchain_desc.Scaling = DXGI_SCALING_STRETCH; + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swapchain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + swapchain_desc.Flags = 0; + + /* Parameter checks */ + /* NULL device */ + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, NULL, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + + /* NULL swapchain description */ + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, NULL, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + + /* Invalid width */ + swapchain_desc.Width = 0; + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + swapchain_desc.Width = 640; + + /* Invalid height */ + swapchain_desc.Height = 0; + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + swapchain_desc.Height = 480; + + /* Invalid scaling */ + swapchain_desc.Scaling = DXGI_SCALING_NONE; + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + swapchain_desc.Scaling = DXGI_SCALING_STRETCH; + + /* Invalid swap effect */ + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + + /* NULL swapchain pointer */ + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, NULL); + todo_wine + ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, + "Got unexpected hr %#lx.\n", hr); + + /* Normal call*/ + hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); + todo_wine + ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + goto done; + + /* Invalid method calls for composition swapchains */ + hr = IDXGISwapChain1_SetFullscreenState(swapchain1, TRUE, NULL); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + + memset(&mode, 0, sizeof(mode)); + mode.Width = 1024; + mode.Height = 768; + hr = IDXGISwapChain1_ResizeTarget(swapchain1, &mode); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + + hr = IDXGISwapChain1_GetContainingOutput(swapchain1, &output); + ok(hr == DXGI_ERROR_UNSUPPORTED, "Got unexpected hr %#lx.\n", hr); + + hr = IDXGISwapChain1_GetHwnd(swapchain1, &window); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + + hr = IDXGISwapChain1_GetCoreWindow(swapchain1, &IID_IUnknown, (void **)&unknown); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#lx.\n", hr); + + IDXGISwapChain1_Release(swapchain1); + +done: + ref_count = IDXGIFactory2_Release(factory2); + ok(ref_count == !is_d3d12, "Factory has %lu references left.\n", ref_count); +} + static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12)) { IDXGIDevice *device; @@ -7705,6 +7825,7 @@ START_TEST(dxgi) run_on_d3d10(test_default_fullscreen_target_output); run_on_d3d10(test_mode_change); run_on_d3d10(test_swapchain_present_count); + run_on_d3d10(test_composition_swapchain);
if (!(d3d12_module = LoadLibraryA("d3d12.dll"))) { @@ -7736,6 +7857,7 @@ START_TEST(dxgi) run_on_d3d12(test_default_fullscreen_target_output); run_on_d3d12(test_mode_change); run_on_d3d12(test_swapchain_present_count); + run_on_d3d12(test_composition_swapchain);
FreeLibrary(d3d12_module); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dxgi/dxgi_private.h | 8 ++++ dlls/dxgi/factory.c | 49 ++++++++++++++++++++-- dlls/dxgi/swapchain.c | 91 ++++++++++++++++++++++++++++++++++++++++ dlls/dxgi/tests/dxgi.c | 8 ---- 4 files changed, 145 insertions(+), 11 deletions(-)
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index dd17e39eca6..e16a3211d2e 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -171,6 +171,12 @@ HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal, struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter(IDXGIAdapter *iface) DECLSPEC_HIDDEN;
/* IDXGISwapChain */ +enum dxgi_swapchain_type +{ + DXGI_SWAPCHAIN_TYPE_HWND, + DXGI_SWAPCHAIN_TYPE_COMPOSITION, +}; + struct d3d11_swapchain { IDXGISwapChain1 IDXGISwapChain1_iface; @@ -181,6 +187,8 @@ struct d3d11_swapchain IWineDXGIDevice *device; IWineDXGIFactory *factory;
+ enum dxgi_swapchain_type type; + HWND window; IDXGIOutput *target; LONG present_count; }; diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c index 8de882b388d..6e07530e7ef 100644 --- a/dlls/dxgi/factory.c +++ b/dlls/dxgi/factory.c @@ -381,10 +381,53 @@ static void STDMETHODCALLTYPE dxgi_factory_UnregisterOcclusionStatus(IWineDXGIFa static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChainForComposition(IWineDXGIFactory *iface, IUnknown *device, const DXGI_SWAP_CHAIN_DESC1 *desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain) { - FIXME("iface %p, device %p, desc %p, output %p, swapchain %p stub!\n", - iface, device, desc, output, swapchain); + IWineDXGISwapChainFactory *swapchain_factory; + ID3D12CommandQueue *command_queue; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, device %p, desc %p,, output %p, swapchain %p.\n", iface, device, desc, output, + swapchain); + + if (!device || !desc || !swapchain) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (desc->Stereo) + { + FIXME("Stereo swapchains are not supported.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + + if (!desc->Width || !desc->Height + || desc->SwapEffect != DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + || desc->Scaling != DXGI_SCALING_STRETCH) + return DXGI_ERROR_INVALID_CALL; + + if (!dxgi_validate_swapchain_desc(desc)) + return DXGI_ERROR_INVALID_CALL; + + if (output) + FIXME("Ignoring output %p.\n", output); + + if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_IWineDXGISwapChainFactory, (void **)&swapchain_factory))) + { + hr = IWineDXGISwapChainFactory_create_swapchain(swapchain_factory, (IDXGIFactory *)iface, + NULL, desc, NULL, output, swapchain); + IWineDXGISwapChainFactory_Release(swapchain_factory); + return hr; + } + + if (SUCCEEDED(IUnknown_QueryInterface(device, &IID_ID3D12CommandQueue, (void **)&command_queue))) + { + hr = d3d12_swapchain_create(iface, command_queue, NULL, desc, NULL, swapchain); + ID3D12CommandQueue_Release(command_queue); + return hr; + } + + ERR("This is not the device we're looking for.\n"); + return DXGI_ERROR_UNSUPPORTED; }
static UINT STDMETHODCALLTYPE dxgi_factory_GetCreationFlags(IWineDXGIFactory *iface) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 9677142e0af..1d321a6bfc1 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -393,6 +393,12 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen return DXGI_ERROR_INVALID_CALL; }
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + if (target) { IDXGIOutput_AddRef(target); @@ -553,6 +559,12 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *i
TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain);
return dxgi_swapchain_resize_target(state, target_mode_desc); @@ -565,6 +577,12 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapCh
TRACE("iface %p, output %p.\n", iface, output);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + if (swapchain->target) { IDXGIOutput_AddRef(*output = swapchain->target); @@ -679,6 +697,12 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetHwnd(IDXGISwapChain1 *iface, return DXGI_ERROR_INVALID_CALL; }
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + *hwnd = d3d11_swapchain_get_hwnd(swapchain); return S_OK; } @@ -686,8 +710,16 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetHwnd(IDXGISwapChain1 *iface, static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetCoreWindow(IDXGISwapChain1 *iface, REFIID iid, void **core_window) { + struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); + FIXME("iface %p, iid %s, core_window %p stub!\n", iface, debugstr_guid(iid), core_window);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + if (core_window) *core_window = NULL;
@@ -799,6 +831,8 @@ static void STDMETHODCALLTYPE d3d11_swapchain_wined3d_object_released(void *pare { struct d3d11_swapchain *swapchain = parent;
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + DestroyWindow(swapchain->window); wined3d_private_store_cleanup(&swapchain->private_store); heap_free(parent); } @@ -866,6 +900,18 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi wined3d_mutex_lock(); wined3d_private_store_init(&swapchain->private_store);
+ if (!desc->device_window) + { + swapchain->type = DXGI_SWAPCHAIN_TYPE_COMPOSITION; + desc->device_window = CreateWindowW(L"static", L"dxgi_dummy_window", WS_POPUP, 0, 0, 1, 1, + 0, 0, 0, 0); + } + else + { + swapchain->type = DXGI_SWAPCHAIN_TYPE_HWND; + } + swapchain->window = desc->device_window; + if (!desc->windowed && (!desc->backbuffer_width || !desc->backbuffer_height)) FIXME("Fullscreen swapchain with back buffer width/height equal to 0 not supported properly.\n");
@@ -1011,6 +1057,7 @@ struct d3d12_swapchain ID3D12Device *device; IWineDXGIFactory *factory;
+ enum dxgi_swapchain_type type; HWND window; IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; @@ -1843,6 +1890,9 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain) if (swapchain->vk_instance) vk_funcs->p_vkDestroySurfaceKHR(swapchain->vk_instance, swapchain->vk_surface, NULL);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + DestroyWindow(swapchain->window); + if (swapchain->target) { WARN("Destroying fullscreen swapchain.\n"); @@ -2183,6 +2233,12 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen return DXGI_ERROR_INVALID_CALL; }
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + if (target) { IDXGIOutput_AddRef(target); @@ -2373,6 +2429,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain4 *i
TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + return dxgi_swapchain_resize_target(swapchain->state, target_mode_desc); }
@@ -2387,6 +2449,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
TRACE("iface %p, output %p.\n", iface, output);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_UNSUPPORTED; + } + if (swapchain->target) { IDXGIOutput_AddRef(*output = swapchain->target); @@ -2487,6 +2555,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetHwnd(IDXGISwapChain4 *iface, return DXGI_ERROR_INVALID_CALL; }
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + *hwnd = swapchain->window; return S_OK; } @@ -2494,8 +2568,16 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetHwnd(IDXGISwapChain4 *iface, static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetCoreWindow(IDXGISwapChain4 *iface, REFIID iid, void **core_window) { + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface); + FIXME("iface %p, iid %s, core_window %p stub!\n", iface, debugstr_guid(iid), core_window);
+ if (swapchain->type == DXGI_SWAPCHAIN_TYPE_COMPOSITION) + { + WARN("Invalid swapchain type.\n"); + return DXGI_ERROR_INVALID_CALL; + } + if (core_window) *core_window = NULL;
@@ -2902,6 +2984,15 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->state_parent.ops = &d3d12_swapchain_state_parent_ops; swapchain->refcount = 1;
+ if (!window) + { + swapchain->type = DXGI_SWAPCHAIN_TYPE_COMPOSITION; + window = CreateWindowW(L"static", L"dxgi_dummy_window", WS_POPUP, 0, 0, 1, 1, 0, 0, 0, 0); + } + else + { + swapchain->type = DXGI_SWAPCHAIN_TYPE_HWND; + } swapchain->window = window; swapchain->desc = *swapchain_desc; swapchain->fullscreen_desc = *fullscreen_desc; diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 5173a474195..c5dec94b459 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -7620,20 +7620,17 @@ static void test_composition_swapchain(IUnknown *device, BOOL is_d3d12) /* Parameter checks */ /* NULL device */ hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, NULL, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr);
/* NULL swapchain description */ hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, NULL, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr);
/* Invalid width */ swapchain_desc.Width = 0; hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); swapchain_desc.Width = 640; @@ -7641,7 +7638,6 @@ static void test_composition_swapchain(IUnknown *device, BOOL is_d3d12) /* Invalid height */ swapchain_desc.Height = 0; hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); swapchain_desc.Height = 480; @@ -7649,7 +7645,6 @@ static void test_composition_swapchain(IUnknown *device, BOOL is_d3d12) /* Invalid scaling */ swapchain_desc.Scaling = DXGI_SCALING_NONE; hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); swapchain_desc.Scaling = DXGI_SCALING_STRETCH; @@ -7657,20 +7652,17 @@ static void test_composition_swapchain(IUnknown *device, BOOL is_d3d12) /* Invalid swap effect */ swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
/* NULL swapchain pointer */ hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, NULL); - todo_wine ok(hr == DXGI_ERROR_INVALID_CALL || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr);
/* Normal call*/ hr = IDXGIFactory2_CreateSwapChainForComposition(factory2, device, &swapchain_desc, NULL, &swapchain1); - todo_wine ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win7 */, "Got unexpected hr %#lx.\n", hr); if (FAILED(hr)) goto done;
I'm not very knowledgeable in general about the subtleties of DXGI, but this looks potentially reasonable. I assume that we'll end up grabbing the window using some internal interface in IDCompositionVisual::SetContent() and then performing a GDI blit?
I'm mildly curious about GetFullscreenState() and GetFullscreenDesc(). I'm also curious if ResizeBuffers() works.
It would probably be good to have a smoke test for presentation as well. I guess we don't have anything in Wine in the way of visual smoke tests, but having a regression test around to make sure that the whole process of presenting doesn't crash seems helpful. Then again, maybe you already have that planned on the dcomp side.
As for specific comments, I think the only thing that I'd mention is that in the tests, I'd just return immediately if we get DXGI_ERROR_UNSUPPORTED rather than checking it on every call.
I'm not very knowledgeable in general about the subtleties of DXGI, but this looks potentially reasonable. I assume that we'll end up grabbing the window using some internal interface in IDCompositionVisual::SetContent() and then performing a GDI blit?
Please see commit_target() in https://gitlab.winehq.org/zhiyi/wine/-/commit/8d72aa74da59ccb1192fb5cb3d7986.... The whole DirectComposition branch is at https://gitlab.winehq.org/zhiyi/wine/-/tree/directcomposition. Basically, it GDI bitblts from the last backbuffer to the window DC. On Windows, it is composited by DWM. We don't have a DWM in Wine and I don't want to write platform specific code for doing composition so blitting to the window DC seems to be good enough.
I'm mildly curious about GetFullscreenState() and GetFullscreenDesc(). I'm also curious if ResizeBuffers() works.
I will add more tests for these.
It would probably be good to have a smoke test for presentation as well. I guess we don't have anything in Wine in the way of visual smoke tests, but having a regression test around to make sure that the whole process of presenting doesn't crash seems helpful. Then again, maybe you already have that planned on the dcomp side.
I only have tests for IDCompositionDevice::Commit(), the implementation of which accesses the swapchain backbuffer and does the blitting. I tried to do a visual test. But on Windows, it's composited by DWM so the window content is actually unchanged so I am unable to test the rendered content.
As for specific comments, I think the only thing that I'd mention is that in the tests, I'd just return immediately if we get DXGI_ERROR_UNSUPPORTED rather than checking it on every call.
I will change it.