wined3d: Implented signed texture formats via NV_TEXTURE_SHADER

Fabian Bieler der.fabe at gmx.net
Sun Mar 11 18:30:19 CDT 2007


The same patch as before, but with GL_DSDT_NV instead of GL_HILO8_NV as 
suggested by Frank Richter.

On Saturday 10 March 2007 15:02, Fabian Bieler wrote:
> This patch implements D3DFMT_V8U8 and D3DFMT_Q8W8V8U8 via
> NV_TEXTURE_SHADER. This fixes some renderissues in Half-Life 2 with the
> DirectX9 path and the DirectX8 path via GLSL.
>
> Pavel Troller described these issues as:
> "there is too much
> shine all over the game. Not only barrels and weapons, but also faces,
> dresses,
> walls.. It looks like covered by the oil film. There are also some strange
> shadow effects - like that the top of the hand is dark and the bottom is
> bright,
> like if the light would come from the ground."
>
> There are still some issues in the closing cutscene. I'm not sure if this
> is due to different handling of RGBA and QWVU textures by the driver or
> some other bug.
>
> Somebody should probably do the same with ATI_envmap_bumpmap for ATI cards.
-------------- next part --------------
From af015cb7fde5ab338701e260eceb13686c10dcc7 Mon Sep 17 00:00:00 2001
From: Fabian Bieler <der.fabe at gmx.net>
Date: Mon, 12 Mar 2007 00:25:16 +0100
Subject: [PATCH] wined3d: Implented signed texture formats via NV_TEXTURE_SHADER

---
 dlls/wined3d/arb_program_shader.c |    8 +++++---
 dlls/wined3d/device.c             |    6 +++---
 dlls/wined3d/state.c              |    4 ++--
 dlls/wined3d/surface.c            |   11 ++++++-----
 dlls/wined3d/surface_gdi.c        |   15 ++++++++-------
 dlls/wined3d/utils.c              |   32 +++++++++++++++++++++++++++-----
 dlls/wined3d/volume.c             |    2 +-
 dlls/wined3d/wined3d_private.h    |    2 +-
 8 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 79148e5..2e636ad 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -694,6 +694,7 @@ 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;
@@ -714,11 +715,12 @@ void pshader_hw_texbem(SHADER_OPCODE_ARG* arg) {
          * So the surface loading code converts the -128 ... 127 signed integers to
          * 0 ... 255 unsigned ones. The following line undoes that.
          *
-         * TODO: Both GL_NV_texture_shader and GL_ATI_envmap_bumpmap provide pixel formats
-         * suitable for loading the Direct3D perturbation data. If one of them is used, do
+         * TODO: GL_ATI_envmap_bumpmap provides pixel formats
+         * suitable for loading the Direct3D perturbation data. If it is used, do
          * not correct the signedness
          */
-        shader_addline(buffer, "MAD T%u, T%u, coefmul.x, -one;\n", src, src);
+        if(!GL_SUPPORT(NV_TEXTURE_SHADER3))
+            shader_addline(buffer, "MAD T%u, T%u, coefmul.x, -one;\n", src, src);
 
         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/device.c b/dlls/wined3d/device.c
index cff0f19..1f745d8 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -587,7 +587,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     IWineD3DSurfaceImpl *object; /*NOTE: impl ref allowed since this is a create function */
     unsigned int pow2Width, pow2Height;
     unsigned int Size       = 1;
-    const PixelFormatDesc *tableEntry = getFormatDescEntry(Format);
+    const PixelFormatDesc *tableEntry = getFormatDescEntry(&GLINFO_LOCATION, Format);
     TRACE("(%p) Create surface\n",This);
     
     /** FIXME: Check ranges on the inputs are valid 
@@ -951,7 +951,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolume(IWineD3DDevice *iface,
 
     IWineD3DDeviceImpl        *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVolumeImpl        *object; /** NOTE: impl ref allowed since this is a create function **/
-    const PixelFormatDesc *formatDesc  = getFormatDescEntry(Format);
+    const PixelFormatDesc *formatDesc  = getFormatDescEntry(&GLINFO_LOCATION, Format);
 
     D3DCREATERESOURCEOBJECTINSTANCE(object, Volume, WINED3DRTYPE_VOLUME, ((Width * formatDesc->bpp) * Height * Depth))
 
@@ -1835,7 +1835,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, U
     DEVMODEW devmode;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     LONG ret;
-    const PixelFormatDesc *formatDesc  = getFormatDescEntry(pMode->Format);
+    const PixelFormatDesc *formatDesc  = getFormatDescEntry(&GLINFO_LOCATION, pMode->Format);
     RECT clip_rc;
 
     TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format));
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index cf1b7f4..059e6f6 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -349,7 +349,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
         surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
 
         if(surf->CKeyFlags & DDSD_CKSRCBLT) {
-            const PixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format);
+            const PixelFormatDesc *fmt = getFormatDescEntry(&GLINFO_LOCATION, surf->resource.format);
             /* The surface conversion does not do color keying conversion for surfaces that have an alpha
              * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
              * surface has alpha bits
@@ -1595,7 +1595,7 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
         IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
 
         if(surf->CKeyFlags & DDSD_CKSRCBLT &&
-           getFormatDescEntry(surf->resource.format)->alphaMask == 0x00000000) {
+           getFormatDescEntry(&GLINFO_LOCATION, surf->resource.format)->alphaMask == 0x00000000) {
 
             /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
              * On the other hand applications can still use texture combiners apparently. This code takes care that apps
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index c8d39f6..d1142ca 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1168,7 +1168,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
     DWORD *masks;
     HRESULT hr;
     RGBQUAD col[256];
-    const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+    const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
 
     TRACE("(%p)->(%p)\n",This,pHDC);
 
@@ -1383,7 +1383,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) {
 
 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 colorkey_active = need_alpha_ck && (This->CKeyFlags & DDSD_CKSRCBLT);
-    const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+    const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
 
     /* Default values: From the surface */
     *format = formatEntry->glFormat;
@@ -1455,10 +1455,11 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
             break;
 
         case WINED3DFMT_V8U8:
-            /* TODO: GL_NV_texture_shader and GL_ATI_envmap_bumpmap provide suitable formats.
-             * use one of them instead of converting
+            /* TODO: GL_ATI_envmap_bumpmap provides suitable formats.
+             * use it instead of converting
              * Remember to adjust the texbem instruction in the shader
              */
+            if(GL_SUPPORT(NV_TEXTURE_SHADER3)) break;
             *convert = CONVERT_V8U8;
             *format = GL_BGR;
             *internal = GL_RGB8;
@@ -2035,7 +2036,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IWineD3D
 
 HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
-    const PixelFormatDesc *formatEntry = getFormatDescEntry(format);
+    const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, format);
 
     if (This->resource.format != WINED3DFMT_UNKNOWN) {
         FIXME("(%p) : The foramt of the surface must be WINED3DFORMAT_UNKNOWN\n", This);
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index 4565f72..638e305 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -35,6 +35,7 @@
 /* Use the d3d_surface debug channel to have one channel for all surfaces */
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
 WINE_DECLARE_DEBUG_CHANNEL(fps);
+#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
 
 /*****************************************************************************
  * x11_copy_to_screen
@@ -534,7 +535,7 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
         dfmt = This->resource.format;
         slock = dlock;
         sfmt = dfmt;
-        sEntry = getFormatDescEntry(sfmt);
+        sEntry = getFormatDescEntry(&GLINFO_LOCATION, sfmt);
         dEntry = sEntry;
     }
     else
@@ -544,9 +545,9 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
             IWineD3DSurface_LockRect(SrcSurface, &slock, NULL, WINED3DLOCK_READONLY);
             sfmt = Src->resource.format;
         }
-        sEntry = getFormatDescEntry(sfmt);
+        sEntry = getFormatDescEntry(&GLINFO_LOCATION, sfmt);
         dfmt = This->resource.format;
-        dEntry = getFormatDescEntry(dfmt);
+        dEntry = getFormatDescEntry(&GLINFO_LOCATION, dfmt);
         IWineD3DSurface_LockRect(iface, &dlock,NULL,0);
     }
 
@@ -1224,7 +1225,7 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface,
         assert(This->resource.allocatedMemory != NULL);
         sbuf = (BYTE *)This->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp;
         dbuf = (BYTE *)This->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp;
-        sEntry = getFormatDescEntry(Src->resource.format);
+        sEntry = getFormatDescEntry(&GLINFO_LOCATION, Src->resource.format);
         dEntry = sEntry;
     }
     else
@@ -1238,8 +1239,8 @@ IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface,
         dbuf = dlock.pBits;
         TRACE("Dst is at %p, Src is at %p\n", dbuf, sbuf);
 
-        sEntry = getFormatDescEntry(Src->resource.format);
-        dEntry = getFormatDescEntry(This->resource.format);
+        sEntry = getFormatDescEntry(&GLINFO_LOCATION, Src->resource.format);
+        dEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
     }
 
     /* Handle first the FOURCC surfaces... */
@@ -1417,7 +1418,7 @@ const char* filename)
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     static char *output = NULL;
     static int size = 0;
-    const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+    const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
 
     if (This->pow2Width > size) {
         output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pow2Width * 3);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 9c82ef0..d609624 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -27,8 +27,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
 
-#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
-
 /*****************************************************************************
  * Pixel format array
  */
@@ -107,14 +105,31 @@ static const PixelFormatDesc formats[] = {
     {WINED3DFMT_Q16W16V16U16,0x0        ,0x0        ,0x0        ,0x0        ,8      ,FALSE      ,GL_COLOR_INDEX         ,GL_COLOR_INDEX     ,GL_UNSIGNED_SHORT              }
 };
 
-const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
+static const PixelFormatDesc NV_texture_shader_formats[] = {
+    {WINED3DFMT_V8U8        ,0x0        ,0x0        ,0x0        ,0x0        ,2      ,FALSE      ,GL_DSDT8_NV            ,GL_DSDT_NV         ,GL_BYTE                        },
+    {WINED3DFMT_X8L8V8U8    ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,FALSE      ,GL_DSDT8_MAG8_INTENSITY8_NV,GL_DSDT_MAG_INTENSITY_NV,GL_BYTE},
+    {WINED3DFMT_Q8W8V8U8    ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,FALSE      ,GL_SIGNED_RGBA8_NV     ,GL_RGBA            ,GL_BYTE                        },
+    {WINED3DFMT_V16U16      ,0x0        ,0x0        ,0x0        ,0x0        ,4      ,FALSE      ,GL_SIGNED_HILO16_NV    ,GL_HILO_NV         ,GL_SHORT                       }
+};
+
+#define GLINFO_LOCATION      (*gl_info)
+
+const PixelFormatDesc *getFormatDescEntry(WineD3D_GL_Info *gl_info, WINED3DFORMAT fmt)
 {
     /* First check if the format is at the position of its value.
      * This will catch the argb formats before the loop is entered
      */
     if(fmt < (sizeof(formats) / sizeof(formats[0])) && formats[fmt].format == fmt) {
         return &formats[fmt];
-    } else {
+    }
+    if(GL_SUPPORT(NV_TEXTURE_SHADER3)) {
+        unsigned int i;
+        for(i = 0; i < (sizeof(NV_texture_shader_formats) / sizeof(NV_texture_shader_formats[0])); i++) {
+            if(NV_texture_shader_formats[i].format == fmt) {
+                return &NV_texture_shader_formats[i];
+            }
+        }
+    } {
         unsigned int i;
         for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) {
             if(formats[i].format == fmt) {
@@ -122,15 +137,18 @@ const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt)
             }
         }
     }
+
     FIXME("Can't find format %s(%d) in the format lookup table\n", debug_d3dformat(fmt), fmt);
     if(fmt == WINED3DFMT_UNKNOWN) {
         ERR("Format table corrupt - Can't find WINED3DFMT_UNKNOWN\n");
         return NULL;
     }
     /* Get the caller a valid pointer */
-    return getFormatDescEntry(WINED3DFMT_UNKNOWN);
+    return getFormatDescEntry(gl_info, WINED3DFMT_UNKNOWN);
 }
 
+#undef GLINFO_LOCATION
+
 /*****************************************************************************
  * Trace formatting of useful values
  */
@@ -787,6 +805,8 @@ static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP
     return FALSE;
 }
 
+#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
+
 void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
     tex_op_args tex_op_args = {{0}, {0}, {0}};
@@ -1085,6 +1105,8 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
     LEAVE_GL();
 }
 
+#undef GLINFO_LOCATION
+
 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
     /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
      * input should be used for all input components. The WINED3DTA_COMPLEMENT
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 3fb3036..3ad9c00 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -264,7 +264,7 @@ static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWi
 
 static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) {
     IWineD3DVolumeImpl *This     = (IWineD3DVolumeImpl *)iface;
-    const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format);
+    const PixelFormatDesc *formatEntry = getFormatDescEntry(&GLINFO_LOCATION, This->resource.format);
 
     if(GL_SUPPORT(EXT_TEXTURE3D)) {
         TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n",
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index df0ff6a..5670c83 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1936,5 +1936,5 @@ typedef struct {
     GLint                   glInternal, glFormat, glType;
 } PixelFormatDesc;
 
-const PixelFormatDesc *getFormatDescEntry(WINED3DFORMAT fmt);
+const PixelFormatDesc *getFormatDescEntry(WineD3D_GL_Info *gl_info, WINED3DFORMAT fmt);
 #endif
-- 
1.4.4.1



More information about the wine-patches mailing list