wined3d: Support for using auxilliary buffers for offscreen rendering.
OpenGL AUX buffers provide a way for offscreen rendering which is very similar to our back buffer "offscreen" rendering emulation. Not all card support aux buffers, but if they are available they are a nice present which is easy to use.
This commit is contained in:
parent
9badfb50cf
commit
8d9a553d89
|
@ -622,6 +622,14 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
|
|
||||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && oldRenderOffscreen) {
|
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && oldRenderOffscreen) {
|
||||||
set_render_target_fbo((IWineD3DDevice *) This, 0, target);
|
set_render_target_fbo((IWineD3DDevice *) This, 0, target);
|
||||||
|
} else if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
|
||||||
|
if(((IWineD3DSwapChainImpl *) swapchain)->backBuffer) {
|
||||||
|
glDrawBuffer(GL_BACK);
|
||||||
|
checkGLcall("glDrawBuffer(GL_BACK)");
|
||||||
|
} else {
|
||||||
|
glDrawBuffer(GL_FRONT);
|
||||||
|
checkGLcall("glDrawBuffer(GL_FRONT)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IWineD3DSwapChain_Release(swapchain);
|
IWineD3DSwapChain_Release(swapchain);
|
||||||
|
|
||||||
|
@ -685,6 +693,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
|
||||||
*/
|
*/
|
||||||
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
|
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
|
||||||
}
|
}
|
||||||
|
glDrawBuffer(This->offscreenBuffer);
|
||||||
|
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1707,6 +1707,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
|
||||||
This->contexts[0]->last_was_rhw = 0;
|
This->contexts[0]->last_was_rhw = 0;
|
||||||
glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights);
|
glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights);
|
||||||
checkGLcall("glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights)");
|
checkGLcall("glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights)");
|
||||||
|
|
||||||
|
switch(wined3d_settings.offscreen_rendering_mode) {
|
||||||
|
case ORM_FBO:
|
||||||
|
case ORM_PBUFFER:
|
||||||
|
This->offscreenBuffer = GL_BACK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ORM_BACKBUFFER:
|
||||||
|
{
|
||||||
|
GLint auxBuffers;
|
||||||
|
glGetIntegerv(GL_AUX_BUFFERS, &auxBuffers);
|
||||||
|
TRACE("Got %d aux buffers\n", auxBuffers);
|
||||||
|
if(auxBuffers > 0) {
|
||||||
|
TRACE("Using auxilliary buffer for offscreen rendering\n");
|
||||||
|
This->offscreenBuffer = GL_AUX0;
|
||||||
|
} else {
|
||||||
|
TRACE("Using back buffer for offscreen rendering\n");
|
||||||
|
This->offscreenBuffer = GL_BACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("(%p) All defaults now set up, leaving Init3D with %p\n", This, This);
|
TRACE("(%p) All defaults now set up, leaving Init3D with %p\n", This, This);
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
|
|
|
@ -691,7 +691,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
|
||||||
* Read from the back buffer
|
* Read from the back buffer
|
||||||
*/
|
*/
|
||||||
TRACE("Locking offscreen render target\n");
|
TRACE("Locking offscreen render target\n");
|
||||||
glReadBuffer(GL_BACK);
|
glReadBuffer(myDevice->offscreenBuffer);
|
||||||
srcIsUpsideDown = TRUE;
|
srcIsUpsideDown = TRUE;
|
||||||
} else {
|
} else {
|
||||||
if(iface == swapchain->frontBuffer) {
|
if(iface == swapchain->frontBuffer) {
|
||||||
|
@ -1087,8 +1087,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
|
||||||
if(!swapchain) {
|
if(!swapchain) {
|
||||||
/* Primary offscreen render target */
|
/* Primary offscreen render target */
|
||||||
TRACE("Offscreen render target\n");
|
TRACE("Offscreen render target\n");
|
||||||
glDrawBuffer(GL_BACK);
|
glDrawBuffer(myDevice->offscreenBuffer);
|
||||||
checkGLcall("glDrawBuffer(GL_BACK)");
|
checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
|
||||||
} else {
|
} else {
|
||||||
if(iface == swapchain->frontBuffer) {
|
if(iface == swapchain->frontBuffer) {
|
||||||
TRACE("Onscreen front buffer\n");
|
TRACE("Onscreen front buffer\n");
|
||||||
|
@ -1118,7 +1118,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
|
||||||
flush_to_framebuffer_texture(This);
|
flush_to_framebuffer_texture(This);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!swapchain || swapchain->backBuffer) {
|
if(!swapchain) {
|
||||||
|
glDrawBuffer(myDevice->offscreenBuffer);
|
||||||
|
checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
|
||||||
|
} else if(swapchain->backBuffer) {
|
||||||
glDrawBuffer(GL_BACK);
|
glDrawBuffer(GL_BACK);
|
||||||
checkGLcall("glDrawBuffer(GL_BACK)");
|
checkGLcall("glDrawBuffer(GL_BACK)");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1730,7 +1733,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
|
||||||
|
|
||||||
glGetIntegerv(GL_READ_BUFFER, &prevRead);
|
glGetIntegerv(GL_READ_BUFFER, &prevRead);
|
||||||
vcheckGLcall("glGetIntegerv");
|
vcheckGLcall("glGetIntegerv");
|
||||||
glReadBuffer(GL_BACK);
|
glReadBuffer(This->resource.wineD3DDevice->offscreenBuffer);
|
||||||
vcheckGLcall("glReadBuffer");
|
vcheckGLcall("glReadBuffer");
|
||||||
|
|
||||||
glCopyTexImage2D(This->glDescription.target,
|
glCopyTexImage2D(This->glDescription.target,
|
||||||
|
@ -1891,7 +1894,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const ch
|
||||||
|
|
||||||
glGetIntegerv(GL_READ_BUFFER, &prevRead);
|
glGetIntegerv(GL_READ_BUFFER, &prevRead);
|
||||||
vcheckGLcall("glGetIntegerv");
|
vcheckGLcall("glGetIntegerv");
|
||||||
glReadBuffer(GL_BACK);
|
glReadBuffer(swapChain ? GL_BACK : This->resource.wineD3DDevice->offscreenBuffer);
|
||||||
vcheckGLcall("glReadBuffer");
|
vcheckGLcall("glReadBuffer");
|
||||||
glCopyTexImage2D(GL_TEXTURE_2D,
|
glCopyTexImage2D(GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
|
@ -2179,7 +2182,9 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
|
||||||
/* Bind the target texture */
|
/* Bind the target texture */
|
||||||
glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
|
glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
|
||||||
checkGLcall("glBindTexture");
|
checkGLcall("glBindTexture");
|
||||||
if(!swapchain || (swapchain->backBuffer && SrcSurface == swapchain->backBuffer[0])) {
|
if(!swapchain) {
|
||||||
|
glReadBuffer(myDevice->offscreenBuffer);
|
||||||
|
} else if(swapchain->backBuffer && SrcSurface == swapchain->backBuffer[0]) {
|
||||||
glReadBuffer(GL_BACK);
|
glReadBuffer(GL_BACK);
|
||||||
} else {
|
} else {
|
||||||
glReadBuffer(GL_FRONT);
|
glReadBuffer(GL_FRONT);
|
||||||
|
@ -2775,8 +2780,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
|
||||||
glDrawBuffer(GL_FRONT);
|
glDrawBuffer(GL_FRONT);
|
||||||
checkGLcall("glDrawBuffer(GL_FRONT)");
|
checkGLcall("glDrawBuffer(GL_FRONT)");
|
||||||
} else if(This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
|
} else if(This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
|
||||||
glDrawBuffer(GL_BACK);
|
glDrawBuffer(myDevice->offscreenBuffer);
|
||||||
checkGLcall("glDrawBuffer(GL_BACK)");
|
checkGLcall("glDrawBuffer(myDevice->offscreenBuffer3)");
|
||||||
} else {
|
} else {
|
||||||
TRACE("Surface is higher back buffer, falling back to software\n");
|
TRACE("Surface is higher back buffer, falling back to software\n");
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
|
@ -2793,10 +2798,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
|
||||||
0 /* Stencil */);
|
0 /* Stencil */);
|
||||||
|
|
||||||
/* Restore the original draw buffer */
|
/* Restore the original draw buffer */
|
||||||
if(!dstSwapchain || (dstSwapchain->backBuffer && dstSwapchain->backBuffer[0])) {
|
if(!dstSwapchain) {
|
||||||
|
glDrawBuffer(myDevice->offscreenBuffer);
|
||||||
|
} else if(dstSwapchain->backBuffer && dstSwapchain->backBuffer[0]) {
|
||||||
glDrawBuffer(GL_BACK);
|
glDrawBuffer(GL_BACK);
|
||||||
vcheckGLcall("glDrawBuffer");
|
|
||||||
}
|
}
|
||||||
|
vcheckGLcall("glDrawBuffer");
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,6 +623,7 @@ struct IWineD3DDeviceImpl
|
||||||
|
|
||||||
/* X and GL Information */
|
/* X and GL Information */
|
||||||
GLint maxConcurrentLights;
|
GLint maxConcurrentLights;
|
||||||
|
GLenum offscreenBuffer;
|
||||||
|
|
||||||
/* Selected capabilities */
|
/* Selected capabilities */
|
||||||
int vs_selected_mode;
|
int vs_selected_mode;
|
||||||
|
|
Loading…
Reference in New Issue