From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 8 +-- dlls/d3dx9_36/surface.c | 101 +++++++++++++++++++--------------- dlls/d3dx9_36/tests/texture.c | 11 ++-- dlls/d3dx9_36/texture.c | 20 +------ 4 files changed, 70 insertions(+), 70 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 52475aa3025..07b4aff5137 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -120,7 +120,8 @@ struct d3dx_image D3DXIMAGE_FILEFORMAT image_file_format; };
-HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t flags); +HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, + uint32_t starting_mip_level, uint32_t flags); void d3dx_image_cleanup(struct d3dx_image *image); HRESULT d3dx_image_get_pixels(struct d3dx_image *image, struct d3dx_pixels *pixels); void d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image); @@ -171,9 +172,8 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette);
-HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette, - DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels, - unsigned int *loaded_miplevels); +HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, + const struct d3dx_image *image, unsigned int *loaded_miplevels); 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); HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 5fe0d0416c1..45277e28109 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -437,6 +437,20 @@ static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_form return E_NOTIMPL; }
+static void d3dx_get_next_mip_level_size(struct volume *size) +{ + size->width = max(size->width / 2, 1); + size->height = max(size->height / 2, 1); + size->depth = max(size->depth / 2, 1); +} + +static const char *debug_volume(const struct volume *volume) +{ + if (!volume) + return "(null)"; + return wine_dbg_sprintf("(%ux%ux%u)", volume->width, volume->height, volume->depth); +} + static HRESULT d3dx_calculate_pixels_size(D3DFORMAT format, uint32_t width, uint32_t height, uint32_t *pitch, uint32_t *size) { @@ -570,9 +584,8 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *d row_pitch, slice_pitch, NULL, src_box, filter, color_key); }
-HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette, - DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels, - unsigned int *loaded_miplevels) +HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, + const struct d3dx_image *image, unsigned int *loaded_miplevels) { HRESULT hr; RECT src_rect; @@ -580,49 +593,29 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, 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); - - /* Loading a cube texture as a simple texture is also supported - * (only first face texture is taken). Same with volume textures. */ - if ((src_info->ResourceType != D3DRTYPE_TEXTURE) - && (src_info->ResourceType != D3DRTYPE_CUBETEXTURE) - && (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE)) - { - WARN("Trying to load a %u resource as a 2D texture, returning failure.\n", src_info->ResourceType); - return D3DXERR_INVALIDDATA; - } + const BYTE *pixels = image->pixels; + struct volume mip_size = image->size;
- width = src_info->Width; - height = src_info->Height; - 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 + skip_levels; ++mip_level) + mip_levels = min(image->mip_levels, IDirect3DTexture9_GetLevelCount(texture)); + for (mip_level = 0; mip_level < mip_levels; ++mip_level) { - hr = d3dx_calculate_pixels_size(src_info->Format, width, height, &src_pitch, &mip_level_size); + hr = d3dx_calculate_pixels_size(image->format, mip_size.width, mip_size.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 - 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; - } + SetRect(&src_rect, 0, 0, mip_size.width, mip_size.height); + IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface); + hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, image->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); + pixels += mip_level_size * mip_size.depth; + d3dx_get_next_mip_level_size(&mip_size); }
- *loaded_miplevels = mip_levels - skip_levels; + *loaded_miplevels = mip_levels;
return D3D_OK; } @@ -733,7 +726,7 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co }
static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src_data_size, - struct d3dx_image *image) + struct d3dx_image *image, uint32_t starting_mip_level) { const struct dds_header *header = src_data; uint32_t expected_src_data_size; @@ -781,6 +774,27 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src
image->pixels = ((BYTE *)src_data) + sizeof(*header); image->image_file_format = D3DXIFF_DDS; + if (starting_mip_level && (image->mip_levels > 1)) + { + uint32_t i, row_pitch, slice_pitch, initial_mip_levels; + const struct volume initial_size = image->size; + + initial_mip_levels = image->mip_levels; + for (i = 0; i < starting_mip_level; i++) + { + d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch); + + image->pixels += slice_pitch * image->size.depth; + d3dx_get_next_mip_level_size(&image->size); + if (--image->mip_levels == 1) + break; + } + + TRACE("Requested starting mip level %u, actual starting mip level is %u (of %u total in image).\n", + starting_mip_level, (initial_mip_levels - image->mip_levels), initial_mip_levels); + TRACE("Original dimensions %s, new dimensions %s.\n", debug_volume(&initial_size), debug_volume(&image->size)); + } + return D3D_OK; }
@@ -1130,14 +1144,15 @@ exit: return hr; }
-HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t flags) +HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, + uint32_t starting_mip_level, uint32_t flags) { if (!src_data || !src_data_size || !image) return D3DERR_INVALIDCALL;
memset(image, 0, sizeof(*image)); if ((src_data_size >= 4) && !memcmp(src_data, "DDS ", 4)) - return d3dx_initialize_image_from_dds(src_data, src_data_size, image); + return d3dx_initialize_image_from_dds(src_data, src_data_size, image, starting_mip_level);
return d3dx_initialize_image_from_wic(src_data, src_data_size, image, flags); } @@ -1210,7 +1225,7 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, if (!info) return D3D_OK;
- hr = d3dx_image_init(data, datasize, &image, D3DX_IMAGE_INFO_ONLY); + hr = d3dx_image_init(data, datasize, &image, 0, D3DX_IMAGE_INFO_ONLY); if (FAILED(hr)) { TRACE("Invalid or unsupported image file\n"); return D3DXERR_INVALIDDATA; @@ -1359,7 +1374,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, if (!pDestSurface || !pSrcData || !SrcDataSize) return D3DERR_INVALIDCALL;
- hr = d3dx_image_init(pSrcData, SrcDataSize, &image, 0); + hr = d3dx_image_init(pSrcData, SrcDataSize, &image, 0, 0); if (FAILED(hr)) return D3DXERR_INVALIDDATA;
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index b099365150e..04dab09c33c 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2393,7 +2393,7 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
check_texture_mip_levels(texture, 1, FALSE); - check_image_info(&img_info, 1, 1, 1, 1, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, TRUE); + check_image_info(&img_info, 1, 1, 1, 1, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); check_texture_level_desc(texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 1, 1, FALSE);
IDirect3DTexture9_Release(texture); @@ -2407,9 +2407,9 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device) D3DX_DEFAULT, D3DX_SKIP_DDS_MIP_LEVELS(3, D3DX_FILTER_POINT), 0, &img_info, NULL, &texture); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
- check_texture_mip_levels(texture, 1, TRUE); - check_image_info(&img_info, 1, 1, 1, 1, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, TRUE); - check_texture_level_desc(texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 1, 1, TRUE); + check_texture_mip_levels(texture, 1, FALSE); + check_image_info(&img_info, 1, 1, 1, 1, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_texture_level_desc(texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 1, 1, FALSE);
IDirect3DTexture9_Release(texture);
@@ -2463,7 +2463,6 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device) for (mip_level = 0; mip_level < ARRAY_SIZE(dds_volume_24bit_4_4_4_expected); ++mip_level) { const uint32_t expected_color = dds_volume_24bit_4_4_4_expected[mip_level]; - BOOL todo = !!mip_level; uint32_t x, y;
IDirect3DTexture9_GetLevelDesc(texture, mip_level, &desc); @@ -2472,7 +2471,7 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device) { for (x = 0; x < desc.Width; ++x) { - check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, todo); + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); } } release_surface_readback(&surface_rb); diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 29358a92fd8..12702c0ca49 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -587,7 +587,8 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi return D3DERR_INVALIDCALL;
staging_tex = tex = *texture = NULL; - hr = d3dx_image_init(srcdata, srcdatasize, &image, 0); + skip_levels = mipfilter != D3DX_DEFAULT ? mipfilter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0; + hr = d3dx_image_init(srcdata, srcdatasize, &image, skip_levels, 0); if (FAILED(hr)) { FIXME("Unrecognized file format, returning failure.\n"); @@ -634,20 +635,6 @@ 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 up texture creation parameters. */ hr = D3DXCheckTextureRequirements(device, &width, &height, &miplevels, usage, &format, pool); @@ -710,8 +697,7 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi } else { - hr = load_texture_from_dds(tex, srcdata, palette, filter, colorkey, &imginfo, skip_levels, - &loaded_miplevels); + hr = load_texture_from_dds(tex, palette, filter, colorkey, &image, &loaded_miplevels); }
if (FAILED(hr))