wined3d: Support more than one back buffer.

This commit is contained in:
Stefan Dösinger 2006-06-15 12:54:19 +02:00 committed by Alexandre Julliard
parent c8901d6f62
commit 3862f8e3d7
7 changed files with 147 additions and 62 deletions

View File

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

View File

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

View File

@ -1343,9 +1343,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
*******************************/
/* 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_CreateAdditionalSwapChain(IWineD3DDevic
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_CreateAdditionalSwapChain(IWineD3DDevic
}
/* 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_CreateAdditionalSwapChain(IWineD3DDevic
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_CreateAdditionalSwapChain(IWineD3DDevic
}
}
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_Init3D(IWineD3DDevice *iface, WINED3DPR
}
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);
@ -6027,7 +6061,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetRenderTargetData(IWineD3DDevice *i
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)) {
@ -6725,28 +6759,44 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
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);
}
}
@ -7072,14 +7122,24 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
/**
* 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");

View File

@ -2282,7 +2282,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);
}
}

View File

@ -287,6 +287,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
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 IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
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 IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
/* 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 IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
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 IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
vcheckGLcall("glReadPixels");
TRACE("Resetting buffer\n");
glReadBuffer(prev_read);
vcheckGLcall("glReadBuffer");
}
@ -696,6 +708,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
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 IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
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 IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
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 IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
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 IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1);
vcheckGLcall("glRasterPos2f");
switch (This->resource.format) {
case WINED3DFMT_X4R4G4B4:
{
@ -1996,7 +2020,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* 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_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* 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_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* 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_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* 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_BltOverride(IWineD3DSurfaceImpl *This, RECT *
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)");
}

View File

@ -101,11 +101,14 @@ static ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
}
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 IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
}
((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 IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *ifa
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 IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *ifa
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;

View File

@ -1125,7 +1125,7 @@ typedef struct IWineD3DSwapChainImpl
IWineD3DDeviceImpl *wineD3DDevice;
/* IWineD3DSwapChain fields */
IWineD3DSurface *backBuffer;
IWineD3DSurface **backBuffer;
IWineD3DSurface *frontBuffer;
BOOL wantsDepthStencilBuffer;
D3DPRESENT_PARAMETERS presentParms;