static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface)
{
struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
- ULONG refcount = InterlockedDecrement(&swapchain->refcount);
+ ULONG refcount;
+ if (!swapchain->refcount)
+ {
+ WARN("Swapchain does not have any references.\n");
+ return 0;
+ }
+
+ refcount = InterlockedDecrement(&swapchain->refcount);
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount)
const RGNDATA *dirty_region, DWORD flags)
{
struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(swapchain->parent_device);
HRESULT hr;
TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
dst_window_override, dirty_region, flags);
+ if (device->device_state != D3D9_DEVICE_STATE_OK)
+ return device->d3d_parent->extended ? S_PRESENT_OCCLUDED : 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, dirty_region, flags);
+ hr = wined3d_swapchain_present(swapchain->wined3d_swapchain,
+ src_rect, dst_rect, dst_window_override, flags);
wined3d_mutex_unlock();
return hr;
TRACE("iface %p, surface %p.\n", iface, surface);
wined3d_mutex_lock();
- hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_surface);
+ hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_texture, dst->sub_resource_idx);
wined3d_mutex_unlock();
return hr;
UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
{
struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
- struct wined3d_surface *wined3d_surface = NULL;
+ struct wined3d_texture *wined3d_texture;
struct d3d9_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_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain,
- backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type)))
+ if ((wined3d_texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, backbuffer_idx)))
{
- surface_impl = wined3d_surface_get_parent(wined3d_surface);
- *backbuffer = &surface_impl->IDirect3DSurface9_iface;
- IDirect3DSurface9_AddRef(*backbuffer);
+ surface_impl = wined3d_texture_get_sub_resource_parent(wined3d_texture, 0);
+ *backbuffer = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*backbuffer);
}
else
{
+ /* Do not set *backbuffer = NULL, see tests/device.c, test_swapchain(). */
hr = D3DERR_INVALIDCALL;
}
wined3d_mutex_unlock();