Stefan Dösinger : wined3d: Fix D3DFMT_R32F, R16F, G16R16F, ... in the pixel shader.

Alexandre Julliard julliard at winehq.org
Thu Dec 4 09:02:09 CST 2008


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Wed Dec  3 14:53:43 2008 +0100

wined3d: Fix D3DFMT_R32F, R16F, G16R16F, ... in the pixel shader.

This allows us to drop the load time conversion and the clear
readback hack and replaces it with a color fixup in the fixed
function pipeline replacement.

---

 dlls/d3d9/tests/visual.c       |    2 +-
 dlls/wined3d/surface.c         |  130 ----------------------------------------
 dlls/wined3d/utils.c           |   20 ++++++
 dlls/wined3d/wined3d_private.h |    3 -
 4 files changed, 21 insertions(+), 134 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 32031e4..d9399fe 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -8679,7 +8679,7 @@ struct formats {
 };
 
 const struct formats test_formats[] = {
-  { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
+  { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index b34ab49..3e72ad6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -36,7 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE table[256][4], BOOL colorkey);
 static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert);
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This);
 static void surface_remove_pbo(IWineD3DSurfaceImpl *This);
 
 void surface_force_reload(IWineD3DSurface *iface)
@@ -945,8 +944,6 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
                                  This->pow2Height, format, type);
     }
 
-    clear_unused_channels(This);
-
     ENTER_GL();
     /* If !SrcIsUpsideDown we should flip the surface.
      * This can be done using glCopyTexSubImage2D but this
@@ -1703,38 +1700,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             *target_bpp = 2;
             break;
 
-        case WINED3DFMT_R32F:
-            /* Can be loaded in theory with fmt=GL_RED, type=GL_FLOAT, but this fails. The reason
-             * is that D3D expects the undefined green, blue and alpha channels to return 1.0
-             * when sampling, but OpenGL sets green and blue to 0.0 instead. Thus we have to inject
-             * 1.0 instead.
-             *
-             * The alpha channel defaults to 1.0 in opengl, so nothing has to be done about it.
-             */
-            *convert = CONVERT_R32F;
-            *format = GL_RGB;
-            *internal = GL_RGB32F_ARB;
-            *type = GL_FLOAT;
-            *target_bpp = 12;
-            break;
-
-        case WINED3DFMT_R16F:
-            /* Similar to R32F */
-            *convert = CONVERT_R16F;
-            *format = GL_RGB;
-            *internal = GL_RGB16F_ARB;
-            *type = GL_HALF_FLOAT_ARB;
-            *target_bpp = 6;
-            break;
-
-        case WINED3DFMT_G16R16:
-            *convert = CONVERT_G16R16;
-            *format = GL_RGB;
-            *internal = GL_RGB16_EXT;
-            *type = GL_UNSIGNED_SHORT;
-            *target_bpp = 6;
-            break;
-
         default:
             break;
     }
@@ -2062,66 +2027,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
             break;
         }
 
-        case CONVERT_R32F:
-        {
-            unsigned int x, y;
-            const float *Source;
-            float *Dest;
-            for(y = 0; y < height; y++) {
-                Source = (const float *)(src + y * pitch);
-                Dest = (float *) (dst + y * outpitch);
-                for (x = 0; x < width; x++ ) {
-                    float color = (*Source++);
-                    Dest[0] = color;
-                    Dest[1] = 1.0;
-                    Dest[2] = 1.0;
-                    Dest += 3;
-                }
-            }
-            break;
-        }
-
-        case CONVERT_R16F:
-        {
-            unsigned int x, y;
-            const WORD *Source;
-            WORD *Dest;
-            const WORD one = 0x3c00;
-            for(y = 0; y < height; y++) {
-                Source = (const WORD *)(src + y * pitch);
-                Dest = (WORD *) (dst + y * outpitch);
-                for (x = 0; x < width; x++ ) {
-                    WORD color = (*Source++);
-                    Dest[0] = color;
-                    Dest[1] = one;
-                    Dest[2] = one;
-                    Dest += 3;
-                }
-            }
-            break;
-        }
-
-        case CONVERT_G16R16:
-        {
-            unsigned int x, y;
-            const WORD *Source;
-            WORD *Dest;
-
-            for(y = 0; y < height; y++) {
-                Source = (const WORD *)(src + y * pitch);
-                Dest = (WORD *) (dst + y * outpitch);
-                for (x = 0; x < width; x++ ) {
-                    WORD green = (*Source++);
-                    WORD red = (*Source++);
-                    Dest[0] = green;
-                    Dest[1] = red;
-                    Dest[2] = 0xffff;
-                    Dest += 3;
-                }
-            }
-            break;
-        }
-
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
@@ -2273,41 +2178,6 @@ 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;
 
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index cd7ff06..fd4f4ee 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -363,6 +363,26 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
         }
     }
 
+    dst = getFmtIdx(WINED3DFMT_R16F);
+    gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+            0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+    dst = getFmtIdx(WINED3DFMT_R32F);
+    gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+            0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+    dst = getFmtIdx(WINED3DFMT_G16R16);
+    gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+            0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+    dst = getFmtIdx(WINED3DFMT_G16R16F);
+    gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+            0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+    dst = getFmtIdx(WINED3DFMT_G32R32F);
+    gl_info->gl_formats[dst].color_fixup = create_color_fixup_desc(
+            0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 2aa74e7..36ba563 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1693,9 +1693,6 @@ typedef enum {
     CONVERT_Q8W8V8U8,
     CONVERT_V16U16,
     CONVERT_A4L4,
-    CONVERT_R32F,
-    CONVERT_R16F,
-    CONVERT_G16R16,
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);




More information about the wine-cvs mailing list