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

Stefan Dösinger stefan at codeweavers.com
Wed Dec 3 07:53:43 CST 2008


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.

We can safely assume that GLSL or at least
GL_ARB_fragment_program is supported if float textures are
available because those formats are only really useable with the
programmable pipeline. (They work with fixed function, but lose
their advantages, so there's no point in implementing them on a
card that doesn't do shaders)

I changed an expected result in the d3d9 visual shader. On
Windows, this format doesn't support post pixel shader blending,
so it was never tested by that test at least on my hardware. A
different test also shows that blue = 0xff, so I think the change
to the test is correct. Unfortunately I do not have any directx
10 hardware to verify this.
---
 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);
-- 
1.5.6.4



--------------000609050902050001040601--



More information about the wine-patches mailing list