From e902cd119f7b5c60f57cd1e232c2c0c37e36fe15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Wed, 24 May 2006 11:34:30 +0200 Subject: [PATCH] wined3d: Swapchain and back buffer corrections + tests. --- dlls/d3d9/swapchain.c | 8 ++ dlls/d3d9/tests/device.c | 146 +++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 145 ++++++++---------------------- dlls/wined3d/swapchain.c | 9 +- dlls/wined3d/wined3d_private.h | 8 +- include/wine/wined3d_interface.h | 2 - 6 files changed, 196 insertions(+), 122 deletions(-) diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index ac3b17c632e..5f60cba203f 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -89,6 +89,7 @@ HRESULT WINAPI IDirect3DSwapChain9Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN9 iface, IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer); IWineD3DSurface_Release(mySurface); } + /* Do not touch the **ppBackBuffer pointer otherwise! (see device test) */ return hrc; } @@ -172,6 +173,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateAdditionalSwapChain(LPDIRECT3DDEVICE object->ref = 1; object->lpVtbl = &Direct3DSwapChain9_Vtbl; + /* The back buffer count is set to one if it's 0 */ + if(pPresentationParameters->BackBufferCount == 0) { + pPresentationParameters->BackBufferCount = 1; + } + /* Allocate an associated WineD3DDevice object */ localParameters.BackBufferWidth = &pPresentationParameters->BackBufferWidth; localParameters.BackBufferHeight = &pPresentationParameters->BackBufferHeight; @@ -214,6 +220,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9 iface, UINT if (hrc == D3D_OK && NULL != swapchain) { IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)pSwapChain); IWineD3DSwapChain_Release(swapchain); + } else { + *pSwapChain = NULL; } return hrc; } diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 9267ce96788..af938c5cd2e 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Vitaliy Margolen + * Copyright (C) 2006 Stefan Dösinger(For CodeWeavers) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +38,150 @@ static int get_refcount(IUnknown *object) trace("%s failed: %s\n", c, DXGetErrorString9(r)); \ } +void test_swapchain(void) +{ + HRESULT hr; + HWND hwnd = NULL; + IDirect3D9 *pD3d = NULL; + IDirect3DDevice9 *pDevice = NULL; + IDirect3DSwapChain9 *swapchain0 = NULL; + IDirect3DSwapChain9 *swapchain1 = NULL; + IDirect3DSwapChain9 *swapchain2 = NULL; + IDirect3DSwapChain9 *swapchain3 = NULL; + IDirect3DSwapChain9 *swapchainX = NULL; + IDirect3DSurface9 *backbuffer = NULL; + D3DPRESENT_PARAMETERS d3dpp; + D3DDISPLAYMODE d3ddm; + + pD3d = pDirect3DCreate9( D3D_SDK_VERSION ); + ok(pD3d != NULL, "Failed to create IDirect3D9 object\n"); + hwnd = CreateWindow( "static", "d3d9_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL ); + ok(hwnd != NULL, "Failed to create window\n"); + if (!pD3d || !hwnd) goto cleanup; + + IDirect3D9_GetAdapterDisplayMode( pD3d, D3DADAPTER_DEFAULT, &d3ddm ); + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.BackBufferCount = 0; + + hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice ); + ok(SUCCEEDED(hr), "Failed to create IDirect3D9Device (%s)\n", DXGetErrorString9(hr)); + if (FAILED(hr)) goto cleanup; + + /* Check if the back buffer count was modified */ + ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount); + + /* Get the implicit swapchain */ + hr = IDirect3DDevice9_GetSwapChain(pDevice, 0, &swapchain0); + ok(SUCCEEDED(hr), "Failed to get the impicit swapchain (%s)\n", DXGetErrorString9(hr)); + if(swapchain0) IDirect3DSwapChain9_Release(swapchain0); + + /* Check if there is a back buffer */ + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer != NULL, "The back buffer is NULL\n"); + if(backbuffer) IDirect3DSurface9_Release(backbuffer); + + /* Try to get a nonexistant swapchain */ + hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX); + ok(hr == D3DERR_INVALIDCALL, "GetSwapChain on an non-existant swapchain returned (%s)\n", DXGetErrorString9(hr)); + ok(swapchainX == NULL, "Swapchain 1 is %p\n", swapchainX); + if(swapchainX) IDirect3DSwapChain9_Release(swapchainX); + + /* Create a bunch of swapchains */ + d3dpp.BackBufferCount = 0; + hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain1); + ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr)); + ok(d3dpp.BackBufferCount == 1, "The back buffer count in the presentparams struct is %d\n", d3dpp.BackBufferCount); + + d3dpp.BackBufferCount = 1; + hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2); + ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr)); + + /* Unsupported by wine for now */ + d3dpp.BackBufferCount = 2; + hr = IDirect3DDevice9_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3); + todo_wine ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr)); + if(SUCCEEDED(hr)) { + /* Swapchain 3, created with backbuffercount 2 */ + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 0, 0, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the 1st back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 1, 0, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the 2nd back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 2, 0, &backbuffer); + ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString9(hr)); + ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain3, 3, 0, &backbuffer); + ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + } + + /* Check the back buffers of the swapchains */ + /* Swapchain 1, created with backbuffercount 0 */ + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer != NULL, "The back buffer is NULL (%s)\n", DXGetErrorString9(hr)); + if(backbuffer) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain1, 1, 0, &backbuffer); + ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + /* Swapchain 2 - created with backbuffercount 1 */ + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 0, 0, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer != NULL && backbuffer != (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 1, 0, &backbuffer); + ok(hr == D3DERR_INVALIDCALL, "GetBackBuffer returned %s\n", DXGetErrorString9(hr)); + ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + backbuffer = (void *) 0xdeadbeef; + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain2, 2, 0, &backbuffer); + ok(FAILED(hr), "Failed to get the back buffer (%s)\n", DXGetErrorString9(hr)); + ok(backbuffer == (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer); + if(backbuffer && backbuffer != (void *) 0xdeadbeef) IDirect3DSurface9_Release(backbuffer); + + /* Try getSwapChain on a manually created swapchain + * it should fail, apparently GetSwapChain only returns implicit swapchains + */ + swapchainX = (void *) 0xdeadbeef; + hr = IDirect3DDevice9_GetSwapChain(pDevice, 1, &swapchainX); + ok(hr == D3DERR_INVALIDCALL, "Failed to get the secound swapchain (%s)\n", DXGetErrorString9(hr)); + ok(swapchainX == NULL, "The swapchain pointer is %p\n", swapchainX); + if(swapchainX && swapchainX != (void *) 0xdeadbeef ) IDirect3DSwapChain9_Release(swapchainX); + + cleanup: + if(swapchain1) IDirect3DSwapChain9_Release(swapchain1); + if(swapchain2) IDirect3DSwapChain9_Release(swapchain2); + if(swapchain3) IDirect3DSwapChain9_Release(swapchain3); + if(pDevice) IDirect3DDevice9_Release(pDevice); + if(pD3d) IDirect3DDevice9_Release(pD3d); + DestroyWindow( hwnd ); +} + void test_refcount(void) { HRESULT hr; @@ -195,6 +340,7 @@ START_TEST(device) pDirect3DCreate9 = (void *)GetProcAddress( d3d9_handle, "Direct3DCreate9" ); if (pDirect3DCreate9) { + test_swapchain(); test_refcount(); } } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 4d5b6b604d0..5ac899c7b45 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1141,6 +1141,12 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac * or does the swap chain notify the device of its destruction. *******************************/ + /* Check the params */ + if(*pPresentationParameters->BackBufferCount > 1) { + ERR("App requested %d back buffers, this is not supported for now\n", *pPresentationParameters->BackBufferCount); + return WINED3DERR_INVALIDCALL; + } + D3DCREATEOBJECTINSTANCE(object, SwapChain) /********************* @@ -1361,6 +1367,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac /********************* * Create the back, front and stencil buffers *******************/ + TRACE("calling rendertarget CB\n"); hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent, object->presentParms.BackBufferWidth, @@ -1477,22 +1484,13 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);"); /* switch back to the original context (if there was one)*/ - if (This->swapchains != NULL) { + if (This->swapchains) { /** TODO: restore the context and drawable **/ glXMakeCurrent(object->display, oldDrawable, oldContext); } LEAVE_GL(); - { /* Finally add the swapchain to the end of the devices' swapchain list */ - SwapChainList **nextSwapchain; - nextSwapchain = &This->swapchains; - while (*nextSwapchain != NULL) { - nextSwapchain = &((*nextSwapchain)->next); - } - (*nextSwapchain) = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->swapchains)); - (*nextSwapchain)->swapchain = (IWineD3DSwapChain *)object; - } TRACE("Set swapchain to %p\n", object); } else { /* something went wrong so clean up */ IUnknown* bufferParent; @@ -1530,47 +1528,25 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* ifac /** NOTE: These are ahead of the other getters and setters to save using a forward declaration **/ UINT WINAPI IWineD3DDeviceImpl_GetNumberOfSwapChains(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - unsigned int numberOfSwapChains = 0; - SwapChainList *swapchain; + TRACE("(%p)\n", This); - swapchain = This->swapchains; - /* itterate through the list to get a count */ - while (swapchain != NULL) { - swapchain = swapchain->next; - numberOfSwapChains++; - } - - TRACE("(%p) returning %d\n", This, numberOfSwapChains); - return numberOfSwapChains; + return This->NumberOfSwapChains; } HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, UINT iSwapChain, IWineD3DSwapChain **pSwapChain) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - SwapChainList *swapchain; - int i = iSwapChain; - HRESULT hr = WINED3DERR_INVALIDCALL; - swapchain = This->swapchains; TRACE("(%p) : swapchain %d\n", This, iSwapChain); - - TRACE("(%p) Finding swapchain %d\n", This, iSwapChain); - while (i > 0 && swapchain != NULL) { - swapchain = swapchain->next; - --i; - } - - if (i > 0) { - FIXME("(%p) Unable to find swapchain %d\n", This, iSwapChain); - *pSwapChain = NULL; - } else if (swapchain != NULL) { - /** TODO: move off to a linkesList implementation **/ - *pSwapChain = swapchain->swapchain; + if(iSwapChain < This->NumberOfSwapChains) { + *pSwapChain = This->swapchains[iSwapChain]; IWineD3DSwapChain_AddRef(*pSwapChain); - hr = WINED3D_OK; + TRACE("(%p) returning %p\n", This, *pSwapChain); + return WINED3D_OK; + } else { + TRACE("Swapchain out of range\n"); + *pSwapChain = NULL; + return WINED3DERR_INVALIDCALL; } - - TRACE("(%p) returning %p\n", This, *pSwapChain); - return hr; } /***** @@ -1705,6 +1681,15 @@ HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPRESENT_P return WINED3DERR_INVALIDCALL; } + This->NumberOfSwapChains = 1; + This->swapchains = HeapAlloc(GetProcessHeap(), 0, This->NumberOfSwapChains * sizeof(IWineD3DSwapChain *)); + if(!This->swapchains) { + ERR("Out of memory!\n"); + IWineD3DSwapChain_Release( (IWineD3DSwapChain *) swapchain); + return E_OUTOFMEMORY; + } + This->swapchains[0] = (IWineD3DSwapChain *) swapchain; + if(swapchain->backBuffer) { TRACE("Setting rendertarget to %p\n", swapchain->backBuffer); This->renderTarget = swapchain->backBuffer; @@ -1767,7 +1752,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface) { int texstage; IUnknown* stencilBufferParent; IUnknown* swapChainParent; - SwapChainList *nextSwapchain; + uint i; TRACE("(%p)\n", This); if(!This->d3d_initialized) return WINED3DERR_INVALIDCALL; @@ -1776,30 +1761,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface) { IWineD3DDevice_SetTexture(iface, texstage, NULL); } - /* NOTE: You must release the parent if the object was created via a callback - ** ***************************/ - /* Release all of the swapchains, except the implicit swapchain */ - - /* NOTE: Don't release swapchain 0 here, it's 'special' */ - TRACE("Finding implicit swapchain\n"); - nextSwapchain = This->swapchains; - if (nextSwapchain != NULL) { - nextSwapchain = nextSwapchain->next; - } else { - WARN("Expected to find the implicit swapchain\n"); - } - - TRACE("Releasing swapchains. nextSwapchain = %p\n", nextSwapchain); - /* release all the other swapchains */ - while (nextSwapchain != NULL) { - SwapChainList *prevSwapchain = nextSwapchain; - nextSwapchain = nextSwapchain->next; - TRACE("Releasing swapchain %p\n", prevSwapchain->swapchain); - IWineD3DSwapChain_Release(prevSwapchain->swapchain); - /* NOTE: no need to free the list element, it will be done by the release callback - HeapFree(GetProcessHeap(), 0, prevSwapchain); */ - } - /* Release the buffers (with sanity checks)*/ + /* Release the buffers (with sanity checks)*/ TRACE("Releasing the depth stencil buffer at %p\n", This->stencilBufferTarget); if(This->stencilBufferTarget != NULL && (IWineD3DSurface_Release(This->stencilBufferTarget) >0)){ if(This->depthStencilBuffer != This->stencilBufferTarget) @@ -1821,16 +1783,19 @@ HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface) { } This->depthStencilBuffer = NULL; - TRACE("Releasing the implicit swapchain\n"); - if (This->swapchains != NULL) { + for(i=0; i < This->NumberOfSwapChains; i++) { + TRACE("Releasing the implicit swapchain %d\n", i); /* Swapchain 0 is special because it's created in startup with a hanging parent, so we have to release its parent now */ - IWineD3DSwapChain_GetParent(This->swapchains->swapchain, &swapChainParent); + IWineD3DSwapChain_GetParent(This->swapchains[i], &swapChainParent); IUnknown_Release(swapChainParent); /* once for the get parent */ if (IUnknown_Release(swapChainParent) > 0) { /* the second time for when it was created */ FIXME("(%p) Something's still holding the implicit swapchain\n", This); } } + + HeapFree(GetProcessHeap(), 0, This->swapchains); This->swapchains = NULL; + This->NumberOfSwapChains = 0; This->d3d_initialized = FALSE; return WINED3D_OK; @@ -7395,45 +7360,6 @@ void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IWineD3DR } - -/** This function is to be called by the swapchain when it is released and it's ref = 0 - *****************************************************/ -void WINAPI IWineD3DDeviceImpl_SwapChainReleased(IWineD3DDevice *iface, IWineD3DSwapChain *swapChain){ - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; - SwapChainList **nextSwapchain; - nextSwapchain = &This->swapchains; - - /* Check to see if the swapchian is being used as the render target */ - if (This->renderTarget != NULL) { - IWineD3DSurface *swapchainBackBuffer; - - IWineD3DSwapChain_GetBackBuffer(swapChain, 0 ,( D3DBACKBUFFER_TYPE) 0, &swapchainBackBuffer); - if (This->renderTarget == swapchainBackBuffer) { - /* Don't know what to do, so warn and carry on as usual (which in this case leaves the renderterget in limbo) */ - FIXME("Atempting to release a swapchain that is currently beuing used as a render target, behaviour is undefined\n"); - } - } - - /* Go through the swapchain list and try to find the swapchain being released */ - while(*nextSwapchain != NULL && (*nextSwapchain)->swapchain != swapChain) { - nextSwapchain = &(*nextSwapchain)->next; - } - - /* Check to see if we found the swapchain */ - if (NULL != *nextSwapchain) { - /* We found the swapchain so remove it from the list */ - TRACE("(%p) releasing swapchain(%p)\n", iface, swapChain); - HeapFree(GetProcessHeap(), 0 , *nextSwapchain); - *nextSwapchain = (*nextSwapchain)->next; - } else { - /* We didn't find the swapchain on the list, this can only heppen because of a programming error in wined3d */ - FIXME("(%p) Attempting to release a swapchain (%p) that hasn't been stored\n", iface, swapChain); - } - - TRACE("swapchain (%p) released\n", swapChain); - return; -} - /********************************************************** * IWineD3DDevice VTbl follows **********************************************************/ @@ -7588,7 +7514,6 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = /*** Internal use IWineD3DDevice methods ***/ IWineD3DDeviceImpl_SetupTextureStates, /*** object tracking ***/ - IWineD3DDeviceImpl_SwapChainReleased, IWineD3DDeviceImpl_ResourceReleased }; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 64a567b9c2c..ba5b5cbe420 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -90,9 +90,6 @@ ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) { if (refCount == 0) { IUnknown* bufferParent; - /* tell the device that we've been released */ - IWineD3DDevice_SwapChainReleased((IWineD3DDevice *)This->wineD3DDevice, iface); - /* release the ref to the front and back buffer parents */ if(This->frontBuffer) { IWineD3DSurface_SetContainer(This->frontBuffer, 0); @@ -377,7 +374,11 @@ HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UIN TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer); if (iBackBuffer > This->presentParms.BackBufferCount - 1) { - FIXME("Only one backBuffer currently supported\n"); + TRACE("Back buffer count out of range\n"); + /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here + * in wined3d to avoid problems in other libs + */ + *ppBackBuffer = NULL; return WINED3DERR_INVALIDCALL; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7f8df4c996a..a0a44144b23 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -444,11 +444,6 @@ typedef struct IWineD3DImpl extern const IWineD3DVtbl IWineD3D_Vtbl; -typedef struct SwapChainList { - IWineD3DSwapChain *swapchain; - struct SwapChainList *next; -} SwapChainList; - /** Hacked out start of a context manager!! **/ typedef struct glContext { int Width; @@ -529,7 +524,8 @@ typedef struct IWineD3DDeviceImpl UINT adapterNo; D3DDEVTYPE devType; - SwapChainList *swapchains; + IWineD3DSwapChain **swapchains; + uint NumberOfSwapChains; ResourceList *resources; /* a linked list to track resources created by the device */ diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 9a1d6aa7ba3..944e7642d66 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -504,7 +504,6 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,struct IWineD3DSurface* pSurface) PURE; /*** Internal use IWineD3Device methods ***/ STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD Flags); - STDMETHOD_(void, SwapChainReleased)(THIS_ struct IWineD3DSwapChain *swapChain); /*** object tracking ***/ STDMETHOD_(void, ResourceReleased)(THIS_ struct IWineD3DResource *resource); }; @@ -652,7 +651,6 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) #define IWineD3DDevice_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b) #define IWineD3DDevice_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b) #define IWineD3DDevice_SetupTextureStates(p,a,b) (p)->lpVtbl->SetupTextureStates(p,a,b) -#define IWineD3DDevice_SwapChainReleased(p,a) (p)->lpVtbl->SwapChainReleased(p,a) #define IWineD3DDevice_ResourceReleased(p,a) (p)->lpVtbl->ResourceReleased(p,a) #endif