[3/5] wined3d: Allow the FBO code to handle multiple render targets

H. Verbeet hverbeet at gmail.com
Tue Dec 19 12:25:35 CST 2006


Note that as of this patch, the limit for the number of draw buffers,
and by extension render targets, is still hardcoded to 1. The next
patch will take care of handling that.

Changelog:
  - Allow the FBO code to handle multiple render targets
-------------- next part --------------
---

 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 fc15ca3..bc5fd32 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 @@ #define                         NEEDS_DI
     BOOL                    render_offscreen;
     WINED3D_DEPTHCOPYSTATE  depth_copy_state;
     GLuint                  fbo;
+    GLenum                  *draw_buffers;
 
     /* Cursor management */
     BOOL                    bCursorVisible;


More information about the wine-patches mailing list