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