wined3d: Store an array of contexts in the swapchain.
This is a preparation for using multiple contexts on one drawable to handle multithreading.
This commit is contained in:
parent
fcb83e7111
commit
90fe64cee0
|
@ -616,7 +616,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
|
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
|
||||||
if(hr == WINED3D_OK && swapchain) {
|
if(hr == WINED3D_OK && swapchain) {
|
||||||
TRACE("Rendering onscreen\n");
|
TRACE("Rendering onscreen\n");
|
||||||
context = ((IWineD3DSwapChainImpl *) swapchain)->context;
|
context = ((IWineD3DSwapChainImpl *) swapchain)->context[0];
|
||||||
This->render_offscreen = FALSE;
|
This->render_offscreen = FALSE;
|
||||||
/* The context != This->activeContext will catch a NOP context change. This can occur
|
/* The context != This->activeContext will catch a NOP context change. This can occur
|
||||||
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
|
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
|
||||||
|
@ -652,7 +652,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
/* This may happen if the app jumps streight into offscreen rendering
|
/* This may happen if the app jumps streight into offscreen rendering
|
||||||
* Start using the context of the primary swapchain
|
* Start using the context of the primary swapchain
|
||||||
*/
|
*/
|
||||||
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
|
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
|
||||||
}
|
}
|
||||||
set_render_target_fbo((IWineD3DDevice *) This, 0, target);
|
set_render_target_fbo((IWineD3DDevice *) This, 0, target);
|
||||||
break;
|
break;
|
||||||
|
@ -671,7 +671,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
* Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
|
* Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
|
||||||
*/
|
*/
|
||||||
This->pbufferContext = CreateContext(This, targetimpl,
|
This->pbufferContext = CreateContext(This, targetimpl,
|
||||||
((IWineD3DSwapChainImpl *) This->swapchains[0])->context->display,
|
((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0]->display,
|
||||||
0 /* Window */);
|
0 /* Window */);
|
||||||
This->pbufferWidth = targetimpl->currentDesc.Width;
|
This->pbufferWidth = targetimpl->currentDesc.Width;
|
||||||
This->pbufferHeight = targetimpl->currentDesc.Height;
|
This->pbufferHeight = targetimpl->currentDesc.Height;
|
||||||
|
@ -694,7 +694,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
/* This may happen if the app jumps streight into offscreen rendering
|
/* This may happen if the app jumps streight into offscreen rendering
|
||||||
* Start using the context of the primary swapchain
|
* Start using the context of the primary swapchain
|
||||||
*/
|
*/
|
||||||
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
|
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
|
||||||
}
|
}
|
||||||
glDrawBuffer(This->offscreenBuffer);
|
glDrawBuffer(This->offscreenBuffer);
|
||||||
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
||||||
|
|
|
@ -1351,10 +1351,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
|
||||||
* doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
|
* doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
|
||||||
* it chooses is identical to the one already being used!
|
* it chooses is identical to the one already being used!
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
/** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
|
/** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
|
||||||
|
|
||||||
|
object->context = HeapAlloc(GetProcessHeap(), 0, sizeof(object->context));
|
||||||
|
if(!object->context) {
|
||||||
|
}
|
||||||
|
object->num_contexts = 1;
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
object->context = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, display, object->win);
|
object->context[0] = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, display, object->win);
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
if (!object->context) {
|
if (!object->context) {
|
||||||
|
@ -1363,7 +1368,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
TRACE("Context created (HWND=%p, glContext=%p, Window=%ld)\n",
|
TRACE("Context created (HWND=%p, glContext=%p, Window=%ld)\n",
|
||||||
object->win_handle, object->context->glCtx, object->win);
|
object->win_handle, object->context[0]->glCtx, object->win);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
@ -1501,7 +1506,7 @@ error:
|
||||||
object->backBuffer = NULL;
|
object->backBuffer = NULL;
|
||||||
}
|
}
|
||||||
if(object->context) {
|
if(object->context) {
|
||||||
DestroyContext(This, object->context);
|
DestroyContext(This, object->context[0]);
|
||||||
}
|
}
|
||||||
if(object->frontBuffer) {
|
if(object->frontBuffer) {
|
||||||
IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
|
IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
|
||||||
|
@ -1682,7 +1687,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
|
||||||
This->lastActiveRenderTarget = swapchain->frontBuffer;
|
This->lastActiveRenderTarget = swapchain->frontBuffer;
|
||||||
}
|
}
|
||||||
IWineD3DSurface_AddRef(This->render_targets[0]);
|
IWineD3DSurface_AddRef(This->render_targets[0]);
|
||||||
This->activeContext = swapchain->context;
|
This->activeContext = swapchain->context[0];
|
||||||
|
|
||||||
/* Depth Stencil support */
|
/* Depth Stencil support */
|
||||||
This->stencilBufferTarget = This->depthStencilBuffer;
|
This->stencilBufferTarget = This->depthStencilBuffer;
|
||||||
|
@ -1700,7 +1705,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
|
||||||
* with Default values
|
* with Default values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
((IWineD3DImpl *) This->wineD3D)->isGLInfoValid = IWineD3DImpl_FillGLCaps( This->wineD3D, swapchain->context->display);
|
((IWineD3DImpl *) This->wineD3D)->isGLInfoValid = IWineD3DImpl_FillGLCaps(This->wineD3D, swapchain->context[0]->display);
|
||||||
/* Setup all the devices defaults */
|
/* Setup all the devices defaults */
|
||||||
IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock);
|
IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock);
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -105,6 +105,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface,
|
||||||
static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) {
|
static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) {
|
||||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||||
WINED3DDISPLAYMODE mode;
|
WINED3DDISPLAYMODE mode;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* release the ref to the front and back buffer parents */
|
/* release the ref to the front and back buffer parents */
|
||||||
if(This->frontBuffer) {
|
if(This->frontBuffer) {
|
||||||
|
@ -136,7 +137,10 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
|
||||||
mode.Format = This->orig_fmt;
|
mode.Format = This->orig_fmt;
|
||||||
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode);
|
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode);
|
||||||
}
|
}
|
||||||
DestroyContext(This->wineD3DDevice, This->context);
|
for(i = 0; i < This->num_contexts; i++) {
|
||||||
|
DestroyContext(This->wineD3DDevice, This->context[i]);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->context);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -192,7 +196,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
|
|
||||||
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
|
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
|
||||||
/* TODO: If only source rect or dest rect are supplied then clip the window to match */
|
/* TODO: If only source rect or dest rect are supplied then clip the window to match */
|
||||||
TRACE("preseting display %p, drawable %ld\n", This->context->display, This->context->drawable);
|
TRACE("preseting display %p, drawable %ld\n", This->context[0]->display, This->context[0]->drawable);
|
||||||
|
|
||||||
/* Don't call checkGLcall, as glGetError is not applicable here */
|
/* Don't call checkGLcall, as glGetError is not applicable here */
|
||||||
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
|
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
|
||||||
|
@ -202,7 +206,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
BYTE *mem;
|
BYTE *mem;
|
||||||
|
|
||||||
TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride);
|
TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride);
|
||||||
if(This->context == This->wineD3DDevice->contexts[0]) {
|
if(This->context[0] == This->wineD3DDevice->contexts[0]) {
|
||||||
/* The primary context 'owns' all the opengl resources. Destroying and recreating that context would require downloading
|
/* The primary context 'owns' all the opengl resources. Destroying and recreating that context would require downloading
|
||||||
* all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
|
* all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
|
||||||
* and reload the resources
|
* and reload the resources
|
||||||
|
@ -224,8 +228,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
||||||
IWineD3DSurface_UnlockRect(This->backBuffer[0]);
|
IWineD3DSurface_UnlockRect(This->backBuffer[0]);
|
||||||
|
|
||||||
DestroyContext(This->wineD3DDevice, This->context);
|
DestroyContext(This->wineD3DDevice, This->context[0]);
|
||||||
This->context = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, display, This->win);
|
This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, display, This->win);
|
||||||
|
|
||||||
IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
|
IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
|
||||||
memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
||||||
|
@ -234,7 +238,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glXSwapBuffers(This->context->display, This->context->drawable); /* TODO: cycle through the swapchain buffers */
|
glXSwapBuffers(This->context[0]->display, This->context[0]->drawable); /* TODO: cycle through the swapchain buffers */
|
||||||
|
|
||||||
TRACE("glXSwapBuffers called, Starting new frame\n");
|
TRACE("glXSwapBuffers called, Starting new frame\n");
|
||||||
/* FPS support */
|
/* FPS support */
|
||||||
|
|
|
@ -506,7 +506,7 @@ struct WineD3DContext {
|
||||||
DWORD isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
|
DWORD isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
|
||||||
|
|
||||||
IWineD3DSurface *surface;
|
IWineD3DSurface *surface;
|
||||||
/* TODO: Thread this ctx belongs to */
|
DWORD tid; /* Thread ID which owns this context at the moment */
|
||||||
|
|
||||||
/* Stores some inforation about the context state for optimization */
|
/* Stores some inforation about the context state for optimization */
|
||||||
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
|
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
|
||||||
|
@ -1357,7 +1357,8 @@ typedef struct IWineD3DSwapChainImpl
|
||||||
|
|
||||||
long prev_time, frames; /* Performance tracking */
|
long prev_time, frames; /* Performance tracking */
|
||||||
|
|
||||||
WineD3DContext *context; /* Later a array for multithreading */
|
WineD3DContext **context; /* Later a array for multithreading */
|
||||||
|
unsigned int num_contexts;
|
||||||
|
|
||||||
HWND win_handle;
|
HWND win_handle;
|
||||||
Window win;
|
Window win;
|
||||||
|
|
Loading…
Reference in New Issue