mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +00:00
wined3d: Clean up ActiveRender.
This commit is contained in:
parent
4a581e6030
commit
448f918a39
1 changed files with 209 additions and 170 deletions
|
@ -7317,15 +7317,149 @@ static HRESULT WINAPI IWineD3DDeviceImpl_FindGLContext(IWineD3DDevice *iface, IW
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Reapply the device stateblock */
|
||||||
|
static void device_reapply_stateblock(IWineD3DDeviceImpl* This) {
|
||||||
|
|
||||||
|
BOOL oldRecording;
|
||||||
|
IWineD3DStateBlockImpl *oldUpdateStateBlock;
|
||||||
|
|
||||||
|
/* Disable recording */
|
||||||
|
oldUpdateStateBlock = This->updateStateBlock;
|
||||||
|
oldRecording= This->isRecordingState;
|
||||||
|
This->isRecordingState = FALSE;
|
||||||
|
This->updateStateBlock = This->stateBlock;
|
||||||
|
|
||||||
|
/* Reapply the state block */
|
||||||
|
IWineD3DStateBlock_Apply((IWineD3DStateBlock *)This->stateBlock);
|
||||||
|
|
||||||
|
/* Restore recording */
|
||||||
|
This->isRecordingState = oldRecording;
|
||||||
|
This->updateStateBlock = oldUpdateStateBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the device to render to a texture, or not.
|
||||||
|
* This involves changing renderUpsideDown */
|
||||||
|
|
||||||
|
static void device_render_to_texture(IWineD3DDeviceImpl* This, BOOL isTexture) {
|
||||||
|
|
||||||
|
DWORD cullMode;
|
||||||
|
BOOL oldRecording;
|
||||||
|
IWineD3DStateBlockImpl *oldUpdateStateBlock;
|
||||||
|
|
||||||
|
/* Disable recording */
|
||||||
|
oldUpdateStateBlock = This->updateStateBlock;
|
||||||
|
oldRecording= This->isRecordingState;
|
||||||
|
This->isRecordingState = FALSE;
|
||||||
|
This->updateStateBlock = This->stateBlock;
|
||||||
|
|
||||||
|
/* Set upside-down rendering, and update the cull mode */
|
||||||
|
/* The surface must be rendered upside down to cancel the flip produced by glCopyTexImage */
|
||||||
|
This->renderUpsideDown = isTexture;
|
||||||
|
This->last_was_rhw = FALSE;
|
||||||
|
This->proj_valid = FALSE;
|
||||||
|
IWineD3DDevice_GetRenderState((IWineD3DDevice*) This, WINED3DRS_CULLMODE, &cullMode);
|
||||||
|
IWineD3DDevice_SetRenderState((IWineD3DDevice*) This, WINED3DRS_CULLMODE, cullMode);
|
||||||
|
|
||||||
|
/* Restore recording */
|
||||||
|
This->isRecordingState = oldRecording;
|
||||||
|
This->updateStateBlock = oldUpdateStateBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns an array of compatible FBconfig(s).
|
||||||
|
* The array must be freed with XFree. Requires ENTER_GL() */
|
||||||
|
|
||||||
|
static GLXFBConfig* device_find_fbconfigs(
|
||||||
|
IWineD3DDeviceImpl* This,
|
||||||
|
IWineD3DSwapChainImpl* implicitSwapchainImpl,
|
||||||
|
IWineD3DSurface* RenderSurface) {
|
||||||
|
|
||||||
|
GLXFBConfig* cfgs = NULL;
|
||||||
|
int nCfgs = 0;
|
||||||
|
int attribs[256];
|
||||||
|
int nAttribs = 0;
|
||||||
|
|
||||||
|
IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
|
||||||
|
D3DFORMAT BackBufferFormat = ((IWineD3DSurfaceImpl *) RenderSurface)->resource.format;
|
||||||
|
D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
|
||||||
|
|
||||||
|
/**TODO:
|
||||||
|
if StencilSurface == NULL && zBufferTarget != NULL then switch the zbuffer off,
|
||||||
|
it StencilSurface != NULL && zBufferTarget == NULL switch it on
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PUSH1(att) attribs[nAttribs++] = (att);
|
||||||
|
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
|
||||||
|
|
||||||
|
/* PUSH2(GLX_BIND_TO_TEXTURE_RGBA_ATI, True); examples of this are few and far between (but I've got a nice working one!)*/
|
||||||
|
|
||||||
|
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
|
||||||
|
PUSH2(GLX_X_RENDERABLE, TRUE);
|
||||||
|
PUSH2(GLX_DOUBLEBUFFER, TRUE);
|
||||||
|
TRACE("calling makeglcfg\n");
|
||||||
|
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, FALSE /* alternate */);
|
||||||
|
PUSH1(None);
|
||||||
|
TRACE("calling chooseFGConfig\n");
|
||||||
|
cfgs = glXChooseFBConfig(implicitSwapchainImpl->display,
|
||||||
|
DefaultScreen(implicitSwapchainImpl->display),
|
||||||
|
attribs, &nCfgs);
|
||||||
|
if (cfgs == NULL) {
|
||||||
|
/* OK we didn't find the exact config, so use any reasonable match */
|
||||||
|
/* TODO: fill in the 'requested' and 'current' depths, also make sure that's
|
||||||
|
why we failed and only show this message once! */
|
||||||
|
MESSAGE("Failed to find exact match, finding alternative but you may "
|
||||||
|
"suffer performance issues, try changing xfree's depth to match the requested depth\n");
|
||||||
|
nAttribs = 0;
|
||||||
|
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT);
|
||||||
|
/* PUSH2(GLX_X_RENDERABLE, TRUE); */
|
||||||
|
PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
|
||||||
|
PUSH2(GLX_DOUBLEBUFFER, FALSE);
|
||||||
|
TRACE("calling makeglcfg\n");
|
||||||
|
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, TRUE /* alternate */);
|
||||||
|
PUSH1(None);
|
||||||
|
cfgs = glXChooseFBConfig(implicitSwapchainImpl->display,
|
||||||
|
DefaultScreen(implicitSwapchainImpl->display),
|
||||||
|
attribs, &nCfgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfgs == NULL) {
|
||||||
|
ERR("Could not get a valid FBConfig for (%u,%s)/(%u,%s)\n",
|
||||||
|
BackBufferFormat, debug_d3dformat(BackBufferFormat),
|
||||||
|
StencilBufferFormat, debug_d3dformat(StencilBufferFormat));
|
||||||
|
} else {
|
||||||
|
#ifdef EXTRA_TRACES
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nCfgs; ++i) {
|
||||||
|
TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat,
|
||||||
|
debug_d3dformat(BackBufferFormat), StencilBufferFormat,
|
||||||
|
debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
|
||||||
|
}
|
||||||
|
if (NULL != This->renderTarget) {
|
||||||
|
glFlush();
|
||||||
|
vcheckGLcall("glFlush");
|
||||||
|
/** This is only useful if the old render target was a swapchain,
|
||||||
|
* we need to supercede this with a function that displays
|
||||||
|
* the current buffer on the screen. This is easy to do in glx1.3 but
|
||||||
|
* we need to do copy-write pixels in glx 1.2.
|
||||||
|
************************************************/
|
||||||
|
glXSwapBuffers(implicitSwapChainImpl->display,
|
||||||
|
implicitSwapChainImpl->drawable);
|
||||||
|
printf("Hit Enter to get next frame ...\n");
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#undef PUSH1
|
||||||
|
#undef PUSH2
|
||||||
|
|
||||||
|
return cfgs;
|
||||||
|
}
|
||||||
|
|
||||||
/** FIXME: This is currently used called whenever SetRenderTarget or SetStencilBuffer are called
|
/** FIXME: This is currently used called whenever SetRenderTarget or SetStencilBuffer are called
|
||||||
* the functionality needs splitting up so that we don't do more than we should do.
|
* the functionality needs splitting up so that we don't do more than we should do.
|
||||||
* this only seems to impact performance a little.
|
* this only seems to impact performance a little.
|
||||||
******************************/
|
******************************/
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
IWineD3DSurface *RenderSurface) {
|
IWineD3DSurface *RenderSurface) {
|
||||||
HRESULT ret = WINED3DERR_INVALIDCALL;
|
|
||||||
BOOL oldRecording;
|
|
||||||
IWineD3DStateBlockImpl *oldUpdateStateBlock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently only active for GLX >= 1.3
|
* Currently only active for GLX >= 1.3
|
||||||
|
@ -7345,102 +7479,37 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
#if defined(GL_VERSION_1_3)
|
#if defined(GL_VERSION_1_3)
|
||||||
|
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
|
|
||||||
IWineD3DSurface *tmp;
|
IWineD3DSurface *tmp;
|
||||||
/** TODO: we only need to look up the configuration !IF! we are setting the target to a texture **/
|
|
||||||
GLXFBConfig* cfgs = NULL;
|
GLXFBConfig* cfgs = NULL;
|
||||||
int nCfgs = 0;
|
|
||||||
int attribs[256];
|
|
||||||
int nAttribs = 0;
|
|
||||||
IWineD3DSwapChain *currentSwapchain;
|
IWineD3DSwapChain *currentSwapchain;
|
||||||
IWineD3DSwapChainImpl *swapchain;
|
IWineD3DSwapChainImpl *currentSwapchainImpl;
|
||||||
/** TODO: get rid of Impl usage we should always create a zbuffer/stencil with our contexts if possible,
|
IWineD3DSwapChain *implicitSwapchain;
|
||||||
* but switch them off if the StencilSurface is set to NULL
|
IWineD3DSwapChainImpl *implicitSwapchainImpl;
|
||||||
** *********************************************************/
|
IWineD3DSwapChain *renderSurfaceSwapchain;
|
||||||
D3DFORMAT BackBufferFormat = ((IWineD3DSurfaceImpl *) RenderSurface)->resource.format;
|
IWineD3DSwapChainImpl *renderSurfaceSwapchainImpl;
|
||||||
D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
|
|
||||||
|
|
||||||
/**TODO:
|
/* Obtain a reference to the device implicit swapchain,
|
||||||
if StencilSurface == NULL && zBufferTarget != NULL then switch the zbuffer off,
|
* the swapchain of the current render target,
|
||||||
it StencilSurface != NULL && zBufferTarget == NULL switch it on
|
* and the swapchain of the new render target.
|
||||||
*/
|
* Fallback to device implicit swapchain if the current render target doesn't have one */
|
||||||
|
IWineD3DDevice_GetSwapChain(iface, 0, &implicitSwapchain);
|
||||||
|
IWineD3DSurface_GetContainer(RenderSurface, &IID_IWineD3DSwapChain, (void**) &renderSurfaceSwapchain);
|
||||||
|
IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DSwapChain, (void **)¤tSwapchain);
|
||||||
|
if (currentSwapchain == NULL)
|
||||||
|
IWineD3DDevice_GetSwapChain(iface, 0, ¤tSwapchain);
|
||||||
|
|
||||||
#define PUSH1(att) attribs[nAttribs++] = (att);
|
currentSwapchainImpl = (IWineD3DSwapChainImpl*) currentSwapchain;
|
||||||
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
|
implicitSwapchainImpl = (IWineD3DSwapChainImpl*) implicitSwapchain;
|
||||||
|
renderSurfaceSwapchainImpl = (IWineD3DSwapChainImpl*) renderSurfaceSwapchain;
|
||||||
/* PUSH2(GLX_BIND_TO_TEXTURE_RGBA_ATI, True); examples of this are few and far between (but I've got a nice working one!)*/
|
|
||||||
|
|
||||||
/** TODO: remove the reff to Impl (context manager should fix this!) **/
|
|
||||||
IWineD3DSwapChainImpl *impSwapChain;
|
|
||||||
IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **)&impSwapChain);
|
|
||||||
if (NULL == impSwapChain) { /* NOTE: This should NEVER fail */
|
|
||||||
ERR("(%p) Failed to get a the implicit swapchain\n", iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
|
|
||||||
PUSH2(GLX_X_RENDERABLE, TRUE);
|
|
||||||
PUSH2(GLX_DOUBLEBUFFER, TRUE);
|
|
||||||
TRACE("calling makeglcfg\n");
|
|
||||||
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, FALSE /* alternate */);
|
|
||||||
PUSH1(None);
|
|
||||||
|
|
||||||
TRACE("calling chooseFGConfig\n");
|
|
||||||
cfgs = glXChooseFBConfig(impSwapChain->display, DefaultScreen(impSwapChain->display),
|
|
||||||
attribs, &nCfgs);
|
|
||||||
|
|
||||||
if (!cfgs) { /* OK we didn't find the exact config, so use any reasonable match */
|
|
||||||
/* TODO: fill in the 'requested' and 'current' depths, also make sure that's
|
|
||||||
why we failed and only show this message once! */
|
|
||||||
MESSAGE("Failed to find exact match, finding alternative but you may suffer performance issues, try changing xfree's depth to match the requested depth\n"); /**/
|
|
||||||
nAttribs = 0;
|
|
||||||
PUSH2(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT);
|
|
||||||
/* PUSH2(GLX_X_RENDERABLE, TRUE); */
|
|
||||||
PUSH2(GLX_RENDER_TYPE, GLX_RGBA_BIT);
|
|
||||||
PUSH2(GLX_DOUBLEBUFFER, FALSE);
|
|
||||||
TRACE("calling makeglcfg\n");
|
|
||||||
D3DFmtMakeGlCfg(BackBufferFormat, StencilBufferFormat, attribs, &nAttribs, TRUE /* alternate */);
|
|
||||||
PUSH1(None);
|
|
||||||
cfgs = glXChooseFBConfig(impSwapChain->display, DefaultScreen(impSwapChain->display),
|
|
||||||
attribs, &nCfgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL != cfgs) {
|
|
||||||
#ifdef EXTRA_TRACES
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < nCfgs; ++i) {
|
|
||||||
TRACE("for (%u,%s)/(%u,%s) found config[%d]@%p\n", BackBufferFormat,
|
|
||||||
debug_d3dformat(BackBufferFormat), StencilBufferFormat,
|
|
||||||
debug_d3dformat(StencilBufferFormat), i, cfgs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL != This->renderTarget) {
|
|
||||||
glFlush();
|
|
||||||
vcheckGLcall("glFlush");
|
|
||||||
/** This is only useful if the old render target was a swapchain,
|
|
||||||
* we need to supercede this with a function that displays
|
|
||||||
* the current buffer on the screen. This is easy to do in glx1.3 but
|
|
||||||
* we need to do copy-write pixels in glx 1.2.
|
|
||||||
************************************************/
|
|
||||||
glXSwapBuffers(impSwapChain->display, impSwapChain->drawable);
|
|
||||||
|
|
||||||
printf("Hit Enter to get next frame ...\n");
|
|
||||||
getchar();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DSwapChain, (void **)¤tSwapchain) != WINED3D_OK) {
|
|
||||||
/* the selected render target doesn't belong to a swapchain, so use the devices implicit swapchain */
|
|
||||||
IWineD3DDevice_GetSwapChain(iface, 0, ¤tSwapchain);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: remove the use of IWineD3DSwapChainImpl, a context manager will help since it will replace the
|
* TODO: remove the use of IWineD3DSwapChainImpl, a context manager will help since it will replace the
|
||||||
* renderTarget = swapchain->backBuffer[i] 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) {
|
if (renderSurfaceSwapchain != NULL) {
|
||||||
|
|
||||||
/* We also need to make sure that the lights &co are also in the context of the swapchains */
|
/* 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? */
|
/* FIXME: If the render target gets sent to the frontBuffer should be be presenting it raw? */
|
||||||
TRACE("making swapchain active\n");
|
TRACE("making swapchain active\n");
|
||||||
|
@ -7448,8 +7517,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
BOOL backbuf = FALSE;
|
BOOL backbuf = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
|
for(i = 0; i < renderSurfaceSwapchainImpl->presentParms.BackBufferCount; i++) {
|
||||||
if(RenderSurface == swapchain->backBuffer[i]) {
|
if(RenderSurface == renderSurfaceSwapchainImpl->backBuffer[i]) {
|
||||||
backbuf = TRUE;
|
backbuf = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7460,19 +7529,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
/* This could be flagged so that some operations work directly with the front buffer */
|
/* This could be flagged so that some operations work directly with the front buffer */
|
||||||
FIXME("Attempting to set the renderTarget to the frontBuffer\n");
|
FIXME("Attempting to set the renderTarget to the frontBuffer\n");
|
||||||
}
|
}
|
||||||
if (glXMakeCurrent(swapchain->display, swapchain->win, swapchain->glCtx)
|
if (glXMakeCurrent(renderSurfaceSwapchainImpl->display,
|
||||||
== False) {
|
renderSurfaceSwapchainImpl->win,
|
||||||
|
renderSurfaceSwapchainImpl->glCtx) == False) {
|
||||||
|
|
||||||
TRACE("Error in setting current context: context %p drawable %ld !\n",
|
TRACE("Error in setting current context: context %p drawable %ld !\n",
|
||||||
impSwapChain->glCtx, impSwapChain->win);
|
implicitSwapchainImpl->glCtx, implicitSwapchainImpl->win);
|
||||||
}
|
}
|
||||||
|
checkGLcall("glXMakeContextCurrent");
|
||||||
|
|
||||||
IWineD3DDeviceImpl_CleanRender(iface, (IWineD3DSwapChainImpl *)currentSwapchain);
|
/* Clean up the old context */
|
||||||
|
IWineD3DDeviceImpl_CleanRender(iface, currentSwapchainImpl);
|
||||||
|
|
||||||
|
/* Reapply the stateblock, and set the device not to render to texture */
|
||||||
|
device_reapply_stateblock(This);
|
||||||
|
device_render_to_texture(This, FALSE);
|
||||||
}
|
}
|
||||||
checkGLcall("glXMakeContextCurrent");
|
|
||||||
|
|
||||||
IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
|
/* Offscreen rendering: PBuffers (currently disabled).
|
||||||
}
|
* Also note that this path is never reached if FBOs are supported */
|
||||||
else if (pbuffer_support && cfgs != NULL /* && some test to make sure that opengl supports pbuffers */) {
|
} else if (pbuffer_support &&
|
||||||
|
(cfgs = device_find_fbconfigs(This, implicitSwapchainImpl, RenderSurface)) != NULL) {
|
||||||
|
|
||||||
/** ********************************************************************
|
/** ********************************************************************
|
||||||
* This is a quickly hacked out implementation of offscreen textures.
|
* This is a quickly hacked out implementation of offscreen textures.
|
||||||
|
@ -7504,13 +7581,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
/* TODO: This should really be part of findGlContext */
|
/* TODO: This should really be part of findGlContext */
|
||||||
if (NULL == newContext->context) {
|
if (NULL == newContext->context) {
|
||||||
|
|
||||||
TRACE("making new buffer\n");
|
int attribs[256];
|
||||||
nAttribs = 0;
|
int nAttribs = 0;
|
||||||
PUSH2(GLX_PBUFFER_WIDTH, newContext->Width);
|
|
||||||
PUSH2(GLX_PBUFFER_HEIGHT, newContext->Height);
|
|
||||||
PUSH1(None);
|
|
||||||
|
|
||||||
newContext->drawable = glXCreatePbuffer(impSwapChain->display, cfgs[0], attribs);
|
TRACE("making new buffer\n");
|
||||||
|
attribs[nAttribs++] = GLX_PBUFFER_WIDTH;
|
||||||
|
attribs[nAttribs++] = newContext->Width;
|
||||||
|
attribs[nAttribs++] = GLX_PBUFFER_HEIGHT;
|
||||||
|
attribs[nAttribs++] = newContext->Height;
|
||||||
|
attribs[nAttribs++] = None;
|
||||||
|
|
||||||
|
newContext->drawable = glXCreatePbuffer(implicitSwapchainImpl->display, cfgs[0], attribs);
|
||||||
|
|
||||||
/** ****************************************
|
/** ****************************************
|
||||||
*GLX1.3 isn't supported by XFree 'yet' until that point ATI emulates pBuffers
|
*GLX1.3 isn't supported by XFree 'yet' until that point ATI emulates pBuffers
|
||||||
|
@ -7520,12 +7601,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
* so until then we have to use glXGetVisualFromFBConfig &co..
|
* so until then we have to use glXGetVisualFromFBConfig &co..
|
||||||
********************************************/
|
********************************************/
|
||||||
|
|
||||||
|
visinfo = glXGetVisualFromFBConfig(implicitSwapchainImpl->display, cfgs[0]);
|
||||||
visinfo = glXGetVisualFromFBConfig(impSwapChain->display, cfgs[0]);
|
|
||||||
if (!visinfo) {
|
if (!visinfo) {
|
||||||
ERR("Error: couldn't get an RGBA, double-buffered visual\n");
|
ERR("Error: couldn't get an RGBA, double-buffered visual\n");
|
||||||
} else {
|
} else {
|
||||||
newContext->context = glXCreateContext(impSwapChain->display, visinfo, impSwapChain->glCtx, GL_TRUE);
|
newContext->context = glXCreateContext(
|
||||||
|
implicitSwapchainImpl->display, visinfo,
|
||||||
|
implicitSwapchainImpl->glCtx, GL_TRUE);
|
||||||
|
|
||||||
XFree(visinfo);
|
XFree(visinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7533,84 +7616,40 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ActiveRender(IWineD3DDevice* iface,
|
||||||
ERR("(%p) : Failed to find a context for surface %p\n", iface, RenderSurface);
|
ERR("(%p) : Failed to find a context for surface %p\n", iface, RenderSurface);
|
||||||
} else {
|
} else {
|
||||||
/* Debug logging, (this function leaks), change to a TRACE when the leak is plugged */
|
/* Debug logging, (this function leaks), change to a TRACE when the leak is plugged */
|
||||||
if (glXMakeCurrent(impSwapChain->display, newContext->drawable, newContext->context) == False) {
|
if (glXMakeCurrent(implicitSwapchainImpl->display,
|
||||||
TRACE("Error in setting current context: context %p drawable %ld\n", newContext->context, newContext->drawable);
|
newContext->drawable, newContext->context) == False) {
|
||||||
|
|
||||||
|
TRACE("Error in setting current context: context %p drawable %ld\n",
|
||||||
|
newContext->context, newContext->drawable);
|
||||||
}
|
}
|
||||||
|
checkGLcall("glXMakeContextCurrent");
|
||||||
|
|
||||||
/* Clean up the old context */
|
/* Clean up the old context */
|
||||||
IWineD3DDeviceImpl_CleanRender(iface, (IWineD3DSwapChainImpl *)currentSwapchain);
|
IWineD3DDeviceImpl_CleanRender(iface, currentSwapchainImpl);
|
||||||
|
|
||||||
|
/* Reapply stateblock, and set device to render to a texture */
|
||||||
|
device_reapply_stateblock(This);
|
||||||
|
device_render_to_texture(This, TRUE);
|
||||||
|
|
||||||
/* Set the current context of the swapchain to the new context */
|
/* Set the current context of the swapchain to the new context */
|
||||||
impSwapChain->drawable = newContext->drawable;
|
implicitSwapchainImpl->drawable = newContext->drawable;
|
||||||
impSwapChain->render_ctx = newContext->context;
|
implicitSwapchainImpl->render_ctx = newContext->context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable recording, and apply the stateblock to the new context
|
/* Replace the render target */
|
||||||
* FIXME: This is a bit of a hack, each context should know it's own state,
|
|
||||||
* the directX current directX state should then be applied to the context */
|
|
||||||
oldUpdateStateBlock = This->updateStateBlock;
|
|
||||||
oldRecording= This->isRecordingState;
|
|
||||||
This->isRecordingState = FALSE;
|
|
||||||
This->updateStateBlock = This->stateBlock;
|
|
||||||
IWineD3DStateBlock_Apply((IWineD3DStateBlock *)This->stateBlock);
|
|
||||||
|
|
||||||
/* clean up the current rendertargets swapchain (if it belonged to one) */
|
|
||||||
if (currentSwapchain != NULL) {
|
|
||||||
IWineD3DSwapChain_Release((IWineD3DSwapChain *)currentSwapchain);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Were done with the opengl context management, setup the rendertargets */
|
|
||||||
|
|
||||||
tmp = This->renderTarget;
|
tmp = This->renderTarget;
|
||||||
This->renderTarget = RenderSurface;
|
This->renderTarget = RenderSurface;
|
||||||
IWineD3DSurface_AddRef(This->renderTarget);
|
IWineD3DSurface_AddRef(This->renderTarget);
|
||||||
IWineD3DSurface_Release(tmp);
|
IWineD3DSurface_Release(tmp);
|
||||||
|
|
||||||
{
|
if (cfgs != NULL) XFree(cfgs);
|
||||||
DWORD value;
|
if (implicitSwapchain != NULL) IWineD3DSwapChain_Release(implicitSwapchain);
|
||||||
|
if (currentSwapchain != NULL) IWineD3DSwapChain_Release(currentSwapchain);
|
||||||
/* The surface must be rendered upside down to cancel the flip produce by glCopyTexImage */
|
if (renderSurfaceSwapchain != NULL) IWineD3DSwapChain_Release(renderSurfaceSwapchain);
|
||||||
/* Check that the container is not a swapchain member */
|
|
||||||
|
|
||||||
IWineD3DSwapChain *tmpSwapChain;
|
|
||||||
if (WINED3D_OK != IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmpSwapChain)) {
|
|
||||||
This->renderUpsideDown = TRUE;
|
|
||||||
}else{
|
|
||||||
This->renderUpsideDown = FALSE;
|
|
||||||
IWineD3DSwapChain_Release(tmpSwapChain);
|
|
||||||
}
|
|
||||||
/* Force updating the cull mode */
|
|
||||||
TRACE("setting render state\n");
|
|
||||||
IWineD3DDevice_GetRenderState(iface, WINED3DRS_CULLMODE, &value);
|
|
||||||
IWineD3DDevice_SetRenderState(iface, WINED3DRS_CULLMODE, value);
|
|
||||||
|
|
||||||
/* Force updating projection matrix */
|
|
||||||
This->last_was_rhw = FALSE;
|
|
||||||
This->proj_valid = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore recording state */
|
|
||||||
This->isRecordingState = oldRecording;
|
|
||||||
This->updateStateBlock = oldUpdateStateBlock;
|
|
||||||
|
|
||||||
ret = WINED3D_OK;
|
|
||||||
|
|
||||||
if (cfgs != NULL) {
|
|
||||||
XFree(cfgs);
|
|
||||||
} else {
|
|
||||||
ERR("cannot get valides GLXFBConfig for (%u,%s)/(%u,%s)\n", BackBufferFormat,
|
|
||||||
debug_d3dformat(BackBufferFormat), StencilBufferFormat, debug_d3dformat(StencilBufferFormat));
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef PUSH1
|
|
||||||
#undef PUSH2
|
|
||||||
if ( NULL != impSwapChain) {
|
|
||||||
IWineD3DSwapChain_Release((IWineD3DSwapChain *)impSwapChain);
|
|
||||||
}
|
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot,
|
static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* iface, UINT XHotSpot,
|
||||||
|
|
Loading…
Reference in a new issue