Resend: WineD3D: Support more than one back buffer
stefan at codeweavers.com
stefan at codeweavers.com
Thu Jun 15 05:54:19 CDT 2006
This patch is a resend of the back buffer patch I sent a few days ago. It
updates the d3d8 and d3d9 tests. The todo_wine is removed for the test which
creates more than 2 back buffers.
-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Stefan Dösinger <stefan at codeweavers.com>
Date: Thu Jun 15 12:42:36 2006 +0200
Subject: [PATCH] WineD3D: Allow more than one back buffer
---
dlls/d3d8/tests/device.c | 3 -
dlls/d3d9/tests/device.c | 3 -
dlls/wined3d/device.c | 120 ++++++++++++++++++++++++++++++----------
dlls/wined3d/drawprim.c | 2 -
dlls/wined3d/surface.c | 58 ++++++++++++++-----
dlls/wined3d/swapchain.c | 21 ++++---
dlls/wined3d/wined3d_private.h | 2 -
7 files changed, 147 insertions(+), 62 deletions(-)
1279053f0a2c25b4984de66f6236a3a74c8aecba
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 89986f8..f754fe1 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -81,10 +81,9 @@ static void test_swapchain(void)
hr = IDirect3DDevice8_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain2);
ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
- /* Unsupported by wine for now */
d3dpp.BackBufferCount = 2;
hr = IDirect3DDevice8_CreateAdditionalSwapChain(pDevice, &d3dpp, &swapchain3);
- todo_wine ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
+ ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString8(hr));
if(SUCCEEDED(hr)) {
/* Swapchain 3, created with backbuffercount 2 */
backbuffer = (void *) 0xdeadbeef;
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 0984aab..a01b2b5 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -166,10 +166,9 @@ static void test_swapchain(void)
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));
+ ok(SUCCEEDED(hr), "Failed to create a swapchain (%s)\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr)) {
/* Swapchain 3, created with backbuffercount 2 */
backbuffer = (void *) 0xdeadbeef;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index e0322eb..7157787 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1343,9 +1343,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
*******************************/
/* Check the params */
- if(*pPresentationParameters->BackBufferCount > 1) {
+ if(*pPresentationParameters->BackBufferCount > D3DPRESENT_BACK_BUFFER_MAX) {
ERR("App requested %d back buffers, this is not supported for now\n", *pPresentationParameters->BackBufferCount);
return WINED3DERR_INVALIDCALL;
+ } else if (*pPresentationParameters->BackBufferCount > 1) {
+ FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n");
}
D3DCREATEOBJECTINSTANCE(object, SwapChain)
@@ -1581,23 +1583,48 @@ static HRESULT WINAPI IWineD3DDeviceImpl
NULL /* pShared (always null)*/);
if (object->frontBuffer != NULL)
IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
+
if(object->presentParms.BackBufferCount > 0) {
- TRACE("calling rendertarget CB\n");
- hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
- object->presentParms.BackBufferWidth,
- object->presentParms.BackBufferHeight,
- object->presentParms.BackBufferFormat,
- object->presentParms.MultiSampleType,
- object->presentParms.MultiSampleQuality,
- TRUE /* Lockable */,
- &object->backBuffer,
- NULL /* pShared (always null)*/);
+ int i;
+
+ object->backBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(IWineD3DSurface *) * object->presentParms.BackBufferCount);
+ if(!object->backBuffer) {
+ ERR("Out of memory\n");
+
+ if (object->frontBuffer) {
+ IUnknown *bufferParent;
+ IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if (IUnknown_Release(bufferParent) > 0) {
+ FIXME("(%p) Something's still holding the front buffer\n",This);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, object);
+ return E_OUTOFMEMORY;
+ }
+
+ for(i = 0; i < object->presentParms.BackBufferCount; i++) {
+ TRACE("calling rendertarget CB\n");
+ hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
+ object->presentParms.BackBufferWidth,
+ object->presentParms.BackBufferHeight,
+ object->presentParms.BackBufferFormat,
+ object->presentParms.MultiSampleType,
+ object->presentParms.MultiSampleQuality,
+ TRUE /* Lockable */,
+ &object->backBuffer[i],
+ NULL /* pShared (always null)*/);
+ if(hr == WINED3D_OK && object->backBuffer[i]) {
+ IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object);
+ } else {
+ break;
+ }
+ }
} else {
object->backBuffer = NULL;
}
if (object->backBuffer != NULL) {
- IWineD3DSurface_SetContainer(object->backBuffer, (IWineD3DBase *)object);
ENTER_GL();
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
@@ -1611,7 +1638,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
}
/* Under directX swapchains share the depth stencil, so only create one depth-stencil */
- if (pPresentationParameters->EnableAutoDepthStencil) {
+ if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK) {
TRACE("Creating depth stencil buffer\n");
if (This->depthStencilBuffer == NULL ) {
hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent,
@@ -1635,7 +1662,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
object->wantsDepthStencilBuffer = FALSE;
}
- TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer, object->wantsDepthStencilBuffer);
+ TRACE("FrontBuf @ %p, BackBuf @ %p, DepthStencil %d\n",object->frontBuffer, object->backBuffer ? NULL : object->backBuffer[0], object->wantsDepthStencilBuffer);
/*********************
@@ -1704,11 +1731,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl
}
}
if (object->backBuffer) {
- IWineD3DSurface_GetParent(object->backBuffer, &bufferParent);
- IUnknown_Release(bufferParent); /* once for the get parent */
- if (IUnknown_Release(bufferParent) > 0) {
- FIXME("(%p) Something's still holding the back buffer\n",This);
+ int i;
+ for(i = 0; i < object->presentParms.BackBufferCount; i++) {
+ if(object->backBuffer[i]) {
+ IWineD3DSurface_GetParent(object->backBuffer[i], &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if (IUnknown_Release(bufferParent) > 0) {
+ FIXME("(%p) Something's still holding the back buffer\n",This);
+ }
+ }
}
+ HeapFree(GetProcessHeap(), 0, object->backBuffer);
+ object->backBuffer = NULL;
}
/* NOTE: don't clean up the depthstencil buffer because it belongs to the device */
/* Clean up the context */
@@ -1891,9 +1925,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl
}
This->swapchains[0] = (IWineD3DSwapChain *) swapchain;
- if(swapchain->backBuffer) {
+ if(swapchain->backBuffer && swapchain->backBuffer[0]) {
TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
- This->renderTarget = swapchain->backBuffer;
+ This->renderTarget = swapchain->backBuffer[0];
}
else {
TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
@@ -5956,7 +5990,7 @@ static HRESULT WINAPI IWineD3DDeviceIm
ENTER_GL();
/* TODO: opengl Context switching for swapchains etc... */
if (NULL != container || pRenderTarget == This->renderTarget || pRenderTarget == This->depthStencilBuffer) {
- if (NULL != container && (pRenderTarget == container->backBuffer)) {
+ if (NULL != container && (pRenderTarget == container->backBuffer[0])) {
glReadBuffer(GL_BACK);
vcheckGLcall("glReadBuffer(GL_BACK)");
} else if ((NULL != container && (pRenderTarget == container->frontBuffer)) || (pRenderTarget == This->renderTarget)) {
@@ -6654,28 +6688,44 @@ static HRESULT WINAPI IWineD3DDeviceImpl
IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain);
}
}
- if(Swapchain->backBuffer != Back) {
+
+ if(Back && !Swapchain->backBuffer) {
+ /* We need memory for the back buffer array - only one back buffer this way */
+ Swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *));
+ if(!Swapchain->backBuffer) {
+ ERR("Out of memory\n");
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ if(Swapchain->backBuffer[0] != Back) {
TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back);
ENTER_GL();
- if(!Swapchain->backBuffer) {
+ if(!Swapchain->backBuffer[0]) {
/* GL was told to draw to the front buffer at creation,
* undo that
*/
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
+ /* Set the backbuffer count to 1 because other code uses it to fing the back buffers */
+ Swapchain->presentParms.BackBufferCount = 1;
} else if (!Back) {
/* That makes problems - disable for now */
/* glDrawBuffer(GL_FRONT); */
checkGLcall("glDrawBuffer(GL_FRONT)");
+ /* We have lost our back buffer, set this to 0 to avoid confusing other code */
+ Swapchain->presentParms.BackBufferCount = 0;
}
LEAVE_GL();
- if(Swapchain->backBuffer)
- IWineD3DSurface_SetContainer(Swapchain->backBuffer, NULL);
- Swapchain->backBuffer = Back;
+ if(Swapchain->backBuffer[0])
+ IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL);
+ Swapchain->backBuffer[0] = Back;
- if(Swapchain->backBuffer) {
- IWineD3DSurface_SetContainer(Swapchain->backBuffer, (IWineD3DBase *) Swapchain);
+ if(Swapchain->backBuffer[0]) {
+ IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain);
+ } else {
+ HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer);
}
}
@@ -7001,14 +7051,24 @@ static HRESULT WINAPI IWineD3DDeviceImpl
/**
* TODO: remove the use of IWineD3DSwapChainImpl, a context manager will help since it will replace the
- * renderTarget = swapchain->backBuffer bit and anything to do with *glContexts
+ * renderTarget = swapchain->backBuffer[i] bit and anything to do with *glContexts
**********************************************************************/
if (IWineD3DSurface_GetContainer(RenderSurface, &IID_IWineD3DSwapChain, (void **)&swapchain) == WINED3D_OK) {
/* We also need to make sure that the lights &co are also in the context of the swapchains */
/* FIXME: If the render target gets sent to the frontBuffer should be be presenting it raw? */
TRACE("making swapchain active\n");
if (RenderSurface != This->renderTarget) {
- if (RenderSurface == swapchain->backBuffer) {
+ BOOL backbuf = FALSE;
+ int i;
+
+ for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
+ if(RenderSurface == swapchain->backBuffer[i]) {
+ backbuf = TRUE;
+ break;
+ }
+ }
+
+ if (backbuf) {
} else {
/* This could be flagged so that some operations work directly with the front buffer */
FIXME("Attempting to set the renderTarget to the frontBuffer\n");
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 08afebe..37f933d 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -2226,7 +2226,7 @@ void drawPrimitive(IWineD3DDevice *iface
for(i = 0; i < IWineD3DDevice_GetNumberOfSwapChains(iface); i++) {
IWineD3DDevice_GetSwapChain(iface, i, (IWineD3DSwapChain **) &swapchain);
if(swapchain) {
- if(swapchain->backBuffer) ((IWineD3DSurfaceImpl *) swapchain->backBuffer)->Flags |= SFLAG_GLDIRTY;
+ if(swapchain->backBuffer) ((IWineD3DSurfaceImpl *) swapchain->backBuffer[0])->Flags |= SFLAG_GLDIRTY;
IWineD3DSwapChain_Release( (IWineD3DSwapChain *) swapchain);
}
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index da0ef63..5a045ff 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -287,6 +287,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
IWineD3DSwapChainImpl *swapchain = NULL;
static UINT messages = 0; /* holds flags to disable fixme messages */
+ BOOL backbuf = FALSE;
/* fixme: should we really lock as such? */
if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INPBUFFER)) ==
@@ -307,7 +308,16 @@ static HRESULT WINAPI IWineD3DSurfaceImp
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
if (swapchain != NULL || iface == myDevice->renderTarget || iface == myDevice->depthStencilBuffer) {
- if (swapchain != NULL && iface == swapchain->backBuffer) {
+ if(swapchain != NULL) {
+ int i;
+ for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
+ if(iface == swapchain->backBuffer[i]) {
+ backbuf = TRUE;
+ break;
+ }
+ }
+ }
+ if (backbuf) {
TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
} else if (swapchain != NULL && iface == swapchain->frontBuffer) {
TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory);
@@ -518,12 +528,13 @@ static HRESULT WINAPI IWineD3DSurfaceImp
/* NOTE: In a shared context environment the renderTarget will use the same context as the implicit swapchain (we're not in a shared environment yet! */
if ((swapchain == targetSwapChain && targetSwapChain != NULL) || iface == myDevice->renderTarget) {
- if (iface == myDevice->renderTarget || iface == swapchain->backBuffer) {
+ if (iface == swapchain->frontBuffer) {
+ TRACE("locking front\n");
+ glReadBuffer(GL_FRONT);
+ }
+ else if (iface == myDevice->renderTarget || backbuf) {
TRACE("locking back buffer\n");
- glReadBuffer(GL_BACK);
- } else if (iface == swapchain->frontBuffer) {
- TRACE("locking front\n");
- glReadBuffer(GL_FRONT);
+ glReadBuffer(GL_BACK);
} else if (iface == myDevice->depthStencilBuffer) {
FIXME("Stencil Buffer lock unsupported for now\n");
} else {
@@ -535,7 +546,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
if (swapchain->glCtx == implSwapChain->render_ctx && swapchain->drawable == implSwapChain->win) {
/* This will fail for the implicit swapchain, which is why there needs to be a context manager */
- if (iface == swapchain->backBuffer) {
+ if (backbuf) {
glReadBuffer(GL_BACK);
} else if (iface == swapchain->frontBuffer) {
glReadBuffer(GL_FRONT);
@@ -639,6 +650,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
vcheckGLcall("glReadPixels");
TRACE("Resetting buffer\n");
+
glReadBuffer(prev_read);
vcheckGLcall("glReadBuffer");
}
@@ -696,6 +708,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice;
const char *buffername = "";
IWineD3DSwapChainImpl *swapchain = NULL;
+ BOOL backbuf = FALSE;
if (!(This->Flags & SFLAG_LOCKED)) {
WARN("trying to Unlock an unlocked surf@%p\n", This);
@@ -705,7 +718,17 @@ static HRESULT WINAPI IWineD3DSurfaceImp
if (WINED3DUSAGE_RENDERTARGET & This->resource.usage) {
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain);
- if ((swapchain != NULL) && iface == swapchain->backBuffer) {
+ if(swapchain) {
+ int i;
+ for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
+ if(iface == swapchain->backBuffer[i]) {
+ backbuf = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (backbuf) {
buffername = "backBuffer";
} else if ((swapchain != NULL) && iface == swapchain->frontBuffer) {
buffername = "frontBuffer";
@@ -743,7 +766,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
IWineD3DSwapChainImpl *implSwapChain;
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
- if (iface == implSwapChain->backBuffer || iface == implSwapChain->frontBuffer || iface == myDevice->renderTarget) {
+ if (backbuf || iface == implSwapChain->frontBuffer || iface == myDevice->renderTarget) {
GLint prev_store;
GLint prev_draw;
GLint prev_depth_test;
@@ -787,7 +810,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
if (iface == implSwapChain->frontBuffer) {
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer GL_FRONT");
- } else if (iface == implSwapChain->backBuffer || iface == myDevice->renderTarget) {
+ } else if (backbuf || iface == myDevice->renderTarget) {
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer GL_BACK");
}
@@ -802,6 +825,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
vcheckGLcall("glRasterPos2f");
+
switch (This->resource.format) {
case WINED3DFMT_X4R4G4B4:
{
@@ -1996,7 +2020,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
/* These flags are unimportant for the flag check, remove them */
if((Flags & ~(DDBLT_DONOTWAIT | DDBLT_WAIT)) == 0) {
- if( ((IWineD3DSurface *) This == swapchain->frontBuffer) && ((IWineD3DSurface *) Src == swapchain->backBuffer) ) {
+ if( swapchain->backBuffer && ((IWineD3DSurface *) This == swapchain->frontBuffer) && ((IWineD3DSurface *) Src == swapchain->backBuffer[0]) ) {
D3DSWAPEFFECT orig_swap = swapchain->presentParms.SwapEffect;
@@ -2027,10 +2051,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
/* Blt from texture to rendertarget? */
if( ( ( (IWineD3DSurface *) This == swapchain->frontBuffer) ||
- ((IWineD3DSurface *) This == swapchain->backBuffer) )
+ ( swapchain->backBuffer && (IWineD3DSurface *) This == swapchain->backBuffer[0]) )
&&
( ( (IWineD3DSurface *) Src != swapchain->frontBuffer) &&
- ( (IWineD3DSurface *) Src != swapchain->backBuffer) ) ) {
+ ( swapchain->backBuffer && (IWineD3DSurface *) Src != swapchain->backBuffer[0]) ) ) {
float glTexCoord[4];
DWORD oldCKey;
GLint oldLight, oldFog, oldDepth, oldBlend, oldCull, oldAlpha;
@@ -2253,9 +2277,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
/* Blt from rendertarget to texture? */
if( (SrcSurface == swapchain->frontBuffer) ||
- (SrcSurface == swapchain->backBuffer) ) {
+ (swapchain->backBuffer && SrcSurface == swapchain->backBuffer[0]) ) {
if( ( (IWineD3DSurface *) This != swapchain->frontBuffer) &&
- ( (IWineD3DSurface *) This != swapchain->backBuffer) ) {
+ ( swapchain->backBuffer && (IWineD3DSurface *) This != swapchain->backBuffer[0]) ) {
UINT row;
D3DRECT srect;
float xrel, yrel;
@@ -2282,7 +2306,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
/* Bind the target texture */
glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
checkGLcall("glBindTexture");
- if(SrcSurface == swapchain->backBuffer) {
+ if(swapchain->backBuffer && SrcSurface == swapchain->backBuffer[0]) {
glReadBuffer(GL_BACK);
} else {
glReadBuffer(GL_FRONT);
@@ -2385,7 +2409,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
TRACE("Calling GetSwapChain with mydevice = %p\n", myDevice);
IWineD3DDevice_GetSwapChain((IWineD3DDevice *)myDevice, 0, (IWineD3DSwapChain **)&implSwapChain);
IWineD3DSwapChain_Release( (IWineD3DSwapChain *) implSwapChain );
- if(This == (IWineD3DSurfaceImpl*) implSwapChain->backBuffer) {
+ if(implSwapChain->backBuffer && This == (IWineD3DSurfaceImpl*) implSwapChain->backBuffer[0]) {
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
}
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 1b8e4d9..e7fd2b3 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -101,11 +101,14 @@ static ULONG WINAPI IWineD3DSwapChainImp
}
if(This->backBuffer) {
- IWineD3DSurface_SetContainer(This->backBuffer, 0);
- IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
- IUnknown_Release(bufferParent); /* once for the get parent */
- if(IUnknown_Release(bufferParent) > 0){
- FIXME("(%p) Something's still holding the back buffer\n",This);
+ int i;
+ for(i = 0; i < This->presentParms.BackBufferCount; i++) {
+ IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
+ IWineD3DSurface_GetParent(This->backBuffer[i], &bufferParent);
+ IUnknown_Release(bufferParent); /* once for the get parent */
+ if(IUnknown_Release(bufferParent) > 0){
+ FIXME("(%p) Something's still holding the back buffer\n",This);
+ }
}
}
@@ -330,7 +333,7 @@ static HRESULT WINAPI IWineD3DSwapChainI
}
((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags |= SFLAG_GLDIRTY;
- ((IWineD3DSurfaceImpl *) This->backBuffer)->Flags |= SFLAG_GLDIRTY;
+ ((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags |= SFLAG_GLDIRTY;
TRACE("returning\n");
return WINED3D_OK;
@@ -373,9 +376,6 @@ static HRESULT WINAPI IWineD3DSwapChainI
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
- *ppBackBuffer = This->backBuffer;
- TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
-
if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
TRACE("Back buffer count out of range\n");
/* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here
@@ -385,6 +385,9 @@ static HRESULT WINAPI IWineD3DSwapChainI
return WINED3DERR_INVALIDCALL;
}
+ *ppBackBuffer = This->backBuffer[iBackBuffer];
+ TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
+
/* Note inc ref on returned surface */
if(*ppBackBuffer) IWineD3DSurface_AddRef(*ppBackBuffer);
return WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9155caf..bd1ccd6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1125,7 +1125,7 @@ typedef struct IWineD3DSwapChainImpl
IWineD3DDeviceImpl *wineD3DDevice;
/* IWineD3DSwapChain fields */
- IWineD3DSurface *backBuffer;
+ IWineD3DSurface **backBuffer;
IWineD3DSurface *frontBuffer;
BOOL wantsDepthStencilBuffer;
D3DPRESENT_PARAMETERS presentParms;
--
1.2.4
More information about the wine-patches
mailing list