On 2019/6/26 20:07, Conor McCarthy wrote:
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
dlls/dxgi/swapchain.c | 144 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index b7a3cc0..457d187 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1085,8 +1085,12 @@ struct d3d12_swapchain IWineDXGIFactory *factory;
HWND window;
- IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc;
- struct wined3d_window_state window_state;
- DXGI_MODE_DESC original_mode;
- RECT orig_window_rect;
};
static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -2178,17 +2182,122 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBuffer(IDXGISwapChain3 *ifac static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreenState(IDXGISwapChain3 *iface, BOOL fullscreen, IDXGIOutput *target) {
- FIXME("iface %p, fullscreen %#x, target %p stub!\n", iface, fullscreen, target);
- struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
- DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc = &swapchain->fullscreen_desc;
- const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc = &swapchain->desc;
- HWND window = swapchain->window;
- DXGI_MODE_DESC actual_mode;
- HRESULT hr = S_OK;
- return E_NOTIMPL;
- TRACE("iface %p, fullscreen %#x, target %p.\n", iface, fullscreen, target);
- if (!fullscreen && target)
- {
WARN("Invalid call.\n");
return DXGI_ERROR_INVALID_CALL;
- }
- if (target)
- {
IDXGIOutput_AddRef(target);
- }
- else if (FAILED(hr = IDXGISwapChain3_GetContainingOutput(iface, &target)))
- {
WARN("Failed to get default target output for swapchain, hr %#x.\n", hr);
return hr;
- }
- wined3d_mutex_lock();
- if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH)
- {
if (fullscreen)
{
actual_mode.Width = swapchain_desc->Width;
actual_mode.Height = swapchain_desc->Height;
actual_mode.RefreshRate = fullscreen_desc->RefreshRate;
actual_mode.Format = swapchain_desc->Format;
actual_mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
}
else
{
actual_mode = swapchain->original_mode;
}
if (FAILED(hr = dxgi_output_set_display_mode(target, &actual_mode)))
goto release;
- }
- else
- {
if (FAILED(hr = dxgi_output_get_display_mode(target, &actual_mode)))
{
ERR("Failed to get display mode, hr %#x.\n", hr);
hr = DXGI_ERROR_INVALID_CALL;
goto release;
}
- }
- if (fullscreen)
- {
if (fullscreen_desc->Windowed)
{
if (FAILED(hr = wined3d_window_setup_fullscreen(&swapchain->window_state,
window, actual_mode.Width, actual_mode.Height)))
goto release;
}
else
{
/* Fullscreen -> fullscreen mode change */
MoveWindow(window, 0, 0, actual_mode.Width, actual_mode.Height, TRUE);
ShowWindow(window, SW_SHOW);
}
- }
- else if (!fullscreen_desc->Windowed)
- {
/* Fullscreen -> windowed switch */
wined3d_window_restore_from_fullscreen(&swapchain->window_state, window, &swapchain->orig_window_rect);
- }
- wined3d_mutex_unlock();
- fullscreen_desc->Windowed = !fullscreen;
- if (!fullscreen)
- {
IDXGIOutput_Release(target);
target = NULL;
- }
- if (swapchain->target)
IDXGIOutput_Release(swapchain->target);
- swapchain->target = target;
- return S_OK;
+release:
- wined3d_mutex_unlock();
- IDXGIOutput_Release(target);
- return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
}
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenState(IDXGISwapChain3 *iface, BOOL *fullscreen, IDXGIOutput **target) {
- FIXME("iface %p, fullscreen %p, target %p stub!\n", iface, fullscreen, target);
- struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
- return E_NOTIMPL;
- TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target);
- if (fullscreen)
*fullscreen = !swapchain->fullscreen_desc.Windowed;
- if (target)
- {
*target = swapchain->target;
if (*target)
IDXGIOutput_AddRef(*target);
- }
- return S_OK;
}
Hi Conor,
My dxgi patch yesterday have some todo_wines for d3d12 Set/GetFullscreenState. Now they should start succeeding and you need to remove those todo_wines.
Thanks, Zhiyi
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetDesc(IDXGISwapChain3 *iface, DXGI_SWAP_CHAIN_DESC *desc) @@ -2306,6 +2415,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh
TRACE("iface %p, output %p.\n", iface, output);
if (swapchain->target)
{
IDXGIOutput_AddRef(*output = swapchain->target);
return S_OK;
}
device_parent = vkd3d_get_device_parent(swapchain->device);
if (SUCCEEDED(hr = IUnknown_QueryInterface(device_parent, &IID_IDXGIAdapter, (void **)&adapter)))
@@ -2752,6 +2867,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->refcount = 1;
swapchain->window = window;
- GetWindowRect(window, &swapchain->orig_window_rect); swapchain->desc = *swapchain_desc; swapchain->fullscreen_desc = *fullscreen_desc;
@@ -2865,6 +2981,7 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu DXGI_SWAP_CHAIN_FULLSCREEN_DESC default_fullscreen_desc; struct d3d12_swapchain *object; ID3D12Device *device;
IDXGIOutput *output; HRESULT hr;
if (swapchain_desc->Format == DXGI_FORMAT_UNKNOWN)
@@ -2895,11 +3012,30 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu return hr; }
if (FAILED(hr = d3d12_swapchain_GetContainingOutput(&object->IDXGISwapChain3_iface, &output)))
{
ERR("Failed to get containing output, hr %#x.\n", hr);
goto cleanup;
}
hr = dxgi_output_get_display_mode(output, &object->original_mode);
IDXGIOutput_Release(output);
if (FAILED(hr))
{
ERR("Failed to get current display mode, hr %#x.\n", hr);
goto cleanup;
}
TRACE("Created swapchain %p.\n", object);
*swapchain = (IDXGISwapChain1 *)&object->IDXGISwapChain3_iface;
return S_OK;
+cleanup:
- d3d12_swapchain_destroy(object);
- heap_free(object);
- return hr;
}
#else