[PATCH] WineD3D: Support ATI's D3DFMT_ATI2N format=0A=

Stefan Doesinger stefan at codeweavers.com
Wed Jul 23 10:33:10 CDT 2008


=0A=
This is an ATI specific format designed for compressed normal=0A=
maps, and quite a few games check for its existance. While it is=0A=
an ATI-specific "extension" in d3d9, it is a core part of=0A=
D3D10(DXGI_FORMAT_BC5), and supported on Geforce 8 cards.=0A=
=0A=
This patch implements it using the ATI extension, another patch=0A=
will add support for the EXT extension as well=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c |   17 +++++++++++++++++=0A=
 dlls/wined3d/device.c             |    3 ++-=0A=
 dlls/wined3d/directx.c            |   10 ++++++++++=0A=
 dlls/wined3d/glsl_shader.c        |   20 ++++++++++++++++++++=0A=
 dlls/wined3d/surface.c            |   12 ++++++++----=0A=
 dlls/wined3d/utils.c              |   13 +++++++++++++=0A=
 include/wine/wined3d_gl.h         |    6 ++++++=0A=
 include/wine/wined3d_types.h      |    2 ++=0A=
 8 files changed, 78 insertions(+), 5 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 83a7ed8..9f074ad 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -816,6 +816,23 @@ static void =
shader_arb_color_correction(SHADER_OPCODE_ARG* arg) {=0A=
             }=0A=
             break;=0A=
 =0A=
+        case WINED3DFMT_ATI2N:=0A=
+            /* GL_ATI_texture_compression_3dc returns the two channels =
as luminance-alpha,=0A=
+             * which means the first one is replicated accross .rgb, =
and the 2nd one is in=0A=
+             * .a. We need the 2nd in .g=0A=
+             */=0A=
+            if(strlen(writemask) =3D=3D 5) {=0A=
+                /* Swap y and z (U and L), and do a sign conversion on =
x and the new y(V and U) */=0A=
+                shader_addline(arg->buffer, "MOV %s.%c, %s.%c;\n",=0A=
+                               reg, writemask[2], reg, writemask[4]);=0A=
+            } else if(strlen(writemask) =3D=3D 2) {=0A=
+                /* Nothing to do */=0A=
+            } else {=0A=
+                /* This is bad: We have VL, but we need VU */=0A=
+                FIXME("2 or 3 components sampled from a converted ATI2N =
texture\n");=0A=
+            }=0A=
+            break;=0A=
+=0A=
             /* stupid compiler */=0A=
         default:=0A=
             break;=0A=
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c=0A=
index b3db3b7..0a6bd2b 100644=0A=
--- a/dlls/wined3d/device.c=0A=
+++ b/dlls/wined3d/device.c=0A=
@@ -641,7 +641,8 @@ static HRESULT  WINAPI =
IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U=0A=
        Size =3D ((max(Width,4) * tableEntry->bpp) * max(Height,4)) >> 1;=0A=
 =0A=
     } else if (Format =3D=3D WINED3DFMT_DXT2 || Format =3D=3D =
WINED3DFMT_DXT3 ||=0A=
-               Format =3D=3D WINED3DFMT_DXT4 || Format =3D=3D =
WINED3DFMT_DXT5) {=0A=
+               Format =3D=3D WINED3DFMT_DXT4 || Format =3D=3D =
WINED3DFMT_DXT5 ||=0A=
+               Format =3D=3D WINED3DFMT_ATI2N) {=0A=
        Size =3D ((max(Width,4) * tableEntry->bpp) * max(Height,4));=0A=
     } else {=0A=
        /* The pitch is a multiple of 4 bytes */=0A=
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c=0A=
index f353739..f4bc0ee 100644=0A=
--- a/dlls/wined3d/directx.c=0A=
+++ b/dlls/wined3d/directx.c=0A=
@@ -59,6 +59,7 @@ static const struct {=0A=
     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE,    =
    0                           },=0A=
     {"GL_ATI_envmap_bumpmap",               ATI_ENVMAP_BUMPMAP,         =
    0                           },=0A=
     {"GL_ATI_fragment_shader",              ATI_FRAGMENT_SHADER,        =
    0                           },=0A=
+    {"GL_ATI_texture_compression_3dc",      =
ATI_TEXTURE_COMPRESSION_3DC,    0                           },=0A=
 =0A=
     /* ARB */=0A=
     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT,     =
    0                           },=0A=
@@ -2371,6 +2372,15 @@ static BOOL CheckTextureCapability(UINT Adapter, =
WINED3DFORMAT CheckFormat)=0A=
             TRACE_(d3d_caps)("[FAILED]\n");=0A=
             return FALSE;=0A=
 =0A=
+        /* Vendor specific formats */=0A=
+        case WINED3DFMT_ATI2N:=0A=
+            if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {=0A=
+                TRACE_(d3d_caps)("[OK]\n");=0A=
+                return TRUE;=0A=
+            }=0A=
+            TRACE_(d3d_caps)("[FAILED]\n");=0A=
+            return FALSE;=0A=
+=0A=
         case WINED3DFMT_UNKNOWN:=0A=
             return FALSE;=0A=
 =0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index da13d1d..7a20ae1 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -1344,6 +1344,26 @@ static void =
shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {=0A=
             }=0A=
             break;=0A=
 =0A=
+        case WINED3DFMT_ATI2N:=0A=
+            /* GL_ATI_texture_compression_3dc returns the two channels =
as luminance-alpha,=0A=
+             * which means the first one is replicated accross .rgb, =
and the 2nd one is in=0A=
+             * .a. We need the 2nd in .g=0A=
+             */=0A=
+            mask =3D shader_glsl_add_dst_param(arg, arg->dst, =
WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);=0A=
+            mask_size =3D shader_glsl_get_write_mask_size(mask);=0A=
+            if(mask_size =3D=3D 4) {=0A=
+                /* Swap y and z (U and L), and do a sign conversion on =
x and the new y(V and U) */=0A=
+                shader_addline(arg->buffer, "%s.%c =3D %s.%c;\n",=0A=
+                               dst_param.reg_name, =
dst_param.mask_str[2],=0A=
+                               dst_param.reg_name, =
dst_param.mask_str[4]);=0A=
+            } else if(mask_size =3D=3D 1) {=0A=
+                /* Nothing to do */=0A=
+            } else {=0A=
+                FIXME("%u components sampled from a converted ATI2N =
texture\n", mask_size);=0A=
+                /* This is bad: We have .r[gb], but we need .ra */=0A=
+            }=0A=
+            break;=0A=
+=0A=
             /* stupid compiler */=0A=
         default:=0A=
             break;=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index cd312bc..2227243 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -93,7 +93,8 @@ static void surface_download_data(IWineD3DSurfaceImpl =
*This) {=0A=
 =0A=
     if (This->resource.format =3D=3D WINED3DFMT_DXT1 ||=0A=
             This->resource.format =3D=3D WINED3DFMT_DXT2 || =
This->resource.format =3D=3D WINED3DFMT_DXT3 ||=0A=
-            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5) {=0A=
+            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5 ||=0A=
+            This->resource.format =3D=3D WINED3DFMT_ATI2N) {=0A=
         if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can =
assume this as the texture would not have been created otherwise */=0A=
             FIXME("(%p) : Attempting to lock a compressed texture when =
texture compression isn't supported by opengl\n", This);=0A=
         } else {=0A=
@@ -232,7 +233,8 @@ static void =
surface_download_data(IWineD3DSurfaceImpl *This) {=0A=
 static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum =
internal, GLsizei width, GLsizei height, GLenum format, GLenum type, =
const GLvoid *data) {=0A=
     if (This->resource.format =3D=3D WINED3DFMT_DXT1 ||=0A=
             This->resource.format =3D=3D WINED3DFMT_DXT2 || =
This->resource.format =3D=3D WINED3DFMT_DXT3 ||=0A=
-            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5) {=0A=
+            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5 ||=0A=
+            This->resource.format =3D=3D WINED3DFMT_ATI2N) {=0A=
         if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {=0A=
             FIXME("Using DXT1/3/5 without advertized support\n");=0A=
         } else {=0A=
@@ -296,7 +298,8 @@ static void =
surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,=0A=
 =0A=
     if (This->resource.format =3D=3D WINED3DFMT_DXT1 ||=0A=
             This->resource.format =3D=3D WINED3DFMT_DXT2 || =
This->resource.format =3D=3D WINED3DFMT_DXT3 ||=0A=
-            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5) {=0A=
+            This->resource.format =3D=3D WINED3DFMT_DXT4 || =
This->resource.format =3D=3D WINED3DFMT_DXT5 ||=0A=
+            This->resource.format =3D=3D WINED3DFMT_ATI2N) {=0A=
         /* glCompressedTexImage2D does not accept NULL pointers, so we =
cannot allocate a compressed texture without uploading data */=0A=
         TRACE("Not allocating compressed surfaces, surface_upload_data =
will specify them\n");=0A=
 =0A=
@@ -3771,7 +3774,8 @@ static HRESULT WINAPI =
IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {=0A=
         WINED3DFORMAT Format =3D This->resource.format;=0A=
         /** TODO: add support for non power two compressed textures **/=0A=
         if (Format =3D=3D WINED3DFMT_DXT1 || Format =3D=3D =
WINED3DFMT_DXT2 || Format =3D=3D WINED3DFMT_DXT3=0A=
-            || Format =3D=3D WINED3DFMT_DXT4 || Format =3D=3D =
WINED3DFMT_DXT5) {=0A=
+            || Format =3D=3D WINED3DFMT_DXT4 || Format =3D=3D =
WINED3DFMT_DXT5=0A=
+            || This->resource.format =3D=3D WINED3DFMT_ATI2N) {=0A=
             FIXME("(%p) Compressed non-power-two textures are not =
supported w(%d) h(%d)\n",=0A=
                   This, This->currentDesc.Width, =
This->currentDesc.Height);=0A=
             return WINED3DERR_NOTAVAILABLE;=0A=
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c=0A=
index dd18b27..370f50b 100644=0A=
--- a/dlls/wined3d/utils.c=0A=
+++ b/dlls/wined3d/utils.c=0A=
@@ -112,6 +112,8 @@ static const StaticPixelFormatDesc formats[] =3D {=0A=
     {WINED3DFMT_INDEX16     ,0x0        ,0x0        ,0x0        ,0x0    =
    ,2      ,0      ,0          ,FALSE },=0A=
     {WINED3DFMT_INDEX32     ,0x0        ,0x0        ,0x0        ,0x0    =
    ,4      ,0      ,0          ,FALSE },=0A=
     {WINED3DFMT_Q16W16V16U16,0x0        ,0x0        ,0x0        ,0x0    =
    ,8      ,0      ,0          ,FALSE },=0A=
+    /* Vendor-specific formats */=0A=
+    {WINED3DFMT_ATI2N       ,0x0        ,0x0        ,0x0        ,0x0    =
    ,1      ,0      ,0          ,TRUE  },=0A=
 };=0A=
 =0A=
 typedef struct {=0A=
@@ -260,6 +262,9 @@ static const GlPixelFormatDescTemplate =
gl_formats_template[] =3D {=0A=
     {WINED3DFMT_INDEX32        ,0                                ,0     =
                                 , 0,           0                        =
 ,0=0A=
         ,0 },=0A=
     {WINED3DFMT_Q16W16V16U16   ,GL_COLOR_INDEX                   =
,GL_COLOR_INDEX                         , 0,           GL_COLOR_INDEX    =
        ,GL_UNSIGNED_SHORT=0A=
+        ,0 },=0A=
+    /* Vendor-specific formats */=0A=
+    {WINED3DFMT_ATI2N          ,0                                ,0     =
                                 , 0,           GL_LUMINANCE_ALPHA       =
 ,GL_UNSIGNED_BYTE=0A=
         ,0 }=0A=
 };=0A=
 =0A=
@@ -390,6 +395,13 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)=0A=
          */=0A=
     }=0A=
 =0A=
+    if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {=0A=
+        dst =3D getFmtIdx(WINED3DFMT_ATI2N);=0A=
+        gl_info->gl_formats[dst].glInternal =3D =
GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;=0A=
+        gl_info->gl_formats[dst].glGammaInternal =3D =
GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;=0A=
+        gl_info->gl_formats[dst].conversion_group=3D WINED3DFMT_ATI2N;=0A=
+    }=0A=
+=0A=
     return TRUE;=0A=
 }=0A=
 =0A=
@@ -519,6 +531,7 @@ const char* debug_d3dformat(WINED3DFORMAT fmt) {=0A=
     FMT_TO_STR(WINED3DFMT_G32R32F);=0A=
     FMT_TO_STR(WINED3DFMT_A32B32G32R32F);=0A=
     FMT_TO_STR(WINED3DFMT_CxV8U8);=0A=
+    FMT_TO_STR(WINED3DFMT_ATI2N);=0A=
 #undef FMT_TO_STR=0A=
   default:=0A=
     {=0A=
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h=0A=
index 04471df..533c991 100644=0A=
--- a/include/wine/wined3d_gl.h=0A=
+++ b/include/wine/wined3d_gl.h=0A=
@@ -2991,6 +2991,11 @@ typedef void (WINE_GLAPI =
*PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const=0A=
 #define GL_NEGATE_BIT_ATI                   0x00000004=0A=
 #define GL_BIAS_BIT_ATI                     0x00000008=0A=
 #endif=0A=
+/* GL_ATI_texture_compression_3dc */=0A=
+#ifndef GL_ATI_texture_compression_3dc=0A=
+#define GL_ATI_texture_compression_3dc=0A=
+#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837=0A=
+#endif=0A=
 =0A=
 /* GL_VERSION_2_0 */=0A=
 #ifndef GL_VERSION_2_0=0A=
@@ -3357,6 +3362,7 @@ typedef enum _GL_SupportedExt {=0A=
   EXT_VERTEX_SHADER,=0A=
   ATI_ENVMAP_BUMPMAP,=0A=
   ATI_FRAGMENT_SHADER,=0A=
+  ATI_TEXTURE_COMPRESSION_3DC,=0A=
   /* APPLE */=0A=
   APPLE_FENCE,=0A=
   APPLE_CLIENT_STORAGE,=0A=
diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h=0A=
index 45a947d..c67c311 100644=0A=
--- a/include/wine/wined3d_types.h=0A=
+++ b/include/wine/wined3d_types.h=0A=
@@ -303,6 +303,8 @@ typedef enum _WINED3DFORMAT {=0A=
     =0A=
     WINED3DFMT_CxV8U8               =3D 117,=0A=
 =0A=
+    /* Vendor specific formats */=0A=
+    WINED3DFMT_ATI2N                =3D  WINEMAKEFOURCC('A', 'T', 'I', =
'2'),=0A=
 =0A=
     WINED3DFMT_FORCE_DWORD          =3D 0xFFFFFFFF=0A=
 } WINED3DFORMAT;=0A=
-- =0A=
1.5.4.5=0A=
=0A=

------=_NextPart_000_000F_01C8ECB6.02173EE0--




More information about the wine-patches mailing list