Module: wine Branch: master Commit: 97987bed7025436df0abe76842798d78b8e4e536 URL: http://source.winehq.org/git/wine.git/?a=commit;h=97987bed7025436df0abe76842...
Author: Józef Kucia joseph.kucia@gmail.com Date: Sun May 13 23:00:07 2012 +0200
d3dx9: Add DDS support in D3DXCreateTextureFromFile functions.
---
dlls/d3dx9_36/d3dx9_36_private.h | 2 + dlls/d3dx9_36/surface.c | 41 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/tests/texture.c | 44 ++++++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/texture.c | 23 ++++++++++++++++--- 4 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index 9405a0f..be460f2 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, 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, 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 ef4baef..ba8487d 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -377,6 +377,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, 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, const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) { diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index f3422e6..60017ec 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -25,6 +25,32 @@ #include "d3dx9tex.h" #include "resources.h"
+/* 2x2 16-bit dds, no mipmaps */ +static const unsigned char dds_16bit[] = { +0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00, +0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, +0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00, +0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f +}; + +/* 2x2 24-bit dds, 2 mipmaps */ +static const unsigned char dds_24bit[] = { +0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00, +0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, +0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00, +0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +}; + /* 4x4 cube map dds */ static const unsigned char dds_cube_map[] = { 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00, @@ -1106,6 +1132,23 @@ static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device) IDirect3DVolumeTexture9_Release(tex); }
+static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device) +{ + HRESULT hr; + IDirect3DTexture9 *texture; + + hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture); + ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory 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); + + hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit) - 1, &texture); + ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); +} + static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device) { HRESULT hr; @@ -1229,6 +1272,7 @@ START_TEST(texture) test_D3DXFillTexture(device); test_D3DXFillCubeTexture(device); test_D3DXFillVolumeTexture(device); + test_D3DXCreateTextureFromFileInMemory(device); test_D3DXCreateCubeTextureFromFileInMemory(device); test_D3DXCreateVolumeTextureFromFileInMemory(device);
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 001c5a7..07e3d02 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, 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)) {