diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c index e3dc52b8ed6..5500452653e 100644 --- a/dlls/dxgi/device.c +++ b/dlls/dxgi/device.c @@ -425,48 +425,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_swapchain_factory_create_swapchain(IWineDX TRACE("iface %p, factory %p, window %p, desc %p, fullscreen_desc %p, output %p, swapchain %p.\n", iface, factory, window, desc, fullscreen_desc, output, swapchain); - if (desc->Scaling != DXGI_SCALING_STRETCH) - FIXME("Ignoring scaling %#x.\n", desc->Scaling); - if (desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE) - FIXME("Ignoring alpha mode %#x.\n", desc->AlphaMode); - if (fullscreen_desc && fullscreen_desc->ScanlineOrdering) - FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering); - if (fullscreen_desc && fullscreen_desc->Scaling) - FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc->Scaling); - - switch (desc->SwapEffect) - { - case DXGI_SWAP_EFFECT_DISCARD: - wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; - break; - case DXGI_SWAP_EFFECT_SEQUENTIAL: - wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_SEQUENTIAL; - break; - case DXGI_SWAP_EFFECT_FLIP_DISCARD: - wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_FLIP_DISCARD; - break; - case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: - wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL; - break; - default: - WARN("Invalid swap effect %#x.\n", desc->SwapEffect); - return DXGI_ERROR_INVALID_CALL; - } - - wined3d_desc.backbuffer_width = desc->Width; - wined3d_desc.backbuffer_height = desc->Height; - wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->Format); - wined3d_desc.backbuffer_count = desc->BufferCount; - wined3d_desc.backbuffer_bind_flags = wined3d_bind_flags_from_dxgi_usage(desc->BufferUsage); - wined3d_sample_desc_from_dxgi(&wined3d_desc.multisample_type, - &wined3d_desc.multisample_quality, &desc->SampleDesc); - wined3d_desc.device_window = window; - wined3d_desc.windowed = fullscreen_desc ? fullscreen_desc->Windowed : TRUE; - wined3d_desc.enable_auto_depth_stencil = FALSE; - wined3d_desc.auto_depth_stencil_format = 0; - wined3d_desc.flags = wined3d_swapchain_flags_from_dxgi(desc->Flags); - wined3d_desc.refresh_rate = fullscreen_desc ? dxgi_rational_to_uint(&fullscreen_desc->RefreshRate) : 0; - wined3d_desc.auto_restore_display_mode = TRUE; + if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, desc, fullscreen_desc))) + return hr; if (!(object = heap_alloc_zero(sizeof(*object)))) { diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index a17c4da83c1..5b934498349 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -85,7 +85,6 @@ void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int l DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; -UINT dxgi_rational_to_uint(const DXGI_RATIONAL *rational) DECLSPEC_HIDDEN; void dxgi_sample_desc_from_wined3d(DXGI_SAMPLE_DESC *desc, enum wined3d_multisample_type wined3d_type, unsigned int wined3d_quality) DECLSPEC_HIDDEN; void wined3d_sample_desc_from_dxgi(enum wined3d_multisample_type *wined3d_type, @@ -97,7 +96,9 @@ void wined3d_display_mode_from_dxgi1(struct wined3d_display_mode *wined3d_mode, DXGI_USAGE dxgi_usage_from_wined3d_bind_flags(unsigned int wined3d_bind_flags) DECLSPEC_HIDDEN; unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE usage) DECLSPEC_HIDDEN; unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) DECLSPEC_HIDDEN; -unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) DECLSPEC_HIDDEN; +HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, + HWND window, const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc) DECLSPEC_HIDDEN; HRESULT dxgi_get_private_data(struct wined3d_private_store *store, REFGUID guid, UINT *data_size, void *data) DECLSPEC_HIDDEN; diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 6741b3d489c..728fcacccf6 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -152,6 +152,37 @@ static HRESULT dxgi_get_output_from_window(IDXGIAdapter *adapter, HWND window, I return DXGI_ERROR_NOT_FOUND; } +static HRESULT dxgi_swapchain_resize_target(IDXGISwapChain1 *swapchain, + struct wined3d_swapchain_state *state, const DXGI_MODE_DESC *target_mode_desc) +{ + struct wined3d_display_mode mode; + struct dxgi_output *dxgi_output; + struct dxgi_adapter *adapter; + IDXGIOutput *output; + HRESULT hr; + + if (!target_mode_desc) + { + WARN("Invalid pointer.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(swapchain, &output))) + return hr; + dxgi_output = unsafe_impl_from_IDXGIOutput(output); + adapter = dxgi_output->adapter; + IDXGIOutput_Release(output); + + TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc)); + + if (target_mode_desc->Scaling) + FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling); + + wined3d_display_mode_from_dxgi(&mode, target_mode_desc); + + return wined3d_swapchain_state_resize_target(state, adapter->factory->wined3d, adapter->ordinal, &mode); +} + static HWND d3d11_swapchain_get_hwnd(struct d3d11_swapchain *swapchain) { struct wined3d_swapchain_desc wined3d_desc; @@ -521,35 +552,12 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_ResizeTarget(IDXGISwapChain1 *i { struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain1(iface); struct wined3d_swapchain_state *state; - struct wined3d_display_mode mode; - struct dxgi_output *dxgi_output; - struct dxgi_adapter *adapter; - IDXGIOutput *output; - HRESULT hr; TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc); - if (!target_mode_desc) - { - WARN("Invalid pointer.\n"); - return DXGI_ERROR_INVALID_CALL; - } - - if (FAILED(hr = IDXGISwapChain1_GetContainingOutput(iface, &output))) - return hr; - dxgi_output = unsafe_impl_from_IDXGIOutput(output); - adapter = dxgi_output->adapter; - IDXGIOutput_Release(output); - - TRACE("Mode: %s.\n", debug_dxgi_mode(target_mode_desc)); - - if (target_mode_desc->Scaling) - FIXME("Ignoring scaling %#x.\n", target_mode_desc->Scaling); - state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain); - wined3d_display_mode_from_dxgi(&mode, target_mode_desc); - return wined3d_swapchain_state_resize_target(state, adapter->factory->wined3d, adapter->ordinal, &mode); + return dxgi_swapchain_resize_target(iface, state, target_mode_desc); } static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapChain1 *iface, IDXGIOutput **output) @@ -1030,6 +1038,8 @@ struct d3d12_swapchain LONG refcount; struct wined3d_private_store private_store; + struct wined3d_swapchain_state *state; + VkSwapchainKHR vk_swapchain; VkSurfaceKHR vk_surface; VkFence vk_fence; @@ -1862,6 +1872,8 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain) IWineDXGIFactory_Release(swapchain->factory); close_library(vulkan_module); + + wined3d_swapchain_state_destroy(swapchain->state); } static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface) @@ -2262,9 +2274,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(IDXGISwapChain3 * static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeTarget(IDXGISwapChain3 *iface, const DXGI_MODE_DESC *target_mode_desc) { - FIXME("iface %p, target_mode_desc %p stub!\n", iface, target_mode_desc); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); - return E_NOTIMPL; + TRACE("iface %p, target_mode_desc %p.\n", iface, target_mode_desc); + + return dxgi_swapchain_resize_target((IDXGISwapChain1 *)iface, swapchain->state, target_mode_desc); } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapChain3 *iface, @@ -2701,6 +2715,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc) { const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs; + struct wined3d_swapchain_desc wined3d_desc; VkWin32SurfaceCreateInfoKHR surface_desc; VkPhysicalDevice vk_physical_device; VkFenceCreateInfo fence_desc; @@ -2745,6 +2760,11 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return DXGI_ERROR_UNSUPPORTED; } + if (FAILED(hr = wined3d_swapchain_desc_from_dxgi(&wined3d_desc, window, swapchain_desc, fullscreen_desc))) + return hr; + if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, &swapchain->state))) + return hr; + if (swapchain_desc->BufferUsage && swapchain_desc->BufferUsage != DXGI_USAGE_RENDER_TARGET_OUTPUT) FIXME("Ignoring buffer usage %#x.\n", swapchain_desc->BufferUsage); if (swapchain_desc->Scaling != DXGI_SCALING_STRETCH) @@ -2771,7 +2791,10 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI swapchain->vk_physical_device = vk_physical_device; if (!init_vk_funcs(&swapchain->vk_funcs, vk_instance, vk_device)) + { + wined3d_swapchain_state_destroy(swapchain->state); return E_FAIL; + } wined3d_private_store_init(&swapchain->private_store); diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c index be94bde8478..aece3a6af1c 100644 --- a/dlls/dxgi/utils.c +++ b/dlls/dxgi/utils.c @@ -415,7 +415,7 @@ void dump_feature_levels(const D3D_FEATURE_LEVEL *feature_levels, unsigned int l TRACE(" [%u] = %s.\n", i, debug_feature_level(feature_levels[i])); } -UINT dxgi_rational_to_uint(const DXGI_RATIONAL *rational) +static unsigned int dxgi_rational_to_uint(const DXGI_RATIONAL *rational) { if (rational->Denominator) return rational->Numerator / rational->Denominator; @@ -537,7 +537,7 @@ unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags) return flags; } -unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) +static unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) { unsigned int wined3d_flags = DXGI_WINED3D_SWAPCHAIN_FLAGS; /* WINED3D_SWAPCHAIN_DISCARD_DEPTHSTENCIL? */ @@ -559,6 +559,55 @@ unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags) return wined3d_flags; } +HRESULT wined3d_swapchain_desc_from_dxgi(struct wined3d_swapchain_desc *wined3d_desc, HWND window, + const DXGI_SWAP_CHAIN_DESC1 *dxgi_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *dxgi_fullscreen_desc) +{ + if (dxgi_desc->Scaling != DXGI_SCALING_STRETCH) + FIXME("Ignoring scaling %#x.\n", dxgi_desc->Scaling); + if (dxgi_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE) + FIXME("Ignoring alpha mode %#x.\n", dxgi_desc->AlphaMode); + if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->ScanlineOrdering) + FIXME("Unhandled scanline ordering %#x.\n", dxgi_fullscreen_desc->ScanlineOrdering); + if (dxgi_fullscreen_desc && dxgi_fullscreen_desc->Scaling) + FIXME("Unhandled mode scaling %#x.\n", dxgi_fullscreen_desc->Scaling); + + switch (dxgi_desc->SwapEffect) + { + case DXGI_SWAP_EFFECT_DISCARD: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + break; + case DXGI_SWAP_EFFECT_SEQUENTIAL: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_SEQUENTIAL; + break; + case DXGI_SWAP_EFFECT_FLIP_DISCARD: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_DISCARD; + break; + case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: + wined3d_desc->swap_effect = WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL; + break; + default: + WARN("Invalid swap effect %#x.\n", dxgi_desc->SwapEffect); + return DXGI_ERROR_INVALID_CALL; + } + + wined3d_desc->backbuffer_width = dxgi_desc->Width; + wined3d_desc->backbuffer_height = dxgi_desc->Height; + wined3d_desc->backbuffer_format = wined3dformat_from_dxgi_format(dxgi_desc->Format); + wined3d_desc->backbuffer_count = dxgi_desc->BufferCount; + wined3d_desc->backbuffer_bind_flags = wined3d_bind_flags_from_dxgi_usage(dxgi_desc->BufferUsage); + wined3d_sample_desc_from_dxgi(&wined3d_desc->multisample_type, + &wined3d_desc->multisample_quality, &dxgi_desc->SampleDesc); + wined3d_desc->device_window = window; + wined3d_desc->windowed = dxgi_fullscreen_desc ? dxgi_fullscreen_desc->Windowed : TRUE; + wined3d_desc->enable_auto_depth_stencil = FALSE; + wined3d_desc->auto_depth_stencil_format = 0; + wined3d_desc->flags = wined3d_swapchain_flags_from_dxgi(dxgi_desc->Flags); + wined3d_desc->refresh_rate = dxgi_fullscreen_desc ? dxgi_rational_to_uint(&dxgi_fullscreen_desc->RefreshRate) : 0; + wined3d_desc->auto_restore_display_mode = TRUE; + + return S_OK; +} + HRESULT dxgi_get_private_data(struct wined3d_private_store *store, REFGUID guid, UINT *data_size, void *data) { diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 2669207cfa3..333c3153f68 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1588,3 +1588,26 @@ HRESULT CDECL wined3d_swapchain_set_fullscreen(struct wined3d_swapchain *swapcha return WINED3D_OK; } + +void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state) +{ + heap_free(state); +} + +HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc, + HWND window, struct wined3d_swapchain_state **state) +{ + struct wined3d_swapchain_state *s; + + TRACE("desc %p, window %p, state %p.\n", desc, window, state); + + if (!(s = heap_alloc_zero(sizeof(*s)))) + return E_OUTOFMEMORY; + + s->desc = *desc; + s->device_window = window; + + *state = s; + + return WINED3D_OK; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index bd91e92c683..01e466e0147 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -278,6 +278,8 @@ @ cdecl wined3d_swapchain_set_palette(ptr ptr) @ cdecl wined3d_swapchain_set_window(ptr ptr) +@ cdecl wined3d_swapchain_state_create(ptr ptr ptr) +@ cdecl wined3d_swapchain_state_destroy(ptr) @ cdecl wined3d_swapchain_state_resize_target(ptr ptr long ptr) @ cdecl wined3d_texture_add_dirty_region(ptr long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index bbb58ba8320..bae2cf86184 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2691,6 +2691,9 @@ HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain, struct wined3d_palette *palette); void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window); +HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc, + HWND window, struct wined3d_swapchain_state **state); +void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state); HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state, struct wined3d *wined3d, unsigned int adapter_idx, const struct wined3d_display_mode *mode);