Matteo Bruni : d3dx9: Support skipping mip levels in D3DXCreateTextureFromFileInMemoryEx.

Alexandre Julliard julliard at winehq.org
Wed Mar 5 14:12:32 CST 2014


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

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Wed Mar  5 18:35:18 2014 +0100

d3dx9: Support skipping mip levels in D3DXCreateTextureFromFileInMemoryEx.

---

 dlls/d3dx9_36/d3dx9_36_private.h |    2 +-
 dlls/d3dx9_36/surface.c          |   23 +++++++++++++----------
 dlls/d3dx9_36/tests/texture.c    |   19 +++++++++++++++++++
 dlls/d3dx9_36/texture.c          |   26 ++++++++++++++++++++++----
 include/d3dx9tex.h               |    5 +++++
 5 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 492b665..79f3b76 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -88,7 +88,7 @@ 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,
+        DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels,
         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;
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 97c71bf..09c2fce 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -539,9 +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 skip_levels,
         unsigned int *loaded_miplevels)
-
 {
     HRESULT hr;
     RECT src_rect;
@@ -569,25 +568,29 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data,
     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++)
+    for (mip_level = 0; mip_level < mip_levels + skip_levels; ++mip_level)
     {
         hr = calculate_dds_surface_size(src_info->Format, width, height, &src_pitch, &mip_level_size);
         if (FAILED(hr)) return hr;
 
-        SetRect(&src_rect, 0, 0, width, height);
+        if (mip_level >= skip_levels)
+        {
+            SetRect(&src_rect, 0, 0, width, height);
 
-        IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface);
-        hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, src_info->Format, src_pitch,
-            NULL, &src_rect, filter, color_key);
-        IDirect3DSurface9_Release(surface);
-        if (FAILED(hr)) return hr;
+            IDirect3DTexture9_GetSurfaceLevel(texture, mip_level - skip_levels, &surface);
+            hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, src_info->Format, src_pitch,
+                    NULL, &src_rect, filter, color_key);
+            IDirect3DSurface9_Release(surface);
+            if (FAILED(hr))
+                return hr;
+        }
 
         pixels += mip_level_size;
         width = max(1, width / 2);
         height = max(1, height / 2);
     }
 
-    *loaded_miplevels = mip_levels;
+    *loaded_miplevels = mip_levels - skip_levels;
 
     return D3D_OK;
 }
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index a2fc551..631a658 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -1511,6 +1511,9 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
 {
     HRESULT hr;
     IDirect3DTexture9 *texture;
+    unsigned int miplevels;
+    IDirect3DSurface9 *surface;
+    D3DSURFACE_DESC desc;
 
     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
         0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
@@ -1522,6 +1525,22 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
 
+    hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit), D3DX_DEFAULT,
+            D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+            D3DX_DEFAULT, D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_FILTER_POINT), 0, NULL, NULL, &texture);
+    ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
+    if (SUCCEEDED(hr))
+    {
+        miplevels = IDirect3DTexture9_GetLevelCount(texture);
+        ok(miplevels == 1, "Got miplevels %u, expected %u\n", miplevels, 1);
+        IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+        IDirect3DSurface9_GetDesc(surface, &desc);
+        ok(desc.Width == 1 && desc.Height == 1,
+                "Surface dimensions are %ux%u, expected 1x1.\n", desc.Width, desc.Height);
+        IDirect3DSurface9_Release(surface);
+        IDirect3DTexture9_Release(texture);
+    }
+
     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
     {
         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index f5f754d..32415a2 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -529,12 +529,15 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
     BOOL file_format = FALSE, file_miplevels = FALSE;
     BOOL dynamic_texture;
     D3DXIMAGE_INFO imginfo;
-    UINT loaded_miplevels;
+    UINT loaded_miplevels, skip_levels;
     D3DCAPS9 caps;
     HRESULT hr;
 
-    TRACE("(%p, %p, %u, %u, %u, %u, %x, %x, %x, %u, %u, %x, %p, %p, %p)\n", device, srcdata, srcdatasize, width,
-        height, miplevels, usage, format, pool, filter, mipfilter, colorkey, srcinfo, palette, texture);
+    TRACE("device %p, srcdata %p, srcdatasize %u, width %u, height %u, miplevels %u,"
+            " usage %#x, format %#x, pool %#x, filter %#x, mipfilter %#x, colorkey %#x,"
+            " srcinfo %p, palette %p, texture %p.\n",
+            device, srcdata, srcdatasize, width, height, miplevels, usage, format, pool,
+            filter, mipfilter, colorkey, srcinfo, palette, texture);
 
     /* check for invalid parameters */
     if (!device || !texture || !srcdata || !srcdatasize)
@@ -588,6 +591,21 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
         miplevels = imginfo.MipLevels;
     }
 
+    skip_levels = mipfilter != D3DX_DEFAULT ? mipfilter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0;
+    if (skip_levels && imginfo.MipLevels > skip_levels)
+    {
+        TRACE("Skipping the first %u (of %u) levels of a DDS mipmapped texture.\n",
+                skip_levels, imginfo.MipLevels);
+        TRACE("Texture level 0 dimensions are %ux%u.\n", imginfo.Width, imginfo.Height);
+        width >>= skip_levels;
+        height >>= skip_levels;
+        miplevels -= skip_levels;
+    }
+    else
+    {
+        skip_levels = 0;
+    }
+
     /* fix texture creation parameters */
     hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool);
     if (FAILED(hr))
@@ -650,7 +668,7 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
     }
     else
     {
-        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo,
+        hr = load_texture_from_dds(*texptr, srcdata, palette, filter, colorkey, &imginfo, skip_levels,
                 &loaded_miplevels);
     }
 
diff --git a/include/d3dx9tex.h b/include/d3dx9tex.h
index 205d897..542460f 100644
--- a/include/d3dx9tex.h
+++ b/include/d3dx9tex.h
@@ -39,6 +39,11 @@
 #define D3DX_FILTER_SRGB_OUT             0x00400000
 #define D3DX_FILTER_SRGB                 0x00600000
 
+#define D3DX_SKIP_DDS_MIP_LEVELS_MASK    0x1f
+#define D3DX_SKIP_DDS_MIP_LEVELS_SHIFT   26
+#define D3DX_SKIP_DDS_MIP_LEVELS(l, f)   ((((l) & D3DX_SKIP_DDS_MIP_LEVELS_MASK) \
+        << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT) | ((f) == D3DX_DEFAULT ? D3DX_FILTER_BOX : (f)))
+
 #define D3DX_NORMALMAP_MIRROR_U          0x00010000
 #define D3DX_NORMALMAP_MIRROR_V          0x00020000
 #define D3DX_NORMALMAP_MIRROR            0x00030000




More information about the wine-cvs mailing list