From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 2 - dlls/d3dx9_36/surface.c | 52 ------------------- dlls/d3dx9_36/tests/texture.c | 98 +++++++++++++++++------------------ dlls/d3dx9_36/texture.c | 47 +++++++++++++++-- 4 files changed, 90 insertions(+), 109 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 26e4a1560d6..34a9f6eec7f 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -174,8 +174,6 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
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_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data, - const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info); HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLOCKED_RECT *lock, IDirect3DSurface9 **temp_surface, BOOL write); HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index a97112a3562..5044feb0fb6 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -619,58 +619,6 @@ HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const vo return D3D_OK; }
-HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data, - const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) -{ - HRESULT hr; - UINT mip_level; - UINT mip_levels; - UINT src_slice_pitch; - UINT src_row_pitch; - D3DBOX src_box; - UINT width, height, depth; - IDirect3DVolume9 *volume; - const struct dds_header *header = src_data; - const BYTE *pixels = (BYTE *)(header + 1); - - if (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE) - return D3DXERR_INVALIDDATA; - - width = src_info->Width; - height = src_info->Height; - depth = src_info->Depth; - mip_levels = min(src_info->MipLevels, IDirect3DVolumeTexture9_GetLevelCount(volume_texture)); - - for (mip_level = 0; mip_level < mip_levels; mip_level++) - { - hr = d3dx_calculate_pixels_size(src_info->Format, width, height, &src_row_pitch, &src_slice_pitch); - if (FAILED(hr)) return hr; - - hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, mip_level, &volume); - if (FAILED(hr)) return hr; - - src_box.Left = 0; - src_box.Top = 0; - src_box.Right = width; - src_box.Bottom = height; - src_box.Front = 0; - src_box.Back = depth; - - hr = D3DXLoadVolumeFromMemory(volume, palette, NULL, pixels, src_info->Format, - src_row_pitch, src_slice_pitch, NULL, &src_box, filter, color_key); - - IDirect3DVolume9_Release(volume); - if (FAILED(hr)) return hr; - - pixels += depth * src_slice_pitch; - width = max(1, width / 2); - height = max(1, height / 2); - depth = max(1, depth / 2); - } - - return D3D_OK; -} - static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t starting_mip_level) { diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 4787bb6ada4..da7521ab134 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2475,37 +2475,35 @@ static void test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *dev hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, dds_24bit_8_8, sizeof(dds_24bit_8_8), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, &img_info, NULL, &texture); - todo_wine ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(texture, 4, FALSE); + check_image_info(&img_info, 8, 8, 1, 4, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_texture_level_desc(texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 8, 8, 1, FALSE); + check_volume_texture_level_desc(texture, 1, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 4, 4, 1, FALSE); + check_volume_texture_level_desc(texture, 2, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 2, 2, 1, FALSE); + check_volume_texture_level_desc(texture, 3, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 1, 1, 1, FALSE); + + for (mip_level = 0; mip_level < 4; ++mip_level) { - check_texture_mip_levels(texture, 4, FALSE); - check_image_info(&img_info, 8, 8, 1, 4, D3DFMT_R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); - check_volume_texture_level_desc(texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 8, 8, 1, FALSE); - check_volume_texture_level_desc(texture, 1, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 4, 4, 1, FALSE); - check_volume_texture_level_desc(texture, 2, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 2, 2, 1, FALSE); - check_volume_texture_level_desc(texture, 3, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 1, 1, 1, FALSE); + const uint32_t expected_color = dds_24bit_8_8_expected[mip_level]; + uint32_t x, y, z;
- for (mip_level = 0; mip_level < 4; ++mip_level) + IDirect3DVolumeTexture9_GetLevelDesc(texture, mip_level, &desc); + get_texture_volume_readback(device, texture, mip_level, &volume_rb); + for (z = 0; z < desc.Depth; ++z) { - const uint32_t expected_color = dds_24bit_8_8_expected[mip_level]; - uint32_t x, y, z; - - IDirect3DVolumeTexture9_GetLevelDesc(texture, mip_level, &desc); - get_texture_volume_readback(device, texture, mip_level, &volume_rb); - for (z = 0; z < desc.Depth; ++z) + for (y = 0; y < desc.Height; ++y) { - for (y = 0; y < desc.Height; ++y) + for (x = 0; x < desc.Width; ++x) { - for (x = 0; x < desc.Width; ++x) - { - check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color, FALSE); - } + check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color, FALSE); } } - release_volume_readback(&volume_rb); } - IDirect3DVolumeTexture9_Release(texture); + release_volume_readback(&volume_rb); } + IDirect3DVolumeTexture9_Release(texture);
/* Multi-mip compressed volume texture file. */ if (has_3d_dxt3) @@ -2550,42 +2548,42 @@ static void test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *dev hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, bmp_32bpp_4_4_argb, sizeof(bmp_32bpp_4_4_argb), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_FILTER_POINT, 0, &img_info, NULL, &texture); - todo_wine ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(texture, 3, TRUE); + check_image_info(&img_info, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_BMP, FALSE); + check_volume_texture_level_desc(texture, 0, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 4, 4, 1, FALSE); + check_volume_texture_level_desc(texture, 1, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 2, 2, 1, TRUE); + check_volume_texture_level_desc(texture, 2, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 1, 1, 1, TRUE); + + /* + * Check that the values actually get set. Only checking 4x4 and 2x2, 1x1 + * will vary based on filter implementation. + */ + for (mip_level = 0; mip_level < 2; ++mip_level) { - check_texture_mip_levels(texture, 3, FALSE); - check_image_info(&img_info, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_BMP, FALSE); - check_volume_texture_level_desc(texture, 0, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 4, 4, 1, FALSE); - check_volume_texture_level_desc(texture, 1, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 2, 2, 1, FALSE); - check_volume_texture_level_desc(texture, 2, D3DFMT_A8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 1, 1, 1, FALSE); - - /* - * Check that the values actually get set. Only checking 4x4 and 2x2, 1x1 - * will vary based on filter implementation. - */ - for (mip_level = 0; mip_level < 2; ++mip_level) + BOOL todo = !!mip_level; + + IDirect3DVolumeTexture9_GetLevelDesc(texture, mip_level, &desc); + get_texture_volume_readback(device, texture, mip_level, &volume_rb); + for (z = 0; z < desc.Depth; ++z) { - IDirect3DVolumeTexture9_GetLevelDesc(texture, mip_level, &desc); - get_texture_volume_readback(device, texture, mip_level, &volume_rb); - for (z = 0; z < desc.Depth; ++z) + for (y = 0; y < desc.Height; ++y) { - for (y = 0; y < desc.Height; ++y) - { - const uint32_t *expected_color = &bmp_32bpp_4_4_argb_expected[(y < (desc.Height / 2)) ? 0 : 2]; + const uint32_t *expected_color = &bmp_32bpp_4_4_argb_expected[(y < (desc.Height / 2)) ? 0 : 2];
- for (x = 0; x < desc.Width; ++x) - { - if (x < (desc.Width / 2)) - check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color[0], FALSE); - else - check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color[1], FALSE); - } + for (x = 0; x < desc.Width; ++x) + { + if (x < (desc.Width / 2)) + check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color[0], todo); + else + check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color[1], todo); } } - release_volume_readback(&volume_rb); } - IDirect3DVolumeTexture9_Release(texture); + release_volume_readback(&volume_rb); } + IDirect3DVolumeTexture9_Release(texture); }
/* fills positive x face with red color */ diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 4050115c6df..8f39cade7f8 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1097,9 +1097,12 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic { HRESULT hr; D3DCAPS9 caps; + struct d3dx_image image; D3DXIMAGE_INFO image_info; + uint32_t loaded_miplevels, skip_levels, i; IDirect3DVolumeTexture9 *tex, *staging_tex; BOOL dynamic_texture, format_specified = FALSE; + const struct pixel_format_desc *src_fmt_desc, *dst_fmt_desc;
TRACE("device %p, data %p, data_size %u, width %u, height %u, depth %u, mip_levels %u, " "usage %#lx, format %#x, pool %#x, filter %#lx, mip_filter %#lx, color_key 0x%08lx, " @@ -1111,11 +1114,15 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic return D3DERR_INVALIDCALL;
staging_tex = tex = *volume_texture = NULL; - hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info); - if (FAILED(hr)) return hr; + skip_levels = mip_filter != D3DX_DEFAULT ? mip_filter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0; + hr = d3dx_image_init(data, data_size, &image, skip_levels, 0); + if (FAILED(hr)) + { + FIXME("Unrecognized file format, returning failure.\n"); + return hr; + }
- if (image_info.ImageFileFormat != D3DXIFF_DDS) - return D3DXERR_INVALIDDATA; + d3dximage_info_from_d3dx_image(&image_info, &image);
/* Handle default values. */ if (!width || width == D3DX_DEFAULT_NONPOW2 || width == D3DX_FROM_FILE || width == D3DX_DEFAULT) @@ -1172,7 +1179,35 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic }
TRACE("Texture created correctly. Now loading the texture data into it.\n"); - hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info); + dst_fmt_desc = get_format_info(format); + src_fmt_desc = get_format_info(image_info.Format); + loaded_miplevels = min(image_info.MipLevels, IDirect3DVolumeTexture9_GetLevelCount(tex)); + for (i = 0; i < loaded_miplevels; i++) + { + struct d3dx_pixels src_pixels, dst_pixels; + D3DVOLUME_DESC dst_volume_desc; + D3DLOCKED_BOX dst_locked_box; + RECT dst_rect; + + hr = d3dx_image_get_pixels(&image, i, &src_pixels); + if (FAILED(hr)) + break; + + hr = IDirect3DVolumeTexture9_LockBox(tex, i, &dst_locked_box, NULL, 0); + if (FAILED(hr)) + break; + + IDirect3DVolumeTexture9_GetLevelDesc(tex, i, &dst_volume_desc); + SetRect(&dst_rect, 0, 0, dst_volume_desc.Width, dst_volume_desc.Height); + set_d3dx_pixels(&dst_pixels, dst_locked_box.pBits, dst_locked_box.RowPitch, dst_locked_box.SlicePitch, palette, + dst_volume_desc.Width, dst_volume_desc.Height, dst_volume_desc.Depth, &dst_rect); + + hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, &src_pixels, src_fmt_desc, filter, color_key); + IDirect3DVolumeTexture9_UnlockBox(tex, i); + if (FAILED(hr)) + break; + } + if (FAILED(hr)) { FIXME("Texture loading failed.\n"); @@ -1194,12 +1229,14 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic *volume_texture = tex; }
+ d3dx_image_cleanup(&image); if (info) *info = image_info;
return hr;
err: + d3dx_image_cleanup(&image); if (tex) IDirect3DVolumeTexture9_Release(tex);