[PATCH 4/5] d3dx9: Allow loading DDS volume textures into 2D textures. (resend)

Matteo Bruni mbruni at codeweavers.com
Mon Mar 3 10:48:14 CST 2014


---
 dlls/d3dx9_36/d3dx9_36_private.h |  3 ++-
 dlls/d3dx9_36/surface.c          | 17 +++++++++++++---
 dlls/d3dx9_36/tests/texture.c    | 43 +++++++++++++++++++++++++++++++++++++---
 dlls/d3dx9_36/texture.c          | 11 ++++++++--
 4 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 0aef8cd..492b665 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -88,7 +88,8 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
     const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette) DECLSPEC_HIDDEN;
 
 HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
-    DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
+        DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info,
+        unsigned int *loaded_miplevels) DECLSPEC_HIDDEN;
 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
     const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
 HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 5e87d94..97c71bf 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -539,7 +539,8 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *d
 }
 
 HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
-    DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info)
+        DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info,
+        unsigned int *loaded_miplevels)
 
 {
     HRESULT hr;
@@ -553,13 +554,21 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data,
     const struct dds_header *header = src_data;
     const BYTE *pixels = (BYTE *)(header + 1);
 
-    /* Loading a cube texture as a simple texture is also supported (only first face texture is taken) */
-    if ((src_info->ResourceType != D3DRTYPE_TEXTURE) && (src_info->ResourceType != D3DRTYPE_CUBETEXTURE))
+    /* Loading a cube texture as a simple texture is also supported
+     * (only first face texture is taken). Same with volume textures. */
+    if ((src_info->ResourceType != D3DRTYPE_TEXTURE)
+            && (src_info->ResourceType != D3DRTYPE_CUBETEXTURE)
+            && (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE))
+    {
+        WARN("Trying to load a %u resource as a 2D texture, returning failure.\n", src_info->ResourceType);
         return D3DXERR_INVALIDDATA;
+    }
 
     width = src_info->Width;
     height = src_info->Height;
     mip_levels = min(src_info->MipLevels, IDirect3DTexture9_GetLevelCount(texture));
+    if (src_info->ResourceType == D3DRTYPE_VOLUMETEXTURE)
+        mip_levels = 1;
     for (mip_level = 0; mip_level < mip_levels; mip_level++)
     {
         hr = calculate_dds_surface_size(src_info->Format, width, height, &src_pitch, &mip_level_size);
@@ -578,6 +587,8 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data,
         height = max(1, height / 2);
     }
 
+    *loaded_miplevels = mip_levels;
+
     return D3D_OK;
 }
 
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index 4a93ac6..a2fc551 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -25,7 +25,7 @@
 #include "d3dx9tex.h"
 #include "resources.h"
 
-static int has_2d_dxt5, has_cube_dxt5;
+static int has_2d_dxt3, has_2d_dxt5, has_cube_dxt5;
 
 /* 2x2 16-bit dds, no mipmaps */
 static const unsigned char dds_16bit[] = {
@@ -1433,6 +1433,7 @@ static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
     D3DSURFACE_DESC desc;
     D3DLOCKED_RECT lock_rect;
     int i;
+    DWORD level_count;
 
     hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
@@ -1464,12 +1465,46 @@ static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
         if (SUCCEEDED(hr))
         {
             for (i = 0; i < 16; i++)
-                ok(((BYTE*)lock_rect.pBits)[i] == dds_cube_map[128+i], "Byte at index %u is 0x%02x, expected 0x%02x\n", i, ((BYTE*)lock_rect.pBits)[i], dds_cube_map[144+i]);
+                ok(((BYTE *)lock_rect.pBits)[i] == dds_cube_map[128 + i],
+                        "Byte at index %u is 0x%02x, expected 0x%02x.\n",
+                        i, ((BYTE *)lock_rect.pBits)[i], dds_cube_map[128 + i]);
             IDirect3DTexture9_UnlockRect(texture, 0);
         }
         IDirect3DTexture9_Release(texture);
 
     }
+
+    /* Volume textures work too. */
+    hr = D3DXCreateTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &texture);
+    if (has_2d_dxt3)
+        ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
+    else
+        todo_wine ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
+    if (SUCCEEDED(hr))
+    {
+        type = IDirect3DTexture9_GetType(texture);
+        ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
+        level_count = IDirect3DBaseTexture9_GetLevelCount((IDirect3DBaseTexture9 *)texture);
+        todo_wine ok(level_count == 3, "Texture has %u mip levels, 3 expected.\n", level_count);
+        hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+        ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
+        ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
+        ok(desc.Height == 4, "Height is %u, expected 4.\n", desc.Height);
+
+        hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+        ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x.\n", hr, D3D_OK);
+        if (SUCCEEDED(hr))
+        {
+            for (i = 0; i < 16; ++i)
+                ok(((BYTE *)lock_rect.pBits)[i] == dds_volume_map[128 + i],
+                        "Byte at index %u is 0x%02x, expected 0x%02x.\n",
+                        i, ((BYTE *)lock_rect.pBits)[i], dds_volume_map[128 + i]);
+            IDirect3DTexture9_UnlockRect(texture, 0);
+        }
+        /* The lower texture levels are apparently generated by filtering the level 0 surface
+         * I.e. following levels from the file are ignored. */
+        IDirect3DTexture9_Release(texture);
+    }
 }
 
 static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
@@ -1821,7 +1856,9 @@ START_TEST(texture)
         return;
     }
 
-    /* Check whether DXT5 textures are supported */
+    /* Check whether DXTn textures are supported. */
+    has_2d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+            D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5);
     has_2d_dxt5 = SUCCEEDED(hr);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index be86347..f5f754d 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -602,6 +602,12 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
         FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
         miplevels = imginfo.MipLevels;
     }
+    if (imginfo.ResourceType == D3DRTYPE_VOLUMETEXTURE
+            && D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5 && miplevels > 1)
+    {
+        FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet.\n");
+        miplevels = 1;
+    }
 
     if (((file_width) && (width != imginfo.Width))    ||
         ((file_height) && (height != imginfo.Height)) ||
@@ -640,10 +646,12 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
         IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
         hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
         IDirect3DSurface9_Release(surface);
+        loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
     }
     else
     {
-        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo);
+        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo,
+                &loaded_miplevels);
     }
 
     if (FAILED(hr))
@@ -654,7 +662,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
         return hr;
     }
 
-    loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(*texptr), imginfo.MipLevels);
     hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
     if (FAILED(hr))
     {
-- 
1.8.3.2




More information about the wine-patches mailing list