[1/8] WineD3D: Support for using auxilliary buffers for offscreen
rendering
Stefan Dösinger
stefan at codeweavers.com
Wed Feb 28 10:18:55 CST 2007
-------------- next part --------------
From adfbd88181120de5f3c9de97c8d313c2c7f55d2e Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Tue, 27 Feb 2007 21:32:15 +0100
Subject: [PATCH] WineD3D: Support for using auxilliary buffers for offscreen rendering
OpenGL AUX buffers provide a way for offscreen rendering which is very simmilar 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.
All that is needed is to make the offscreen rendering buffer more flexible, instead of
hardcoding GL_BACK an offscreen buffer is selected at d3d initialization and passed to
glDrawBuffer / glReadBuffer.
---
dlls/wined3d/context.c | 10 ++++++++++
dlls/wined3d/device.c | 22 ++++++++++++++++++++++
dlls/wined3d/surface.c | 29 ++++++++++++++++++-----------
dlls/wined3d/wined3d_private.h | 1 +
4 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index ac2ca44..d087a4c 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -622,6 +622,14 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && oldRenderOffscreen) {
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);
@@ -685,6 +693,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
*/
context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
}
+ glDrawBuffer(This->offscreenBuffer);
+ checkGLcall("glDrawBuffer(This->offscreenBuffer)");
break;
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index e614559..445df6e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1783,6 +1783,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
This->contexts[0]->last_was_rhw = 0;
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);
LEAVE_GL();
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 00199c8..8e5bd88 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -691,7 +691,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
* Read from the back buffer
*/
TRACE("Locking offscreen render target\n");
- glReadBuffer(GL_BACK);
+ glReadBuffer(myDevice->offscreenBuffer);
srcIsUpsideDown = TRUE;
} else {
if(iface == swapchain->frontBuffer) {
@@ -1087,8 +1087,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
if(!swapchain) {
/* Primary offscreen render target */
TRACE("Offscreen render target\n");
- glDrawBuffer(GL_BACK);
- checkGLcall("glDrawBuffer(GL_BACK)");
+ glDrawBuffer(myDevice->offscreenBuffer);
+ checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
} else {
if(iface == swapchain->frontBuffer) {
TRACE("Onscreen front buffer\n");
@@ -1118,7 +1118,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
flush_to_framebuffer_texture(This);
break;
}
- if(!swapchain || swapchain->backBuffer) {
+ if(!swapchain) {
+ glDrawBuffer(myDevice->offscreenBuffer);
+ checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
+ } else if(swapchain->backBuffer) {
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
} else {
@@ -1730,7 +1733,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
glGetIntegerv(GL_READ_BUFFER, &prevRead);
vcheckGLcall("glGetIntegerv");
- glReadBuffer(GL_BACK);
+ glReadBuffer(This->resource.wineD3DDevice->offscreenBuffer);
vcheckGLcall("glReadBuffer");
glCopyTexImage2D(This->glDescription.target,
@@ -1891,7 +1894,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, const ch
glGetIntegerv(GL_READ_BUFFER, &prevRead);
vcheckGLcall("glGetIntegerv");
- glReadBuffer(GL_BACK);
+ glReadBuffer(swapChain ? GL_BACK : This->resource.wineD3DDevice->offscreenBuffer);
vcheckGLcall("glReadBuffer");
glCopyTexImage2D(GL_TEXTURE_2D,
0,
@@ -2179,7 +2182,9 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
/* Bind the target texture */
glBindTexture(GL_TEXTURE_2D, This->glDescription.textureName);
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);
} else {
glReadBuffer(GL_FRONT);
@@ -2775,8 +2780,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer(GL_FRONT)");
} else if(This == (IWineD3DSurfaceImpl *) myDevice->render_targets[0]) {
- glDrawBuffer(GL_BACK);
- checkGLcall("glDrawBuffer(GL_BACK)");
+ glDrawBuffer(myDevice->offscreenBuffer);
+ checkGLcall("glDrawBuffer(myDevice->offscreenBuffer3)");
} else {
TRACE("Surface is higher back buffer, falling back to software\n");
return WINED3DERR_INVALIDCALL;
@@ -2793,10 +2798,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
0 /* Stencil */);
/* 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);
- vcheckGLcall("glDrawBuffer");
}
+ vcheckGLcall("glDrawBuffer");
return WINED3D_OK;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e314fd1..9aac520 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -593,6 +593,7 @@ struct IWineD3DDeviceImpl
/* X and GL Information */
GLint maxConcurrentLights;
+ GLenum offscreenBuffer;
/* Selected capabilities */
int vs_selected_mode;
--
1.4.4.3
More information about the wine-patches
mailing list