[PATCH 3/7] dxgi: Implement d3d12_swapchain_ResizeTarget().
Henri Verbeet
hverbeet at codeweavers.com
Wed Jul 31 15:29:47 CDT 2019
From: Conor McCarthy <cmccarthy at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 167238.
dlls/dxgi/device.c | 44 ++-------------------------
dlls/dxgi/dxgi_private.h | 5 ++--
dlls/dxgi/swapchain.c | 75 +++++++++++++++++++++++++++++++----------------
dlls/dxgi/utils.c | 53 +++++++++++++++++++++++++++++++--
dlls/wined3d/swapchain.c | 23 +++++++++++++++
dlls/wined3d/wined3d.spec | 2 ++
include/wine/wined3d.h | 3 ++
7 files changed, 133 insertions(+), 72 deletions(-)
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);
--
2.11.0
More information about the wine-devel
mailing list