[PATCH] WineD3D: Fix D3DFMT_R32F, R16F, G16R16F, ... in the =

Stefan Doesinger stefan at codeweavers.com
Wed Nov 26 21:47:50 CST 2008


pixel shader=0A=
=0A=
This allows us to drop the load time conversion and the clear=0A=
readback hack and replaces it with a color fixup in the fixed=0A=
function pipeline replacement.=0A=
=0A=
We can safely assume that GLSL or at least=0A=
GL_ARB_fragment_program is supported if float textures are=0A=
available because those formats are only really useable with the=0A=
programmable pipeline. (They work with fixed function, but lose=0A=
their advantages, so there's no point in implementing them on a=0A=
card that doesn't do shaders)=0A=
=0A=
I changed an expected result in the d3d9 visual shader. On=0A=
Windows, this format doesn't support post pixel shader blending,=0A=
so it was never tested by that test at least on my hardware. A=0A=
different test also shows that blue =3D 0xff, so I think the change=0A=
to the test is correct. Unfortunately I do not have any directx=0A=
10 hardware to verify this.=0A=
---=0A=
 dlls/d3d9/tests/visual.c          |    2 +-=0A=
 dlls/wined3d/arb_program_shader.c |   10 +++=0A=
 dlls/wined3d/glsl_shader.c        |   11 +++=0A=
 dlls/wined3d/surface.c            |  130 =
-------------------------------------=0A=
 dlls/wined3d/utils.c              |   11 +++=0A=
 dlls/wined3d/wined3d_gl.h         |   23 ++++---=0A=
 dlls/wined3d/wined3d_private.h    |    3 -=0A=
 7 files changed, 45 insertions(+), 145 deletions(-)=0A=
=0A=
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c=0A=
index 32031e4..d9399fe 100644=0A=
--- a/dlls/d3d9/tests/visual.c=0A=
+++ b/dlls/d3d9/tests/visual.c=0A=
@@ -8679,7 +8679,7 @@ struct formats {=0A=
 };=0A=
 =0A=
 const struct formats test_formats[] =3D {=0A=
-  { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},=0A=
+  { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},=0A=
   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },=0A=
   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },=0A=
   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, =
0x00201000 },=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 5d3a546..f386666 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -606,6 +606,16 @@ static void gen_color_correction(SHADER_BUFFER =
*buffer, const char *reg, const c=0A=
             }=0A=
             break;=0A=
 =0A=
+        case set_green_blue_1:=0A=
+            /* D3DFMT_R16F and D3DFMT_R32F */=0A=
+            if(strlen(writemask) >=3D 4) {=0A=
+                shader_addline(buffer, "MOV %s.%c, %s;\n", reg, =
writemask[3], one);=0A=
+            }=0A=
+            if(strlen(writemask) >=3D 3) {=0A=
+                shader_addline(buffer, "MOV %s.%c, %s;\n", reg, =
writemask[2], one);=0A=
+            }=0A=
+            break;=0A=
+=0A=
         case signed_2_no_ba:=0A=
             /* Applies to V8U8, V16U16. Input blue and alpha are 1.0, =
so the output=0A=
              * is 1.0 as well=0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index 7f30888..239dfff 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -1251,6 +1251,17 @@ static void shader_glsl_color_correction(const =
SHADER_OPCODE_ARG *arg)=0A=
             }=0A=
             break;=0A=
 =0A=
+        case set_green_blue_1:=0A=
+            /* D3DFMT_R16F and D3DFMT_R32F */=0A=
+            mask =3D shader_glsl_add_dst_param(arg, arg->dst, =
WINED3DSP_WRITEMASK_2, &dst_param);=0A=
+            mask_size =3D shader_glsl_get_write_mask_size(mask);=0A=
+            if(mask_size >=3D 3) {=0A=
+                shader_addline(arg->buffer, "%s.%c%c =3D vec2(1.0);\n", =
dst_param.reg_name, dst_param.mask_str[2], dst_param.mask_str[3]);=0A=
+            } else if(mask_size >=3D 2) {=0A=
+                shader_addline(arg->buffer, "%s.%c =3D 1.0;\n", =
dst_param.reg_name, dst_param.mask_str[2]);=0A=
+            }=0A=
+            break;=0A=
+=0A=
         case signed_2_no_ba:=0A=
             /* Correct the sign, but leave the blue as it is - it was =
loaded correctly already=0A=
              * V8U8 and V16U16 without GL_NV_texture_shader or =
GL_ATI_envmap_bumpmap=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index 20bc73b..73e0a2a 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -35,7 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);=0A=
 =0A=
 static void d3dfmt_p8_init_palette(IWineD3DSurfaceImpl *This, BYTE =
table[256][4], BOOL colorkey);=0A=
 static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, =
CONVERT_TYPES convert);=0A=
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This);=0A=
 static void surface_remove_pbo(IWineD3DSurfaceImpl *This);=0A=
 =0A=
 void surface_force_reload(IWineD3DSurface *iface)=0A=
@@ -944,8 +943,6 @@ static void =
read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)=0A=
                                  This->pow2Height, format, type);=0A=
     }=0A=
 =0A=
-    clear_unused_channels(This);=0A=
-=0A=
     ENTER_GL();=0A=
     /* If !SrcIsUpsideDown we should flip the surface.=0A=
      * This can be done using glCopyTexSubImage2D but this=0A=
@@ -1702,38 +1699,6 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl =
*This, BOOL need_alpha_ck, BOOL use_=0A=
             *target_bpp =3D 2;=0A=
             break;=0A=
 =0A=
-        case WINED3DFMT_R32F:=0A=
-            /* Can be loaded in theory with fmt=3DGL_RED, =
type=3DGL_FLOAT, but this fails. The reason=0A=
-             * is that D3D expects the undefined green, blue and alpha =
channels to return 1.0=0A=
-             * when sampling, but OpenGL sets green and blue to 0.0 =
instead. Thus we have to inject=0A=
-             * 1.0 instead.=0A=
-             *=0A=
-             * The alpha channel defaults to 1.0 in opengl, so nothing =
has to be done about it.=0A=
-             */=0A=
-            *convert =3D CONVERT_R32F;=0A=
-            *format =3D GL_RGB;=0A=
-            *internal =3D GL_RGB32F_ARB;=0A=
-            *type =3D GL_FLOAT;=0A=
-            *target_bpp =3D 12;=0A=
-            break;=0A=
-=0A=
-        case WINED3DFMT_R16F:=0A=
-            /* Similar to R32F */=0A=
-            *convert =3D CONVERT_R16F;=0A=
-            *format =3D GL_RGB;=0A=
-            *internal =3D GL_RGB16F_ARB;=0A=
-            *type =3D GL_HALF_FLOAT_ARB;=0A=
-            *target_bpp =3D 6;=0A=
-            break;=0A=
-=0A=
-        case WINED3DFMT_G16R16:=0A=
-            *convert =3D CONVERT_G16R16;=0A=
-            *format =3D GL_RGB;=0A=
-            *internal =3D GL_RGB16_EXT;=0A=
-            *type =3D GL_UNSIGNED_SHORT;=0A=
-            *target_bpp =3D 6;=0A=
-            break;=0A=
-=0A=
         default:=0A=
             break;=0A=
     }=0A=
@@ -2061,66 +2026,6 @@ static HRESULT d3dfmt_convert_surface(const BYTE =
*src, BYTE *dst, UINT pitch, UI=0A=
             break;=0A=
         }=0A=
 =0A=
-        case CONVERT_R32F:=0A=
-        {=0A=
-            unsigned int x, y;=0A=
-            const float *Source;=0A=
-            float *Dest;=0A=
-            for(y =3D 0; y < height; y++) {=0A=
-                Source =3D (const float *)(src + y * pitch);=0A=
-                Dest =3D (float *) (dst + y * outpitch);=0A=
-                for (x =3D 0; x < width; x++ ) {=0A=
-                    float color =3D (*Source++);=0A=
-                    Dest[0] =3D color;=0A=
-                    Dest[1] =3D 1.0;=0A=
-                    Dest[2] =3D 1.0;=0A=
-                    Dest +=3D 3;=0A=
-                }=0A=
-            }=0A=
-            break;=0A=
-        }=0A=
-=0A=
-        case CONVERT_R16F:=0A=
-        {=0A=
-            unsigned int x, y;=0A=
-            const WORD *Source;=0A=
-            WORD *Dest;=0A=
-            const WORD one =3D 0x3c00;=0A=
-            for(y =3D 0; y < height; y++) {=0A=
-                Source =3D (const WORD *)(src + y * pitch);=0A=
-                Dest =3D (WORD *) (dst + y * outpitch);=0A=
-                for (x =3D 0; x < width; x++ ) {=0A=
-                    WORD color =3D (*Source++);=0A=
-                    Dest[0] =3D color;=0A=
-                    Dest[1] =3D one;=0A=
-                    Dest[2] =3D one;=0A=
-                    Dest +=3D 3;=0A=
-                }=0A=
-            }=0A=
-            break;=0A=
-        }=0A=
-=0A=
-        case CONVERT_G16R16:=0A=
-        {=0A=
-            unsigned int x, y;=0A=
-            const WORD *Source;=0A=
-            WORD *Dest;=0A=
-=0A=
-            for(y =3D 0; y < height; y++) {=0A=
-                Source =3D (const WORD *)(src + y * pitch);=0A=
-                Dest =3D (WORD *) (dst + y * outpitch);=0A=
-                for (x =3D 0; x < width; x++ ) {=0A=
-                    WORD green =3D (*Source++);=0A=
-                    WORD red =3D (*Source++);=0A=
-                    Dest[0] =3D green;=0A=
-                    Dest[1] =3D red;=0A=
-                    Dest[2] =3D 0xffff;=0A=
-                    Dest +=3D 3;=0A=
-                }=0A=
-            }=0A=
-            break;=0A=
-        }=0A=
-=0A=
         default:=0A=
             ERR("Unsupported conversation type %d\n", convert);=0A=
     }=0A=
@@ -2272,41 +2177,6 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) {=0A=
     return TRUE;=0A=
 }=0A=
 =0A=
-static inline void clear_unused_channels(IWineD3DSurfaceImpl *This) {=0A=
-    GLboolean oldwrite[4];=0A=
-=0A=
-    /* Some formats have only some color channels, and the others are =
1.0.=0A=
-     * since our rendering renders to all channels, and those pixel =
formats=0A=
-     * are emulated by using a full texture with the other channels set =
to 1.0=0A=
-     * manually, clear the unused channels.=0A=
-     *=0A=
-     * This could be done with hacking colorwriteenable to mask the =
colors,=0A=
-     * but before drawing the buffer would have to be cleared too, so =
there's=0A=
-     * no gain in that=0A=
-     */=0A=
-    switch(This->resource.format) {=0A=
-        case WINED3DFMT_R16F:=0A=
-        case WINED3DFMT_R32F:=0A=
-            TRACE("R16F or R32F format, clearing green, blue and alpha =
to 1.0\n");=0A=
-            /* Do not activate a context, the correct drawable is =
active already=0A=
-             * though just the read buffer is set, make sure to have =
the correct draw=0A=
-             * buffer too=0A=
-             */=0A=
-            glDrawBuffer(This->resource.wineD3DDevice->offscreenBuffer);=0A=
-            glDisable(GL_SCISSOR_TEST);=0A=
-            glGetBooleanv(GL_COLOR_WRITEMASK, oldwrite);=0A=
-            glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);=0A=
-            glClearColor(0.0, 1.0, 1.0, 1.0);=0A=
-            glClear(GL_COLOR_BUFFER_BIT);=0A=
-            glColorMask(oldwrite[0], oldwrite[1], oldwrite[2], =
oldwrite[3]);=0A=
-            if(!This->resource.wineD3DDevice->render_offscreen) =
glDrawBuffer(GL_BACK);=0A=
-            checkGLcall("Unused channel clear\n");=0A=
-            break;=0A=
-=0A=
-        default: break;=0A=
-    }=0A=
-}=0A=
-=0A=
 static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface =
*iface, BOOL srgb_mode) {=0A=
     IWineD3DSurfaceImpl *This =3D (IWineD3DSurfaceImpl *)iface;=0A=
 =0A=
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c=0A=
index 7845b8a..e7949b7 100644=0A=
--- a/dlls/wined3d/utils.c=0A=
+++ b/dlls/wined3d/utils.c=0A=
@@ -363,6 +363,17 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)=0A=
         }=0A=
     }=0A=
 =0A=
+    dst =3D getFmtIdx(WINED3DFMT_R16F);=0A=
+    gl_info->gl_formats[dst].conversion_group =3D set_green_blue_1;=0A=
+    dst =3D getFmtIdx(WINED3DFMT_R32F);=0A=
+    gl_info->gl_formats[dst].conversion_group =3D set_green_blue_1;=0A=
+    dst =3D getFmtIdx(WINED3DFMT_G16R16);=0A=
+    gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+    dst =3D getFmtIdx(WINED3DFMT_G16R16F);=0A=
+    gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+    dst =3D getFmtIdx(WINED3DFMT_G32R32F);=0A=
+    gl_info->gl_formats[dst].conversion_group =3D set_blue_1;=0A=
+=0A=
     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and =
GL_NV_texture_shader.=0A=
      * V16U16 is only supported by GL_NV_texture_shader. The formats =
need fixup if=0A=
      * their extensions are not available. GL_ATI_envmap_bumpmap is not =
used because=0A=
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h=0A=
index efd55e0..0194e52 100644=0A=
--- a/dlls/wined3d/wined3d_gl.h=0A=
+++ b/dlls/wined3d/wined3d_gl.h=0A=
@@ -3815,17 +3815,18 @@ typedef BOOL (WINAPI * =
WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFor=0A=
 =0A=
 enum shader_color_conv=0A=
 {=0A=
-    fmtconv_none        =3D 1,=0A=
-    set_blue_1          =3D 2,=0A=
-    signed_2_no_ba      =3D 3,=0A=
-    signed_2            =3D 4,=0A=
-    signed_4            =3D 5,=0A=
-    signed_l6v5u5       =3D 6,=0A=
-    swap_rg_blue_1      =3D 7,=0A=
-    a_to_g_ba_1         =3D 8,=0A=
-    yuv_yuy2            =3D 9,=0A=
-    yuv_uyvy            =3D 10,=0A=
-    yuv_yv12            =3D 11,=0A=
+    fmtconv_none        =3D  1,=0A=
+    set_blue_1          =3D  2,=0A=
+    set_green_blue_1    =3D  3,=0A=
+    signed_2_no_ba      =3D  4,=0A=
+    signed_2            =3D  5,=0A=
+    signed_4            =3D  6,=0A=
+    signed_l6v5u5       =3D  7,=0A=
+    swap_rg_blue_1      =3D  8,=0A=
+    a_to_g_ba_1         =3D  9,=0A=
+    yuv_yuy2            =3D 10,=0A=
+    yuv_uyvy            =3D 11,=0A=
+    yuv_yv12            =3D 12,=0A=
     force_dword         =3D 0x7ffffff=0A=
 };=0A=
 =0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 77579a1..d6ad1fd 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -1575,9 +1575,6 @@ typedef enum {=0A=
     CONVERT_Q8W8V8U8,=0A=
     CONVERT_V16U16,=0A=
     CONVERT_A4L4,=0A=
-    CONVERT_R32F,=0A=
-    CONVERT_R16F,=0A=
-    CONVERT_G16R16,=0A=
 } CONVERT_TYPES;=0A=
 =0A=
 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);=0A=
-- =0A=
1.5.6.4=0A=
=0A=

------=_NextPart_000_000D_01C9502F.C39C86B0--




More information about the wine-patches mailing list