d3dx9: Support skipping mip levels in D3DXCreateTextureFromFileInMemoryEx.

This commit is contained in:
Matteo Bruni 2014-03-05 18:35:18 +01:00 committed by Alexandre Julliard
parent 7788161c91
commit 596557a57a
5 changed files with 60 additions and 15 deletions

View File

@ -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;

View File

@ -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;
if (mip_level >= skip_levels)
{
SetRect(&src_rect, 0, 0, width, height);
IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface);
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;
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;
}

View File

@ -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");

View File

@ -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);
}

View File

@ -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