dxgi: Implement d3d12_swapchain_ResizeTarget().

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Conor McCarthy 2019-08-01 00:59:47 +04:30 committed by Alexandre Julliard
parent 71e8a32479
commit 6d64bfc28b
7 changed files with 133 additions and 72 deletions

View file

@ -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))))
{

View file

@ -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;

View file

@ -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);

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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)

View file

@ -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);