d3dx9: Support skipping mip levels in D3DXCreateTextureFromFileInMemoryEx.
This commit is contained in:
parent
7788161c91
commit
596557a57a
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue