[10/12] WineD3D: Support for using auxilliary buffers for offscreen rendering

Stefan Dösinger stefan at codeweavers.com
Mon Feb 26 09:04:15 CST 2007


Another patch that seemed to have issues on the first try
-------------- next part --------------
From a0c3ade89f2ed85142f531c8c27a6f40ac2617ac Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sun, 25 Feb 2007 22:53:02 +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 8545568..c978962 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -640,6 +640,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);
 
@@ -709,6 +717,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                          */
                         context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
                     }
+                    glDrawBuffer(This->offscreenBuffer);
+                    checkGLcall("glDrawBuffer(This->offscreenBuffer)");
                     break;
             }
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0d765c0..609549f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1795,6 +1795,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 b779704..f014f48 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -689,7 +689,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) {
@@ -1086,8 +1086,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");
@@ -1117,7 +1117,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 {
@@ -1729,7 +1732,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,
@@ -1890,7 +1893,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,
@@ -2178,7 +2181,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);
@@ -2794,8 +2799,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;
@@ -2812,10 +2817,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 fa4232c..b5cbbd3 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