[5/8] d3dx9: Add DDS support in D3DXCreateTextureFromFile functions.

Józef Kucia joseph.kucia at gmail.com
Wed May 9 16:32:08 CDT 2012


---
 dlls/d3dx9_36/d3dx9_36_private.h |    2 +
 dlls/d3dx9_36/surface.c          |   41 ++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/tests/surface.c    |   15 +++++++++++++
 dlls/d3dx9_36/texture.c          |   23 +++++++++++++++++---
 4 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index d258de5..4ef8cff 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -62,6 +62,8 @@ HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer,
 const PixelFormatDesc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
 const PixelFormatDesc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
 
+HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, UINT srd_data_size,
+    const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
     UINT src_data_size, 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 8a6dc0e..4594735 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -375,6 +375,47 @@ static HRESULT get_image_info_from_dds(const void *buffer, UINT length, D3DXIMAG
    return D3D_OK;
 }
 
+HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, UINT srd_data_size,
+    const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info)
+{
+    HRESULT hr;
+    RECT src_rect;
+    UINT src_pitch;
+    UINT mip_level;
+    UINT mip_levels;
+    UINT mip_level_size;
+    UINT width, height;
+    IDirect3DSurface9 *surface;
+    const struct dds_header *header = src_data;
+    const BYTE *pixels = (BYTE *)(header + 1);
+
+    if (src_info->ResourceType != D3DRTYPE_TEXTURE)
+        return D3DXERR_INVALIDDATA;
+
+    width = src_info->Width;
+    height = src_info->Height;
+    mip_levels = min(src_info->MipLevels, IDirect3DTexture9_GetLevelCount(texture));
+    for (mip_level = 0; mip_level < mip_levels; mip_level++)
+    {
+        hr = calculate_dds_surface_size(src_info, width, height, &src_pitch, &mip_level_size);
+        if (FAILED(hr)) return hr;
+
+        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;
+
+        pixels += mip_level_size;
+        width = max(1, width / 2);
+        height = max(1, height / 2);
+    }
+
+    return D3D_OK;
+}
+
 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data, UINT src_data_size,
     const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
 {
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index ab56593..3d5a50f 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -917,6 +917,20 @@ static void test_D3DXCreateVolumeTexture(IDirect3DDevice9 *device)
     }
 }
 
+static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
+{
+    HRESULT hr;
+    IDirect3DTexture9 *texture;
+
+    hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
+    ok(hr == D3D_OK, "D3DCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+    hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &texture);
+    ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+}
+
 static void test_D3DXSaveSurfaceToFile(IDirect3DDevice9 *device)
 {
     HRESULT hr;
@@ -1035,6 +1049,7 @@ START_TEST(surface)
     test_D3DXLoadSurface(device);
     test_D3DXCreateCubeTexture(device);
     test_D3DXCreateVolumeTexture(device);
+    test_D3DXCreateTextureFromFileInMemory(device);
     test_D3DXSaveSurfaceToFile(device);
 
     check_release((IUnknown*)device, 0);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index a75cc28..2bae4fb 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -504,6 +504,7 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
     BOOL file_width = FALSE, file_height = FALSE;
     BOOL file_format = FALSE, file_miplevels = FALSE;
     D3DXIMAGE_INFO imginfo;
+    UINT loaded_miplevels;
     D3DCAPS9 caps;
     HRESULT hr;
 
@@ -571,6 +572,12 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
         return hr;
     }
 
+    if (imginfo.MipLevels < miplevels && (D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5))
+    {
+        FIXME("Generation of mipmaps for compressed pixel formats is not implemented yet\n");
+        miplevels = imginfo.MipLevels;
+    }
+
     if (((file_width) && (width != imginfo.Width))    ||
         ((file_height) && (height != imginfo.Height)) ||
         ((file_format) && (format != imginfo.Format)) ||
@@ -601,9 +608,16 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
     }
 
     /* Load the file */
-    IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
-    hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
-    IDirect3DSurface9_Release(surface);
+    if (imginfo.ImageFileFormat != D3DXIFF_DDS)
+    {
+        IDirect3DTexture9_GetSurfaceLevel(*texptr, 0, &surface);
+        hr = D3DXLoadSurfaceFromFileInMemory(surface, palette, NULL, srcdata, srcdatasize, NULL, filter, colorkey, NULL);
+        IDirect3DSurface9_Release(surface);
+    }
+    else
+    {
+        hr = load_texture_from_dds(*texptr, srcdata, srcdatasize, palette, filter, colorkey, &imginfo);
+    }
 
     if (FAILED(hr))
     {
@@ -612,7 +626,8 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
         return hr;
     }
 
-    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, 0, mipfilter);
+    loaded_miplevels = min(miplevels, imginfo.MipLevels);
+    hr = D3DXFilterTexture((IDirect3DBaseTexture9*) *texptr, palette, loaded_miplevels - 1, mipfilter);
 
     if (FAILED(hr))
     {
-- 
1.7.8.6




More information about the wine-patches mailing list