Stefan Dösinger : wined3d: Clear unused channels on R32F and R16F textures on readback.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 30 06:20:25 CDT 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Aug 21 22:46:52 2007 +0200

wined3d: Clear unused channels on R32F and R16F textures on readback.

---

 dlls/wined3d/surface.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 2abb277..f8becfe 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1963,6 +1963,41 @@ static BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
     return TRUE;
 }
 
+static inline void clear_unused_channels(IWineD3DSurfaceImpl *This) {
+    GLboolean oldwrite[4];
+
+    /* Some formats have only some color channels, and the others are 1.0.
+     * since our rendering renders to all channels, and those pixel formats
+     * are emulated by using a full texture with the other channels set to 1.0
+     * manually, clear the unused channels.
+     *
+     * This could be done with hacking colorwriteenable to mask the colors,
+     * but before drawing the buffer would have to be cleared too, so there's
+     * no gain in that
+     */
+    switch(This->resource.format) {
+        case WINED3DFMT_R16F:
+        case WINED3DFMT_R32F:
+            TRACE("R16F or R32F format, clearing green, blue and alpha to 1.0\n");
+            /* Do not activate a context, the correct drawable is active already
+             * though just the read buffer is set, make sure to have the correct draw
+             * buffer too
+             */
+            glDrawBuffer(This->resource.wineD3DDevice->offscreenBuffer);
+            glDisable(GL_SCISSOR_TEST);
+            glGetBooleanv(GL_COLOR_WRITEMASK, oldwrite);
+            glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
+            glClearColor(0.0, 1.0, 1.0, 1.0);
+            glClear(GL_COLOR_BUFFER_BIT);
+            glColorMask(oldwrite[0], oldwrite[1], oldwrite[2], oldwrite[3]);
+            if(!This->resource.wineD3DDevice->render_offscreen) glDrawBuffer(GL_BACK);
+            checkGLcall("Unused channel clear\n");
+            break;
+
+        default: break;
+    }
+}
+
 static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
@@ -2027,6 +2062,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
                                          This->pow2Height, format, type);
             }
 
+            clear_unused_channels(This);
+
             glCopyTexSubImage2D(This->glDescription.target,
                                 This->glDescription.level,
                                 0, 0, 0, 0,




More information about the wine-cvs mailing list