H. Verbeet : wined3d: Allow the FBO code to handle multiple render targets.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Dec 20 08:54:56 CST 2006


Module: wine
Branch: master
Commit: 299c1e62bfb879c03e03cab0a1aa000bc4984c8b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=299c1e62bfb879c03e03cab0a1aa000bc4984c8b

Author: H. Verbeet <hverbeet at gmail.com>
Date:   Tue Dec 19 19:25:35 2006 +0100

wined3d: Allow the FBO code to handle multiple render targets.

---

 dlls/wined3d/device.c          |   32 ++++++++++++++++++++++++++------
 dlls/wined3d/directx.c         |    2 ++
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a12781e..8609c55 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -574,6 +574,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_R
 
         HeapFree(GetProcessHeap(), 0, This->render_targets);
 
+        HeapFree(GetProcessHeap(), 0, This->draw_buffers);
+
         /* TODO: Clean up all the surfaces and textures! */
         /* NOTE: You must release the parent if the object was created via a callback
         ** ***************************/
@@ -5794,14 +5796,18 @@ static void set_depth_stencil_fbo(IWineD
     }
 }
 
-static void set_render_target_fbo(IWineD3DDevice *iface, IWineD3DSurface *render_target) {
+static void set_render_target_fbo(IWineD3DDevice *iface, DWORD idx, IWineD3DSurface *render_target) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DSurfaceImpl *rtimpl = (IWineD3DSurfaceImpl *)render_target;
 
-    if (This->render_offscreen) {
-        GLenum texttarget, target;
+    if (idx >= GL_LIMITS(buffers)) {
+        ERR("%p : Trying to set render target %d, but only %d supported\n", This, idx, GL_LIMITS(buffers));
+    }
 
-        bind_fbo(iface);
+    bind_fbo(iface);
+
+    if (rtimpl) {
+        GLenum texttarget, target;
 
         IWineD3DSurface_PreLoad(render_target);
         texttarget = rtimpl->glDescription.target;
@@ -5812,9 +5818,23 @@ static void set_render_target_fbo(IWineD
         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glBindTexture(target, 0);
 
-        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texttarget, rtimpl->glDescription.textureName, 0));
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, texttarget, rtimpl->glDescription.textureName, 0));
         checkGLcall("glFramebufferTexture2DEXT()");
+
+        This->draw_buffers[idx] = GL_COLOR_ATTACHMENT0_EXT + idx;
     } else {
+        GL_EXTCALL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + idx, GL_TEXTURE_2D, 0, 0));
+        checkGLcall("glFramebufferTexture2DEXT()");
+
+        This->draw_buffers[idx] = GL_NONE;
+    }
+
+    if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
+        GL_EXTCALL(glDrawBuffersARB(GL_LIMITS(buffers), This->draw_buffers));
+        checkGLcall("glDrawBuffers()");
+    }
+
+    if (!This->render_offscreen) {
         GL_EXTCALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
         checkGLcall("glBindFramebuffer()");
     }
@@ -5878,7 +5898,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         if (pRenderTarget) IWineD3DSurface_AddRef(pRenderTarget);
 
         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-            set_render_target_fbo(iface, pRenderTarget);
+            set_render_target_fbo(iface, RenderTargetIndex, pRenderTarget);
         }
     }
 
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 839b648..b3b891f 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2450,6 +2450,8 @@ static HRESULT  WINAPI IWineD3DImpl_Crea
 
     object->render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DSurface *) * GL_LIMITS(buffers));
 
+    object->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLenum) * GL_LIMITS(buffers));
+
     /* set the state of the device to valid */
     object->state = WINED3D_OK;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 13d79ed..906619a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -587,6 +587,7 @@ typedef struct IWineD3DDeviceImpl
     BOOL                    render_offscreen;
     WINED3D_DEPTHCOPYSTATE  depth_copy_state;
     GLuint                  fbo;
+    GLenum                  *draw_buffers;
 
     /* Cursor management */
     BOOL                    bCursorVisible;




More information about the wine-cvs mailing list