Module: wine Branch: master Commit: 596557a57acd1bc800d71853c3a9f82b5f9f962b URL: http://source.winehq.org/git/wine.git/?a=commit;h=596557a57acd1bc800d71853c3...
Author: Matteo Bruni mbruni@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