Stefan Dösinger : wined3d: General signed format correction without native signed formats.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 21 17:02:50 CDT 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Wed Mar 21 00:06:04 2007 +0100

wined3d: General signed format correction without native signed formats.

Implement signed d3d formats for D3DFMT_V8U8 and D3DFMT_Q8W8V8U8 if no
suitable opengl signed format is supported.

---

 dlls/wined3d/arb_program_shader.c |   30 +++++++++++++------------
 dlls/wined3d/surface.c            |   43 ++++++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 24 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 56ef5fb..f2c58ff 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -382,6 +382,8 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param,
 static void shader_hw_sample(SHADER_OPCODE_ARG* arg, DWORD sampler_idx, const char *dst_str, const char *coord_reg) {
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *) deviceImpl->stateBlock->textures[sampler_idx];
+    WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(((IWineD3DDeviceImpl *)(This->baseShader.device))->wineD3D))->gl_info;
 
     SHADER_BUFFER* buffer = arg->buffer;
     DWORD sampler_type = arg->reg_maps->samplers[sampler_idx] & WINED3DSP_TEXTURETYPE_MASK;
@@ -414,6 +416,19 @@ static void shader_hw_sample(SHADER_OPCODE_ARG* arg, DWORD sampler_idx, const ch
     } else {
         shader_addline(buffer, "TEX %s, %s, texture[%u], %s;\n", dst_str, coord_reg, sampler_idx, tex_type);
     }
+
+    /* Signedness correction */
+    if(!GL_SUPPORT(NV_TEXTURE_SHADER3) /* Provides signed formats */ && texture) {
+        WINED3DFORMAT format = texture->baseTexture.format;
+
+        if((format == WINED3DFMT_V8U8 && !GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) ||
+            format == WINED3DFMT_Q8W8V8U8 ||
+            format == WINED3DFMT_V16U16) {
+            shader_addline(buffer, "MAD %s, %s, coefmul.x, -one;\n", dst_str, dst_str);
+        } else if(format == WINED3DFMT_X8L8V8U8) {
+            shader_addline(buffer, "MAD %s.rg, %s, coefmul.x, -one;\n", dst_str, dst_str);
+        }
+    }
 }
 
 
@@ -694,7 +709,6 @@ void pshader_hw_texreg2gb(SHADER_OPCODE_ARG* arg) {
 
 void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
-    WineD3D_GL_Info *gl_info = &((IWineD3DImpl *)(((IWineD3DDeviceImpl *)(This->baseShader.device))->wineD3D))->gl_info;
 
     DWORD dst = arg->dst;
     DWORD src = arg->src[0] & WINED3DSP_REGNUM_MASK;
@@ -709,19 +723,7 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
     pshader_get_register_name(dst, reg_coord);
 
     if(This->bumpenvmatconst) {
-        /*shader_addline(buffer, "MOV T%u, fragment.texcoord[%u];\n", 1, 1); Not needed - done already */
-
-        /* Plain GL does not have any signed formats suitable for that instruction.
-         * So the surface loading code converts the -128 ... 127 signed integers to
-         * 0 ... 255 unsigned ones. The following line undoes that.
-         *
-         * TODO: GL_ATI_envmap_bumpmap supports D3DFMT_DU8DV8 only. If conversion for other formats
-         * is implemented check the texture format.
-         *
-         * TODO: Move that to the common sampling function
-         */
-        if(!GL_SUPPORT(NV_TEXTURE_SHADER3) && !GL_SUPPORT(ATI_ENVMAP_BUMPMAP))
-            shader_addline(buffer, "MAD T%u, T%u, coefmul.x, -one;\n", src, src);
+        /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed */
 
         shader_addline(buffer, "SWZ TMP2, bumpenvmat, x, z, 0, 0;\n");
         shader_addline(buffer, "DP3 TMP.r, TMP2, T%u;\n", src);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e1c754e..8ac924b 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -45,7 +45,10 @@ typedef enum {
     CONVERT_CK_8888,
     CONVERT_CK_8888_ARGB,
     CONVERT_RGB32_888,
-    CONVERT_V8U8
+    CONVERT_V8U8,
+    CONVERT_X8L8V8U8,
+    CONVERT_Q8W8V8U8,
+    CONVERT_V16U16
 } CONVERT_TYPES;
 
 HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *surf);
@@ -1475,37 +1478,37 @@ static HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BO
             *convert = CONVERT_V8U8;
             *format = GL_BGR;
             *internal = GL_RGB8;
-            *type = GL_BYTE;
+            *type = GL_UNSIGNED_BYTE;
             *target_bpp = 3;
             break;
 
         case WINED3DFMT_X8L8V8U8:
             if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
-            FIXME("Conversion for D3D_X8L8V8U8 not implemented\n");
+            *convert = CONVERT_X8L8V8U8;
             *format = GL_BGRA;
             *internal = GL_RGBA8;
-            *type = GL_BYTE;
+            *type = GL_UNSIGNED_BYTE;
             *target_bpp = 4;
             /* Not supported by GL_ATI_envmap_bumpmap */
             break;
 
         case WINED3DFMT_Q8W8V8U8:
             if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
-            FIXME("Conversion for D3D_Q8W8V8U8 not implemented\n");
+            *convert = CONVERT_Q8W8V8U8;
             *format = GL_BGRA;
             *internal = GL_RGBA8;
-            *type = GL_BYTE;
+            *type = GL_UNSIGNED_BYTE;
             *target_bpp = 4;
             /* Not supported by GL_ATI_envmap_bumpmap */
             break;
 
         case WINED3DFMT_V16U16:
             if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
-            FIXME("Conversion for D3D_V16U16 not implemented\n");
-            *format = GL_COLOR_INDEX;
-            *internal = GL_COLOR_INDEX;
+            *convert = CONVERT_V16U16;
+            *format = GL_BGR;
+            *internal = GL_RGB16;
             *type = GL_SHORT;
-            *target_bpp = 4;
+            *target_bpp = 6;
             /* What should I do here about GL_ATI_envmap_bumpmap?
              * Convert it or allow data loss by loading it into a 8 bit / channel texture?
              */
@@ -1649,6 +1652,26 @@ HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, UINT pitch, UINT width, UIN
             break;
         }
 
+        case CONVERT_Q8W8V8U8:
+        {
+            unsigned int x, y;
+            DWORD *Source;
+            unsigned char *Dest;
+            for(y = 0; y < height; y++) {
+                Source = (DWORD *) (src + y * pitch);
+                Dest = (unsigned char *) (dst + y * outpitch);
+                for (x = 0; x < width; x++ ) {
+                    long color = (*Source++);
+                    /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
+                    /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
+                    /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
+                    /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
+                    Dest += 4;
+                }
+            }
+            break;
+        }
+
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }




More information about the wine-cvs mailing list