H. Verbeet : wined3d: Allow wined3d 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: e4fc45e0fe2bae4e6653b54267e0419d51c66d72
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e4fc45e0fe2bae4e6653b54267e0419d51c66d72

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

wined3d: Allow wined3d to handle multiple render targets.

---

 dlls/wined3d/device.c      |   28 +++++++++++++++++-----------
 dlls/wined3d/directx.c     |   13 +++++++------
 dlls/wined3d/glsl_shader.c |   12 ++++--------
 3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 8609c55..53ab337 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5643,11 +5643,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl
 static HRESULT  WINAPI  IWineD3DDeviceImpl_GetRenderTarget(IWineD3DDevice* iface,DWORD RenderTargetIndex, IWineD3DSurface **ppRenderTarget) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
-    /* FIXME: Implelent RenderTargetIndex >0 */
-    if(RenderTargetIndex > 0)
-        FIXME("(%p) : RenderTargetIndex %d >0 not currently supported\n", This, RenderTargetIndex);
+    if (RenderTargetIndex >= GL_LIMITS(buffers)) {
+        ERR("(%p) : Only %d render targets are supported.\n", This, GL_LIMITS(buffers));
+        return WINED3DERR_INVALIDCALL;
+    }
 
-    *ppRenderTarget = This->render_targets[0];
+    *ppRenderTarget = This->render_targets[RenderTargetIndex];
     TRACE("(%p) : RenderTarget %d Index returning %p\n", This, RenderTargetIndex, *ppRenderTarget);
     /* Note inc ref on returned surface */
     if(*ppRenderTarget != NULL)
@@ -5849,10 +5850,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
     HRESULT  hr = WINED3D_OK;
     WINED3DVIEWPORT viewport;
 
-    TRACE("(%p) Swapping rendertarget\n",This);
-    if (RenderTargetIndex > 0) {
-        FIXME("(%p) Render targets other than the first are not supported\n",This);
-        RenderTargetIndex = 0;
+    TRACE("(%p) : Setting rendertarget %d to %p\n", This, RenderTargetIndex, pRenderTarget);
+
+    if (RenderTargetIndex >= GL_LIMITS(buffers)) {
+        ERR("(%p) : Only %d render targets are supported.\n", This, GL_LIMITS(buffers));
+        return WINED3DERR_INVALIDCALL;
     }
 
     /* MSDN says that null disables the render target
@@ -5867,7 +5869,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         return WINED3DERR_INVALIDCALL;
     }
     /* TODO: replace Impl* usage with interface usage */
-    if (!((IWineD3DSurfaceImpl *)pRenderTarget)->resource.usage & WINED3DUSAGE_RENDERTARGET) {
+    if (pRenderTarget && !((IWineD3DSurfaceImpl *)pRenderTarget)->resource.usage & WINED3DUSAGE_RENDERTARGET) {
         FIXME("(%p)Trying to set the render target to a surface(%p) that wasn't created with a usage of WINED3DUSAGE_RENDERTARGET\n",This ,pRenderTarget);
         return WINED3DERR_INVALIDCALL;
     }
@@ -5875,7 +5877,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl
      *        builds, but I think wine counts as a 'debug' build for now.
       ******************************/
     /* If we are trying to set what we already have, don't bother */
-    if (pRenderTarget == This->render_targets[0]) {
+    if (pRenderTarget == This->render_targets[RenderTargetIndex]) {
         TRACE("Trying to do a NOP SetRenderTarget operation\n");
     } else {
         /* Otherwise, set the render target up */
@@ -5890,7 +5892,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl
         A shared context implementation will share all buffers between all rendertargets (including swapchains),
         implementations that use separate pbuffers for different swapchains or rendertargets will have to duplicate the
         stencil buffer and incure an extra memory overhead */
-        hr = IWineD3DDeviceImpl_ActiveRender(iface, pRenderTarget);
+        if (RenderTargetIndex == 0) {
+            hr = IWineD3DDeviceImpl_ActiveRender(iface, pRenderTarget);
+        } else {
+            hr = WINED3D_OK;
+        }
 
         /* Replace the render target */
         if (This->render_targets[RenderTargetIndex]) IWineD3DSurface_Release(This->render_targets[RenderTargetIndex]);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index b3b891f..fb65bab 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -804,6 +804,11 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *i
         wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
     }
 
+    /* MRTs are currently only supported when FBOs are used. */
+    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
+        gl_info->max_buffers = 1;
+    }
+
     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
      * in case of the latest videocards in the number of pixel/vertex pipelines.
@@ -2284,12 +2289,8 @@ static HRESULT WINAPI IWineD3DImpl_GetDe
         } else
             *pCaps->DeclTypes                         = 0;
 
-#if 0 /* We don't properly support multiple render targets yet, so disable this for now */
-        if (GL_SUPPORT(ARB_DRAWBUFFERS)) {
-            *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
-        } else    
-#endif
-            *pCaps->NumSimultaneousRTs = 1;
+        *pCaps->NumSimultaneousRTs = GL_LIMITS(buffers);
+
             
         *pCaps->StretchRectFilterCaps             = 0;
         *pCaps->VertexTextureFilterCaps           = 0;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index dffc1aa..17b6a47 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -680,17 +680,13 @@ static void shader_glsl_get_register_nam
             sprintf(tmpStr, "Vsampler%u", reg);
     break;
     case WINED3DSPR_COLOROUT:
+        if (reg >= GL_LIMITS(buffers)) {
+            WARN("Write to render target %u, only %d supported\n", reg, 4);
+        }
         if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
             sprintf(tmpStr, "gl_FragData[%u]", reg);
-            if (reg > 0) {
-                /* TODO: See GL_ARB_draw_buffers */
-                FIXME("Unsupported write to render target %u\n", reg);
-            }
         } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
-            if (reg > 0)
-                WARN("This OpenGL implementation doesn't support writing to multiple render targets!\n");
-            else
-                sprintf(tmpStr, "gl_FragColor");
+            sprintf(tmpStr, "gl_FragColor");
         }
     break;
     case WINED3DSPR_RASTOUT:




More information about the wine-cvs mailing list