reactos/dll/directx/wine/d3d8/swapchain.c
Joachim Henze 81cffd7658 [D3D8][D3D9][DDRAW][D3DCOMPILER_43][WINED3D] Revert to Wine Staging 3.3
Avoid regressions CORE-14955 "Ddraw fullscreen crashes" and CORE-15652

This brings us back to before guilty commit 0.4.10-dev-55-g
7af3969e9f

and therefore downgrades
dll/directx/wine/
D3D8,D3D9,DDRAW,D3DCOMPILER_43,WINED3D
to WineStaging 3.3.
Also downgrades related header sdk/include/reactos/wine/wined3d.h
and for the first time also media/doc/README.WINE

Same versions of these dlls we had in every ros rls since 0.4.10rls.
Amine Khaldi agreed to perform this revert also for master now.

Purpose of this revert is to fix crashes when Ddraw apps switch
into fullscreen with VBEMP and inbuilt Mesa.
I tested, before:
 DxDiag crashed when switching to fullscreen (CORE-14955),
 Diablo II crashed immediately (CORE-15652),
 Monster-Truck-Madness 2 demo crashed after main menu

Afterwards all of these apps do run.
DXTN does still work after that, even with VBEMP and inbuilt Mesa.

squashed commit of 0.4.13-RC-2-g
67dd70e5ef
and 0.4.13-RC-3-g
9f1e2cd172
2019-10-03 18:38:29 +02:00

215 lines
6.5 KiB
C

/*
* IDirect3DSwapChain8 implementation
*
* Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "d3d8_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
static inline struct d3d8_swapchain *impl_from_IDirect3DSwapChain8(IDirect3DSwapChain8 *iface)
{
return CONTAINING_RECORD(iface, struct d3d8_swapchain, IDirect3DSwapChain8_iface);
}
static HRESULT WINAPI d3d8_swapchain_QueryInterface(IDirect3DSwapChain8 *iface, REFIID riid, void **out)
{
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IDirect3DSwapChain8)
|| IsEqualGUID(riid, &IID_IUnknown))
{
IDirect3DSwapChain8_AddRef(iface);
*out = iface;
return S_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
*out = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI d3d8_swapchain_AddRef(IDirect3DSwapChain8 *iface)
{
struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
ULONG ref = InterlockedIncrement(&swapchain->refcount);
TRACE("%p increasing refcount to %u.\n", iface, ref);
if (ref == 1)
{
if (swapchain->parent_device)
IDirect3DDevice8_AddRef(swapchain->parent_device);
wined3d_mutex_lock();
wined3d_swapchain_incref(swapchain->wined3d_swapchain);
wined3d_mutex_unlock();
}
return ref;
}
static ULONG WINAPI d3d8_swapchain_Release(IDirect3DSwapChain8 *iface)
{
struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
ULONG ref = InterlockedDecrement(&swapchain->refcount);
TRACE("%p decreasing refcount to %u.\n", iface, ref);
if (!ref)
{
IDirect3DDevice8 *parent_device = swapchain->parent_device;
wined3d_mutex_lock();
wined3d_swapchain_decref(swapchain->wined3d_swapchain);
wined3d_mutex_unlock();
if (parent_device)
IDirect3DDevice8_Release(parent_device);
}
return ref;
}
static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChain8 *iface,
const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
const RGNDATA *dirty_region)
{
struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
struct d3d8_device *device = impl_from_IDirect3DDevice8(swapchain->parent_device);
HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);
if (device->device_state != D3D8_DEVICE_STATE_OK)
return D3DERR_DEVICELOST;
if (dirty_region)
FIXME("Ignoring dirty_region %p.\n", dirty_region);
wined3d_mutex_lock();
hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
src_rect, dst_rect, dst_window_override, 0, 0);
wined3d_mutex_unlock();
return hr;
}
static HRESULT WINAPI d3d8_swapchain_GetBackBuffer(IDirect3DSwapChain8 *iface,
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
{
struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
struct wined3d_texture *wined3d_texture;
struct d3d8_surface *surface_impl;
HRESULT hr = D3D_OK;
TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
iface, backbuffer_idx, backbuffer_type, backbuffer);
/* backbuffer_type is ignored by native. */
if (!backbuffer)
{
WARN("The output pointer is NULL, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
wined3d_mutex_lock();
if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx)))
{
surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
*backbuffer = &surface_impl->IDirect3DSurface8_iface;
IDirect3DSurface8_AddRef(*backbuffer);
}
else
{
/* Do not set *backbuffer = NULL, see tests/device.c, test_swapchain(). */
hr = D3DERR_INVALIDCALL;
}
wined3d_mutex_unlock();
return hr;
}
static const IDirect3DSwapChain8Vtbl d3d8_swapchain_vtbl =
{
d3d8_swapchain_QueryInterface,
d3d8_swapchain_AddRef,
d3d8_swapchain_Release,
d3d8_swapchain_Present,
d3d8_swapchain_GetBackBuffer
};
static void STDMETHODCALLTYPE d3d8_swapchain_wined3d_object_released(void *parent)
{
heap_free(parent);
}
static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
{
d3d8_swapchain_wined3d_object_released,
};
static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
struct wined3d_swapchain_desc *desc)
{
HRESULT hr;
swapchain->refcount = 1;
swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl;
wined3d_mutex_lock();
hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
&d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain);
wined3d_mutex_unlock();
if (FAILED(hr))
{
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
return hr;
}
swapchain->parent_device = &device->IDirect3DDevice8_iface;
IDirect3DDevice8_AddRef(swapchain->parent_device);
return D3D_OK;
}
HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
struct d3d8_swapchain **swapchain)
{
struct d3d8_swapchain *object;
HRESULT hr;
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = swapchain_init(object, device, desc)))
{
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
heap_free(object);
return hr;
}
TRACE("Created swapchain %p.\n", object);
*swapchain = object;
return D3D_OK;
}