From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/d3dx9_test_images.h | 102 ++++++++++++++ dlls/d3dx9_36/tests/texture.c | 170 +++++++++++++++++++++++- dlls/d3dx9_36/tests/volume.c | 100 -------------- 3 files changed, 271 insertions(+), 101 deletions(-)
diff --git a/dlls/d3dx9_36/tests/d3dx9_test_images.h b/dlls/d3dx9_36/tests/d3dx9_test_images.h index 1034700c22e..f1e8ffb94bf 100644 --- a/dlls/d3dx9_36/tests/d3dx9_test_images.h +++ b/dlls/d3dx9_36/tests/d3dx9_test_images.h @@ -20,6 +20,8 @@ */
#include <stdint.h> +#define COBJMACROS +#include "d3dx9tex.h"
/* 1x1 bmp (1 bpp) */ static const uint8_t bmp_1bpp[] = @@ -433,3 +435,103 @@ static inline void check_image_info_(const char *file, uint32_t line, const D3DX ok_(file, line)(info->ImageFileFormat == image_file_format, "Expected image_file_format %d, got %d.\n", image_file_format, info->ImageFileFormat); } + +struct volume_readback +{ + IDirect3DVolume9 *volume; + D3DLOCKED_BOX locked_box; +}; + +static inline uint32_t get_volume_readback_color(struct volume_readback *rb, uint32_t x, uint32_t y, uint32_t z) +{ + const uint32_t *pixels = rb->locked_box.pBits; + const D3DLOCKED_BOX *box = &rb->locked_box; + + if (!box->pBits) + return 0xdeadbeef; + return pixels[(z * (box->SlicePitch / sizeof(uint32_t)) + (y * (box->RowPitch / sizeof(uint32_t))) + x)]; +} + +#define release_volume_readback(rb) release_volume_readback_(__FILE__, __LINE__, rb) +static inline void release_volume_readback_(const char *file, uint32_t line, struct volume_readback *rb) +{ + HRESULT hr; + + if (!rb->volume) + return; + if (rb->locked_box.pBits && FAILED(hr = IDirect3DVolume9_UnlockBox(rb->volume))) + trace_(file, line)("Can't unlock the readback volume, hr %#lx.\n", hr); + IDirect3DVolume9_Release(rb->volume); +} + +#define get_texture_volume_readback(device, volume_tex, mip_level, rb) \ + get_texture_volume_readback_(__FILE__, __LINE__, device, volume_tex, mip_level, rb) +static inline void get_texture_volume_readback_(const char *file, uint32_t line, IDirect3DDevice9 *device, + IDirect3DVolumeTexture9 *volume_tex, uint32_t mip_level, struct volume_readback *rb) +{ + IDirect3DVolumeTexture9 *rb_tex; + IDirect3DVolume9 *volume = NULL; + D3DVOLUME_DESC desc; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_tex, mip_level, &desc); + if (FAILED(hr)) + { + trace_(file, line)("Failed to get volume description for mip level %d, hr %#lx.\n", mip_level, hr); + return; + } + + hr = IDirect3DDevice9_CreateVolumeTexture(device, desc.Width, desc.Height, desc.Depth, 1, 0, D3DFMT_A8R8G8B8, + D3DPOOL_SYSTEMMEM, &rb_tex, NULL); + if (FAILED(hr)) + { + trace_(file, line)("Can't create the readback volume texture, hr %#lx.\n", hr); + return; + } + + hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_tex, mip_level, &volume); + if (FAILED(hr)) + { + trace_(file, line)("Failed to get the volume for mip_level %d, hr %#lx.\n", mip_level, hr); + goto exit; + } + + hr = IDirect3DVolumeTexture9_GetVolumeLevel(rb_tex, 0, &rb->volume); + if (FAILED(hr)) + { + trace_(file, line)("Failed to get readback volume, hr %#lx.\n", hr); + goto exit; + } + + hr = D3DXLoadVolumeFromVolume(rb->volume, NULL, NULL, volume, NULL, NULL, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + { + trace_(file, line)("Can't load the source volume into the readback, hr %#lx.\n", hr); + goto exit; + } + + hr = IDirect3DVolume9_LockBox(rb->volume, &rb->locked_box, NULL, D3DLOCK_READONLY); + if (FAILED(hr)) + trace_(file, line)("Can't lock the readback volume, hr %#lx.\n", hr); + +exit: + IDirect3DVolumeTexture9_Release(rb_tex); + if (volume) + IDirect3DVolume9_Release(volume); + if (FAILED(hr)) + { + if (rb->volume) + IDirect3DVolume9_Release(rb->volume); + rb->volume = NULL; + } +} + +#define check_volume_readback_pixel_4bpp(rb, x, y, z, color, todo) \ + _check_volume_readback_pixel_4bpp(__FILE__, __LINE__, rb, x, y, z, color, todo) +static inline void _check_volume_readback_pixel_4bpp(const char *file, uint32_t line, struct volume_readback *rb, + uint32_t x, uint32_t y, uint32_t z, uint32_t expected_color, BOOL todo) +{ + uint32_t color = get_volume_readback_color(rb, x, y, z); + todo_wine_if(todo) ok_(file, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x.\n", color, expected_color); +} diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 847d55bafea..4787bb6ada4 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -92,6 +92,42 @@ static inline void check_texture_level_desc_(uint32_t line, IDirect3DTexture9 *t ok_(__FILE__, line)(desc.Height == height, "Expected height %u, got %u.\n", height, desc.Height); }
+#define check_volume_texture_level_desc(tex, level, format, usage, pool, width, height, depth, wine_todo) \ + check_volume_texture_level_desc_(__LINE__, tex, level, format, usage, pool, width, height, depth, wine_todo) +static inline void check_volume_texture_level_desc_(uint32_t line, IDirect3DVolumeTexture9 *tex, uint32_t level, + D3DFORMAT format, uint32_t usage, D3DPOOL pool, uint32_t width, uint32_t height, uint32_t depth, BOOL wine_todo) +{ + const D3DVOLUME_DESC expected_desc = { format, D3DRTYPE_VOLUME, usage, pool, width, height, depth }; + D3DVOLUME_DESC desc; + BOOL matched; + HRESULT hr; + + hr = IDirect3DVolumeTexture9_GetLevelDesc(tex, level, &desc); + todo_wine_if(wine_todo && FAILED(hr)) + ok_(__FILE__, line)(hr == S_OK, "Failed to get texture level desc with hr %#lx.\n", hr); + if (FAILED(hr)) + return; + + matched = !memcmp(&expected_desc, &desc, sizeof(desc)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected volume desc values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && desc.Format != format) + ok_(__FILE__, line)(desc.Format == format, "Expected volume format %d, got %d.\n", format, desc.Format); + ok_(__FILE__, line)(desc.Type == D3DRTYPE_VOLUME, "Expected D3DRTYPE_VOLUME, got %d.\n", desc.Type); + todo_wine_if(wine_todo && desc.Usage != usage) + ok_(__FILE__, line)(desc.Usage == usage, "Expected usage %u, got %lu.\n", usage, desc.Usage); + todo_wine_if(wine_todo && desc.Pool != pool) + ok_(__FILE__, line)(desc.Pool == pool, "Expected pool %d, got %d.\n", pool, desc.Pool); + todo_wine_if(wine_todo && desc.Width != width) + ok_(__FILE__, line)(desc.Width == width, "Expected width %u, got %u.\n", width, desc.Width); + todo_wine_if(wine_todo && desc.Height != height) + ok_(__FILE__, line)(desc.Height == height, "Expected height %u, got %u.\n", height, desc.Height); + todo_wine_if(wine_todo && desc.Depth != depth) + ok_(__FILE__, line)(desc.Depth == depth, "Expected depth %u, got %u.\n", depth, desc.Depth); +} + #define check_texture_mip_levels(tex, expected_mip_levels, wine_todo) \ check_texture_mip_levels_(__LINE__, ((IDirect3DBaseTexture9 *)tex), expected_mip_levels, wine_todo) static inline void check_texture_mip_levels_(uint32_t line, IDirect3DBaseTexture9 *tex, uint32_t expected_mip_levels, @@ -2406,7 +2442,23 @@ static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *devic
static void test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device) { - IDirect3DVolumeTexture9 *volume_texture; + static const uint32_t dds_volume_dxt3_4_4_4_expected_uncompressed[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, + }; + static const uint32_t dds_24bit_8_8_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000, + }; + static const uint32_t bmp_32bpp_4_4_argb_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000, + }; + IDirect3DVolumeTexture9 *volume_texture, *texture; + struct volume_readback volume_rb; + uint32_t mip_level, x, y, z; + D3DXIMAGE_INFO img_info; + D3DVOLUME_DESC desc; HRESULT hr;
hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, dds_volume_map, sizeof(dds_volume_map), D3DX_DEFAULT, @@ -2418,6 +2470,122 @@ static void test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *dev D3DX_DEFAULT, D3DX_DEFAULT, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &volume_texture); ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#lx.\n", hr); + + /* Load a 2D texture DDS file with multiple mips into a volume texture. */ + 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)) + { + 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) + { + 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 (x = 0; x < desc.Width; ++x) + { + check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color, FALSE); + } + } + } + release_volume_readback(&volume_rb); + } + IDirect3DVolumeTexture9_Release(texture); + } + + /* Multi-mip compressed volume texture file. */ + if (has_3d_dxt3) + { + hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, dds_volume_dxt3_4_4_4, sizeof(dds_volume_dxt3_4_4_4), + D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, + D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, &img_info, NULL, &texture); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + check_texture_mip_levels(texture, 3, FALSE); + check_image_info(&img_info, 4, 4, 4, 3, D3DFMT_DXT3, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_texture_level_desc(texture, 0, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 4, 4, 4, FALSE); + check_volume_texture_level_desc(texture, 1, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 2, 2, 2, FALSE); + check_volume_texture_level_desc(texture, 2, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 1, 1, 1, FALSE); + + for (mip_level = 0; mip_level < 3; ++mip_level) + { + const uint32_t expected_color = dds_volume_dxt3_4_4_4_expected_uncompressed[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 (x = 0; x < desc.Width; ++x) + { + check_volume_readback_pixel_4bpp(&volume_rb, x, y, z, expected_color, FALSE); + } + } + } + release_volume_readback(&volume_rb); + } + IDirect3DVolumeTexture9_Release(texture); + } + else + { + skip("D3DFMT_DXT3 volume textures are not supported, skipping tests.\n"); + } + + /* Load a BMP file into a volume texture. */ + 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)) + { + 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) + { + 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) + { + 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); + } + } + } + release_volume_readback(&volume_rb); + } + IDirect3DVolumeTexture9_Release(texture); + } }
/* fills positive x face with red color */ diff --git a/dlls/d3dx9_36/tests/volume.c b/dlls/d3dx9_36/tests/volume.c index 9ffc487078c..c0bad638597 100644 --- a/dlls/d3dx9_36/tests/volume.c +++ b/dlls/d3dx9_36/tests/volume.c @@ -23,106 +23,6 @@ #include "d3dx9tex.h" #include "d3dx9_test_images.h"
-struct volume_readback -{ - IDirect3DVolume9 *volume; - D3DLOCKED_BOX locked_box; -}; - -static inline uint32_t get_volume_readback_color(struct volume_readback *rb, uint32_t x, uint32_t y, uint32_t z) -{ - const uint32_t *pixels = rb->locked_box.pBits; - const D3DLOCKED_BOX *box = &rb->locked_box; - - if (!box->pBits) - return 0xdeadbeef; - return pixels[(z * (box->SlicePitch / sizeof(uint32_t)) + (y * (box->RowPitch / sizeof(uint32_t))) + x)]; -} - -#define release_volume_readback(rb) release_volume_readback_(__FILE__, __LINE__, rb) -static inline void release_volume_readback_(const char *file, uint32_t line, struct volume_readback *rb) -{ - HRESULT hr; - - if (!rb->volume) - return; - if (rb->locked_box.pBits && FAILED(hr = IDirect3DVolume9_UnlockBox(rb->volume))) - trace_(file, line)("Can't unlock the readback volume, hr %#lx.\n", hr); - IDirect3DVolume9_Release(rb->volume); -} - -#define get_texture_volume_readback(device, volume_tex, mip_level, rb) \ - get_texture_volume_readback_(__FILE__, __LINE__, device, volume_tex, mip_level, rb) -static inline void get_texture_volume_readback_(const char *file, uint32_t line, IDirect3DDevice9 *device, - IDirect3DVolumeTexture9 *volume_tex, uint32_t mip_level, struct volume_readback *rb) -{ - IDirect3DVolumeTexture9 *rb_tex; - IDirect3DVolume9 *volume = NULL; - D3DVOLUME_DESC desc; - HRESULT hr; - - memset(rb, 0, sizeof(*rb)); - hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_tex, mip_level, &desc); - if (FAILED(hr)) - { - trace_(file, line)("Failed to get volume description for mip level %d, hr %#lx.\n", mip_level, hr); - return; - } - - hr = IDirect3DDevice9_CreateVolumeTexture(device, desc.Width, desc.Height, desc.Depth, 1, 0, D3DFMT_A8R8G8B8, - D3DPOOL_SYSTEMMEM, &rb_tex, NULL); - if (FAILED(hr)) - { - trace_(file, line)("Can't create the readback volume texture, hr %#lx.\n", hr); - return; - } - - hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_tex, mip_level, &volume); - if (FAILED(hr)) - { - trace_(file, line)("Failed to get the volume for mip_level %d, hr %#lx.\n", mip_level, hr); - goto exit; - } - - hr = IDirect3DVolumeTexture9_GetVolumeLevel(rb_tex, 0, &rb->volume); - if (FAILED(hr)) - { - trace_(file, line)("Failed to get readback volume, hr %#lx.\n", hr); - goto exit; - } - - hr = D3DXLoadVolumeFromVolume(rb->volume, NULL, NULL, volume, NULL, NULL, D3DX_FILTER_NONE, 0); - if (FAILED(hr)) - { - trace_(file, line)("Can't load the source volume into the readback, hr %#lx.\n", hr); - goto exit; - } - - hr = IDirect3DVolume9_LockBox(rb->volume, &rb->locked_box, NULL, D3DLOCK_READONLY); - if (FAILED(hr)) - trace_(file, line)("Can't lock the readback volume, hr %#lx.\n", hr); - -exit: - IDirect3DVolumeTexture9_Release(rb_tex); - if (volume) - IDirect3DVolume9_Release(volume); - if (FAILED(hr)) - { - if (rb->volume) - IDirect3DVolume9_Release(rb->volume); - rb->volume = NULL; - } -} - -#define check_volume_readback_pixel_4bpp(rb, x, y, z, color, todo) \ - _check_volume_readback_pixel_4bpp(__FILE__, __LINE__, rb, x, y, z, color, todo) -static inline void _check_volume_readback_pixel_4bpp(const char *file, uint32_t line, struct volume_readback *rb, - uint32_t x, uint32_t y, uint32_t z, uint32_t expected_color, BOOL todo) -{ - uint32_t color = get_volume_readback_color(rb, x, y, z); - todo_wine_if(todo) ok_(file, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x.\n", color, expected_color); -} - #define check_pixel_4bpp(box, x, y, z, color) _check_pixel_4bpp(__LINE__, box, x, y, z, color) static inline void _check_pixel_4bpp(unsigned int line, const D3DLOCKED_BOX *box, int x, int y, int z, DWORD expected_color) {