Nice that you found a way to support this format :-)

Can you separate the compressed data loading changes from the ATI1N specific changes? I will make regression testing easier if anything should break.

Do you have an app that needs this format? I think a test would be a good idea.

Am 07.06.2009 um 09:48 schrieb Frank Richter:

---
dlls/wined3d/device.c       |    5 +-
dlls/wined3d/directx.c      |    8 +++
dlls/wined3d/surface.c      |  110
++++++++++++++++++++++++-------------------
dlls/wined3d/surface_base.c |    6 +-
dlls/wined3d/utils.c        |    6 ++
include/wine/wined3d.idl    |    1 +
6 files changed, 82 insertions(+), 54 deletions(-)


diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index f1dd938..a08f713 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -920,10 +920,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface,
    mul_4h = (Height + 3) & ~3;
    if (WINED3DFMT_UNKNOWN == Format) {
        Size = 0;
-    } else if (Format == WINED3DFMT_DXT1) {
-        /* DXT1 is half byte per pixel */
+ } else if (Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_ATI1N) {
+        /* DXT1, ATI1N are half byte per pixel */
        Size = (mul_4w * glDesc->byte_count * mul_4h) >> 1;
-
} else if (Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 || Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5 ||
               Format == WINED3DFMT_ATI2N) {
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 4a2a270..60045aa 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2467,6 +2467,14 @@ static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
            return FALSE;

        /* Vendor specific formats */
+        case WINED3DFMT_ATI1N:
+            if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
+                TRACE_(d3d_caps)("[OK]\n");
+                return TRUE;
+            }
+            TRACE_(d3d_caps)("[FAILED]\n");
+            return FALSE;
+
        case WINED3DFMT_ATI2N:
if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) { shader_backend = select_shader_backend(adapter, DeviceType);
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 2f5554f..6469fa4 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -132,6 +132,25 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
    return FALSE;
}

+/* Download data for a compressed surface */
+static void surface_download_data_compressed(IWineD3DSurfaceImpl *This, const struct GlPixelFormatDesc *format_desc) { + TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p\n", + This, This->glDescription.level, format_desc->glFormat, format_desc->glType,
+           This->resource.allocatedMemory);
+
+    if(This->Flags & SFLAG_PBO) {
+       GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
+       checkGLcall("glBindBufferARB");
+ GL_EXTCALL(glGetCompressedTexImageARB(This->glDescription.target, This->glDescription.level, NULL));
+       checkGLcall("glGetCompressedTexImageARB()");
+       GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+       checkGLcall("glBindBufferARB");
+    } else {
+ GL_EXTCALL(glGetCompressedTexImageARB(This->glDescription.target, This->glDescription.level, This->resource.allocatedMemory));
+       checkGLcall("glGetCompressedTexImageARB()");
+    }
+}
+
/* This call just downloads data, the caller is responsible for activating the
 * right context and binding the correct texture. */
static void surface_download_data(IWineD3DSurfaceImpl *This) {
@@ -145,31 +164,19 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
    }

    ENTER_GL();
-
- if (format_desc->format == WINED3DFMT_DXT1 || format_desc- >format == WINED3DFMT_DXT2 - || format_desc->format == WINED3DFMT_DXT3 || format_desc->format == WINED3DFMT_DXT4 - || format_desc->format == WINED3DFMT_DXT5 || format_desc->format == WINED3DFMT_ATI2N)
-    {
+
+ if (format_desc->format == WINED3DFMT_DXT1 || format_desc- >format == WINED3DFMT_DXT2 + || format_desc->format == WINED3DFMT_DXT3 || format_desc- >format == WINED3DFMT_DXT4
+           || format_desc->format == WINED3DFMT_DXT5) {
if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* We can assume this as the texture would not have been created otherwise */ FIXME("(%p) : Attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
        } else {
- TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p\n", - This, This->glDescription.level, format_desc- >glFormat, format_desc->glType,
-                    This->resource.allocatedMemory);
-
-            if(This->Flags & SFLAG_PBO) {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
-                checkGLcall("glBindBufferARB");
- GL_EXTCALL(glGetCompressedTexImageARB(This- >glDescription.target, This->glDescription.level, NULL));
-                checkGLcall("glGetCompressedTexImageARB()");
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
-                checkGLcall("glBindBufferARB");
-            } else {
- GL_EXTCALL(glGetCompressedTexImageARB(This- >glDescription.target, This->glDescription.level, This- >resource.allocatedMemory));
-                checkGLcall("glGetCompressedTexImageARB()");
-            }
+           surface_download_data_compressed(This, format_desc);
        }
        LEAVE_GL();
+ } else if (format_desc->format == WINED3DFMT_ATI1N || format_desc->format == WINED3DFMT_ATI2N) {
+       surface_download_data_compressed(This, format_desc);
+        LEAVE_GL();
    } else {
        void *mem;
        GLenum format = format_desc->glFormat;
@@ -286,6 +293,35 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
    This->Flags |= SFLAG_INSYSMEM;
}

+/* Upload data for a compressed surface */
+static void surface_upload_data_compressed(IWineD3DSurfaceImpl *This, const struct GlPixelFormatDesc *format_desc, + GLenum internal, GLsizei width, GLsizei height, const GLvoid *data) { + /* glCompressedTexSubImage2D for uploading and glTexImage2D for allocating does not work well on some drivers(r200 dri, MacOS ATI driver) + * glCompressedTexImage2D does not accept NULL pointers. So for compressed textures surface_allocate_surface does nothing, and this + * function uses glCompressedTexImage2D instead of the SubImage call
+     */
+ TRACE("(%p) : Calling glCompressedTexSubImage2D w %d, h %d, data %p\n", This, width, height, data);
+    ENTER_GL();
+
+    if(This->Flags & SFLAG_PBO) {
+       GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
+       checkGLcall("glBindBufferARB");
+       TRACE("(%p) pbo: %#x, data: %p\n", This, This->pbo, data);
+
+ GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
+               width, height, 0 /* border */, This->resource.size, NULL));
+       checkGLcall("glCompressedTexSubImage2D");
+
+       GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+       checkGLcall("glBindBufferARB");
+    } else {
+ GL_EXTCALL(glCompressedTexImage2DARB(This->glDescription.target, This->glDescription.level, internal,
+               width, height, 0 /* border */, This->resource.size, data));
+       checkGLcall("glCompressedTexSubImage2D");
+    }
+    LEAVE_GL();
+}
+
/* This call just uploads data, the caller is responsible for activating the
 * right context and binding the correct texture. */
static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data) { @@ -293,38 +329,16 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi

if (format_desc->heightscale != 1.0 && format_desc->heightscale ! = 0.0) height *= format_desc->heightscale;

- if (format_desc->format == WINED3DFMT_DXT1 || format_desc- >format == WINED3DFMT_DXT2 - || format_desc->format == WINED3DFMT_DXT3 || format_desc->format == WINED3DFMT_DXT4 - || format_desc->format == WINED3DFMT_DXT5 || format_desc->format == WINED3DFMT_ATI2N)
-    {
+ if (format_desc->format == WINED3DFMT_DXT1 || format_desc- >format == WINED3DFMT_DXT2 + || format_desc->format == WINED3DFMT_DXT3 || format_desc- >format == WINED3DFMT_DXT4
+           || format_desc->format == WINED3DFMT_DXT5) {
        if (!GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
            FIXME("Using DXT1/3/5 without advertized support\n");
        } else {
- /* glCompressedTexSubImage2D for uploading and glTexImage2D for allocating does not work well on some drivers(r200 dri, MacOS ATI driver) - * glCompressedTexImage2D does not accept NULL pointers. So for compressed textures surface_allocate_surface does nothing, and this - * function uses glCompressedTexImage2D instead of the SubImage call
-             */
- TRACE("(%p) : Calling glCompressedTexSubImage2D w %d, h %d, data %p\n", This, width, height, data);
-            ENTER_GL();
-
-            if(This->Flags & SFLAG_PBO) {
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-                checkGLcall("glBindBufferARB");
- TRACE("(%p) pbo: %#x, data: %p\n", This, This->pbo, data);
-
- GL_EXTCALL(glCompressedTexImage2DARB(This- >glDescription.target, This->glDescription.level, internal, - width, height, 0 /* border */, This- >resource.size, NULL));
-                checkGLcall("glCompressedTexSubImage2D");
-
- GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
-                checkGLcall("glBindBufferARB");
-            } else {
- GL_EXTCALL(glCompressedTexImage2DARB(This- >glDescription.target, This->glDescription.level, internal, - width, height, 0 /* border */, This- >resource.size, data));
-                checkGLcall("glCompressedTexSubImage2D");
-            }
-            LEAVE_GL();
+ surface_upload_data_compressed(This, format_desc, internal, width, height, data);
        }
+ } else if (format_desc->format == WINED3DFMT_ATI1N || format_desc->format == WINED3DFMT_ATI2N) { + surface_upload_data_compressed(This, format_desc, internal, width, height, data);
    } else {
TRACE("(%p) : Calling glTexSubImage2D w %d, h %d, data, %p \n", This, width, height, data);
        ENTER_GL();
diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c
index d487f80..83cbd9d 100644
--- a/dlls/wined3d/surface_base.c
+++ b/dlls/wined3d/surface_base.c
@@ -339,7 +339,7 @@ DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPitch(IWineD3DSurface *iface) { /* DXTn formats don't have exact pitches as they are to the new row of blocks, where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5) ie pitch = (width/4) * bytes per block */
-    if (format == WINED3DFMT_DXT1) /* DXT1 is 8 bytes per block */
+ if (format == WINED3DFMT_DXT1 || format == WINED3DFMT_ATI1N) /* DXT1, ATI1N are 8 bytes per block */
        ret = ((This->currentDesc.Width + 3) >> 2) << 3;
    else if (format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 ||
format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */ @@ -521,8 +521,8 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3D TRACE("(%p) : Setting texture format to (%d,%s)\n", This, format, debug_d3dformat(format));
    if (format == WINED3DFMT_UNKNOWN) {
        This->resource.size = 0;
-    } else if (format == WINED3DFMT_DXT1) {
-        /* DXT1 is half byte per pixel */
+ } else if (format == WINED3DFMT_DXT1 || format == WINED3DFMT_ATI1N) {
+        /* DXT1, ATI1N are half byte per pixel */
This->resource.size = ((max(This->pow2Width, 4) * format_desc->byte_count) * max(This->pow2Height, 4)) >> 1;

} else if (format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 ||
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index f141a3b..822ce14 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -129,6 +129,7 @@ static const struct StaticPixelFormatDesc formats[] = {WINED3DFMT_R32_UINT, 0x0, 0x0, 0x0, 0x0, 4, 0, 0, FALSE}, {WINED3DFMT_R16G16B16A16_SNORM, 0x0, 0x0, 0x0, 0x0, 8, 0, 0, FALSE},
    /* Vendor-specific formats */
+ {WINED3DFMT_ATI1N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE }, {WINED3DFMT_ATI2N, 0x0, 0x0, 0x0, 0x0, 1, 0, 0, TRUE }, {WINED3DFMT_NVHU, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE }, {WINED3DFMT_NVHS, 0x0, 0x0, 0x0, 0x0, 2, 0, 0, TRUE }, @@ -459,6 +460,10 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
            WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
            EXT_PACKED_DEPTH_STENCIL},
    /* Vendor-specific formats */
+ {WINED3DFMT_ATI1N, GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_RED_RGTC1_EXT, 0,
+            GL_RED,                 GL_UNSIGNED_BYTE,
+            0,
+            EXT_TEXTURE_COMPRESSION_RGTC},
{WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
            GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE,
            0,
@@ -868,6 +873,7 @@ const char* debug_d3dformat(WINED3DFORMAT fmt) {
    FMT_TO_STR(WINED3DFMT_D24FS8);
    FMT_TO_STR(WINED3DFMT_VERTEXDATA);
    FMT_TO_STR(WINED3DFMT_CxV8U8);
+    FMT_TO_STR(WINED3DFMT_ATI1N);
    FMT_TO_STR(WINED3DFMT_ATI2N);
    FMT_TO_STR(WINED3DFMT_NVHU);
    FMT_TO_STR(WINED3DFMT_NVHS);
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index 51d886c..6d087fd 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -272,6 +272,7 @@ cpp_quote("#define WINED3DFMT_MULTI2_ARGB8 WINEMAKEFOURCC('M', 'E', 'T', '1')") cpp_quote("#define WINED3DFMT_G8R8_G8B8 WINEMAKEFOURCC('G', 'R', 'G', 'B')") cpp_quote("#define WINED3DFMT_R8G8_B8G8 WINEMAKEFOURCC('R', 'G', 'B', 'G')")
/* Vendor specific formats */
+cpp_quote("#define WINED3DFMT_ATI1N WINEMAKEFOURCC('A', 'T', 'I', '1')") cpp_quote("#define WINED3DFMT_ATI2N WINEMAKEFOURCC('A', 'T', 'I', '2')") cpp_quote("#define WINED3DFMT_NVHU WINEMAKEFOURCC('N', 'V', 'H', 'U')") cpp_quote("#define WINED3DFMT_NVHS WINEMAKEFOURCC('N', 'V', 'H', 'S')")





Reply via email to