Also some patches to address comments made on the last MR. :)
-- v2: d3dx9: Add support for loading non-square cubemap DDS files into cube textures. d3dx9: Add support for specifying which array layer to get pixel data from to d3dx_image_get_pixels(). d3dx9: Use d3dx_image structure inside of D3DXCreateCubeTextureFromFileInMemoryEx(). d3dx9: Cleanup texture value argument handling in D3DXCreateCubeTextureFromFileInMemoryEx(). d3dx9: Refactor texture creation and cleanup in D3DXCreateCubeTextureFromFileInMemoryEx(). d3dx9/tests: Add more D3DXCreateCubeTextureFromFileInMemory{Ex}() tests. d3dx9/tests: Reorder test structure members. d3dx9/tests: Make some test structures static const.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 5fca2f5d64d..f6614d6b727 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -251,7 +251,7 @@ static void test_dds_header_handling(void) BYTE data[4096 * 1024]; } *dds;
- struct + static const struct { struct dds_pixel_format pixel_format; DWORD flags; @@ -355,7 +355,7 @@ static void test_dds_header_handling(void) { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 9, 262146, { D3D_OK, 9 } }, { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 10, 262146, { D3D_OK, 10 } }, }; - struct + static const struct { uint32_t flags; uint32_t width;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/surface.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index f6614d6b727..1d60f9c46aa 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -375,40 +375,40 @@ static void test_dds_header_handling(void) D3DRESOURCETYPE resource_type; } expected; + uint32_t pixel_data_size; BOOL todo_hr; BOOL todo_info; - uint32_t pixel_data_size; } info_tests[] = { /* Depth value set to 4, but no caps bits are set. Depth is ignored. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 }, /* The volume texture caps2 field is ignored. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), DDS_CAPS2_VOLUME, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 }, /* * The DDS_DEPTH flag is the only thing checked to determine if a DDS * file represents a volume texture. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 }, /* Even if the depth field is set to 0, it's still a volume texture. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 0, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 }, /* The DDS_DEPTH flag overrides cubemap caps. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), - { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, (292 * 6) }, + { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, (292 * 6) }, /* Cubemap where width field does not equal height. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 5, 1, (4 * 4), 1, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), - { D3D_OK, 4, 5, 1, 1, D3DRTYPE_CUBETEXTURE, }, FALSE, FALSE, (80 * 6) }, + { D3D_OK, 4, 5, 1, 1, D3DRTYPE_CUBETEXTURE, }, (80 * 6) }, /* Partial cubemaps are not supported. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 1, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_POSITIVEX), - { D3DXERR_INVALIDDATA, }, FALSE, FALSE, (64 * 6) }, + { D3DXERR_INVALIDDATA, }, (64 * 6) }, };
dds = calloc(1, sizeof(*dds));
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/d3dx9_test_images.h | 93 +++++++ dlls/d3dx9_36/tests/texture.c | 319 +++++++++++++++++++++--- 2 files changed, 377 insertions(+), 35 deletions(-)
diff --git a/dlls/d3dx9_36/tests/d3dx9_test_images.h b/dlls/d3dx9_36/tests/d3dx9_test_images.h index bc80fd01c6b..655d9a87fde 100644 --- a/dlls/d3dx9_36/tests/d3dx9_test_images.h +++ b/dlls/d3dx9_36/tests/d3dx9_test_images.h @@ -254,6 +254,99 @@ static const uint8_t dds_cube_map[] = 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55 };
+/* 4x2 cube map DDS file. */ +static const uint8_t dds_cube_map_4_2[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x00,0x00,0x02,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +/* 2x4 cube map DDS file. */ +static const uint8_t dds_cube_map_2_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x00,0x00,0x04,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +/* 4x4 cube map DDS file with 2 mips. */ +static const uint8_t dds_cube_map_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x02,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00, +}; + /* 4x4x2 volume map dds, 2 mipmaps */ static const uint8_t dds_volume_map[] = { diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 2c022b470d5..b3e05253a25 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -48,6 +48,38 @@ static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, got->x, got->y, got->z, got->w); }
+static inline void check_surface_desc(uint32_t line, D3DFORMAT format, uint32_t usage, D3DPOOL pool, + D3DMULTISAMPLE_TYPE multi_sample_type, uint32_t multi_sample_quality, uint32_t width, uint32_t height, + const D3DSURFACE_DESC *desc, BOOL wine_todo) +{ + const D3DSURFACE_DESC expected_desc = { format, D3DRTYPE_SURFACE, usage, pool, multi_sample_type, + multi_sample_quality, width, height }; + BOOL matched; + + matched = !memcmp(&expected_desc, desc, sizeof(*desc)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected surface desc values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && desc->Format != format) + ok_(__FILE__, line)(desc->Format == format, "Expected surface format %d, got %d.\n", format, desc->Format); + ok_(__FILE__, line)(desc->Type == D3DRTYPE_SURFACE, "Expected D3DRTYPE_SURFACE, 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->MultiSampleType != multi_sample_type) + ok_(__FILE__, line)(desc->MultiSampleType == multi_sample_type, "Expected multi sample type %d, got %d.\n", + multi_sample_type, desc->MultiSampleType); + todo_wine_if(wine_todo && desc->MultiSampleQuality != multi_sample_quality) + ok_(__FILE__, line)(desc->MultiSampleQuality == multi_sample_quality, "Expected multi sample quality %u, got %lu.\n", + multi_sample_quality, desc->MultiSampleQuality); + todo_wine_if(wine_todo && desc->Width != width) + ok_(__FILE__, line)(desc->Width == width, "Expected width %d, got %d.\n", width, desc->Width); + todo_wine_if(wine_todo && desc->Height != height) + ok_(__FILE__, line)(desc->Height == height, "Expected height %d, got %d.\n", height, desc->Height); +} + #define check_texture_level_desc(tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, width, \ height, wine_todo) \ check_texture_level_desc_(__LINE__, tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, \ @@ -56,10 +88,7 @@ static inline void check_texture_level_desc_(uint32_t line, IDirect3DTexture9 *t uint32_t usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multi_sample_type, uint32_t multi_sample_quality, uint32_t width, uint32_t height, BOOL wine_todo) { - const D3DSURFACE_DESC expected_desc = { format, D3DRTYPE_SURFACE, usage, pool, multi_sample_type, - multi_sample_quality, width, height }; D3DSURFACE_DESC desc; - BOOL matched; HRESULT hr;
hr = IDirect3DTexture9_GetLevelDesc(tex, level, &desc); @@ -68,28 +97,28 @@ static inline void check_texture_level_desc_(uint32_t line, IDirect3DTexture9 *t if (FAILED(hr)) return;
- matched = !memcmp(&expected_desc, &desc, sizeof(desc)); - todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected surface desc values.\n"); - if (matched) + check_surface_desc(line, format, usage, pool, multi_sample_type, multi_sample_quality, width, height, &desc, + wine_todo); +} + +#define check_cube_texture_level_desc(tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, size, \ + wine_todo) \ + check_cube_texture_level_desc_(__LINE__, tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, \ + size, wine_todo) +static inline void check_cube_texture_level_desc_(uint32_t line, IDirect3DCubeTexture9 *tex, uint32_t level, + D3DFORMAT format, uint32_t usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multi_sample_type, + uint32_t multi_sample_quality, uint32_t size, BOOL wine_todo) +{ + D3DSURFACE_DESC desc; + HRESULT hr; + + hr = IDirect3DCubeTexture9_GetLevelDesc(tex, level, &desc); + todo_wine_if(wine_todo && FAILED(hr)) + ok_(__FILE__, line)(hr == S_OK, "Failed to get cube texture level desc with hr %#lx.\n", hr); + if (FAILED(hr)) return;
- todo_wine_if(wine_todo && desc.Format != format) - ok_(__FILE__, line)(desc.Format == format, "Expected surface format %d, got %d.\n", format, desc.Format); - ok_(__FILE__, line)(desc.Type == D3DRTYPE_SURFACE, "Expected D3DRTYPE_SURFACE, 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.MultiSampleType != multi_sample_type) - ok_(__FILE__, line)(desc.MultiSampleType == multi_sample_type, "Expected multi sample type %d, got %d.\n", - multi_sample_type, desc.MultiSampleType); - todo_wine_if(wine_todo && desc.MultiSampleQuality != multi_sample_quality) - ok_(__FILE__, line)(desc.MultiSampleQuality == multi_sample_quality, "Expected multi sample quality %u, got %lu.\n", - multi_sample_quality, desc.MultiSampleQuality); - 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); + check_surface_desc(line, format, usage, pool, multi_sample_type, multi_sample_quality, size, size, &desc, wine_todo); }
#define check_volume_texture_level_desc(tex, level, format, usage, pool, width, height, depth, wine_todo) \ @@ -177,21 +206,11 @@ static void release_surface_readback(struct surface_readback *rb) IDirect3DSurface9_Release(rb->surface); }
-static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DTexture9 *texture, uint32_t mip_level, - struct surface_readback *rb) +static void get_surface_readback(IDirect3DDevice9 *device, IDirect3DSurface9 *surface, struct surface_readback *rb) { - IDirect3DSurface9 *surface; D3DSURFACE_DESC desc; HRESULT hr;
- memset(rb, 0, sizeof(*rb)); - hr = IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface); - if (FAILED(hr)) - { - trace("Failed to get surface for mip level %d, hr %#lx.\n", mip_level, hr); - return; - } - hr = IDirect3DSurface9_GetDesc(surface, &desc); if (FAILED(hr)) { @@ -219,7 +238,6 @@ static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DText trace("Can't lock the readback surface, hr %#lx.\n", hr);
exit: - IDirect3DSurface9_Release(surface); if (FAILED(hr)) { if (rb->surface) @@ -228,6 +246,42 @@ exit: } }
+static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DTexture9 *texture, uint32_t mip_level, + struct surface_readback *rb) +{ + IDirect3DSurface9 *surface; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + hr = IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface); + if (FAILED(hr)) + { + trace("Failed to get surface for mip level %d, hr %#lx.\n", mip_level, hr); + return; + } + + get_surface_readback(device, surface, rb); + IDirect3DSurface9_Release(surface); +} + +static void get_cube_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DCubeTexture9 *texture, uint32_t face, + uint32_t mip_level, struct surface_readback *rb) +{ + IDirect3DSurface9 *surface; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, mip_level, &surface); + if (FAILED(hr)) + { + trace("Failed to get surface for face %d mip level %d, hr %#lx.\n", face, mip_level, hr); + return; + } + + get_surface_readback(device, surface, rb); + IDirect3DSurface9_Release(surface); +} + #define check_readback_pixel_4bpp(rb, x, y, color, todo) _check_readback_pixel_4bpp(__LINE__, rb, x, y, color, todo) static inline void _check_readback_pixel_4bpp(uint32_t line, struct surface_readback *rb, uint32_t x, uint32_t y, uint32_t expected_color, BOOL todo) @@ -2367,6 +2421,12 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device) hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#lx, expected %#lx\n", hr, D3DERR_INVALIDCALL);
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &cube_texture); + todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + + hr = D3DXCreateCubeTextureFromFileInMemory(device, bmp_32bpp_4_4_argb, sizeof(bmp_32bpp_4_4_argb), &cube_texture); + todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture); if (SUCCEEDED(hr)) { @@ -2385,7 +2445,20 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device) { + static const uint32_t dds_cube_map_non_square_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xffff00ff, 0xff000000, + }; + static const uint32_t dds_cube_map_4_4_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xffff00ff, 0xff00ffff, + 0xffffffff, 0xff000000, 0xff800000, 0xff008000, 0xff000080, 0xff808000 + }; IDirect3DCubeTexture9 *cube_texture; + struct surface_readback surface_rb; + D3DSURFACE_DESC desc; + D3DXIMAGE_INFO info; + uint32_t i, x, y; HRESULT hr;
hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT, @@ -2405,6 +2478,182 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); IDirect3DCubeTexture9_Release(cube_texture); + + /* + * Cubemap file with a width of 4 and a height of 2. The largest value is + * used for the size of the created cubemap. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + if (y < info.Height) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + } + + /* + * Load the same cubemap, but this time with a point filter. Source image + * is scaled to cover the entire 4x4 cubemap texture faces. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_POINT, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + } + + /* + * Cubemap file with a width of 2 and a height of 4. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_2_4, sizeof(dds_cube_map_2_4), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 2, 4, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + if (x < info.Width) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + } + + /* Multi-mip cubemap DDS file. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, D3DX_FROM_FILE, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 2, FALSE); + check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + check_cube_texture_level_desc(cube_texture, 1, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, FALSE); + + for (i = 0; i < 6; ++i) + { + uint32_t mip_level; + + for (mip_level = 0; mip_level < 2; ++mip_level) + { + const uint32_t expected_color = dds_cube_map_4_4_expected[(i * 2) + mip_level]; + + winetest_push_context("Face %u, mip level %u", i, mip_level); + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, mip_level, &desc); + get_cube_texture_surface_readback(device, cube_texture, i, mip_level, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + } + IDirect3DCubeTexture9_Release(cube_texture); + + /* Skip level bits are bits 30-26. Bit 31 needs to be ignored. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, + D3DX_FROM_FILE, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, + D3DX_FILTER_POINT | (0x20u << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT), 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + IDirect3DCubeTexture9_Release(cube_texture); + + /* Multi-mip cubemap DDS file with mip skipping. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, + D3DX_FROM_FILE, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, + D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_DEFAULT), 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, TRUE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, TRUE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, TRUE); + + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_4_4_expected[(i * 2) + 1]; + + winetest_push_context("Face %u", i); + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, TRUE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); }
static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/texture.c | 65 +++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 22 deletions(-)
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 6ecd9adfece..5659c0d76d0 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1386,7 +1386,7 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, BOOL file_size = FALSE; BOOL file_format = FALSE; BOOL file_mip_levels = FALSE; - IDirect3DCubeTexture9 *tex, *buftex; + IDirect3DCubeTexture9 *tex, *staging_tex;
TRACE("device %p, src_data %p, src_data_size %u, size %u, mip_levels %u, usage %#lx, " "format %#x, pool %#x, filter %#lx, mip_filter %#lx, color_key 0x%08lx, src_info %p, " @@ -1397,6 +1397,7 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, if (!device || !cube_texture || !src_data || !src_data_size) return D3DERR_INVALIDCALL;
+ staging_tex = tex = *cube_texture = NULL; hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info); if (FAILED(hr)) return hr; @@ -1435,64 +1436,84 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool); if (FAILED(hr)) - return hr; + { + FIXME("Couldn't find suitable texture parameters.\n"); + goto err; + }
if ((file_size && size != img_info.Width) || (file_format && format != img_info.Format) || (file_mip_levels && mip_levels != img_info.MipLevels)) - return D3DERR_NOTAVAILABLE; + { + hr = D3DERR_NOTAVAILABLE; + goto err; + }
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); if (FAILED(hr)) - return D3DERR_INVALIDCALL; + { + hr = D3DERR_INVALIDCALL; + goto err; + }
dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC); if (pool == D3DPOOL_DEFAULT && !dynamic_texture) { - hr = D3DXCreateCubeTexture(device, size, mip_levels, 0, format, D3DPOOL_SYSTEMMEM, &buftex); - tex = buftex; + TRACE("Creating staging texture.\n"); + hr = D3DXCreateCubeTexture(device, size, mip_levels, 0, format, D3DPOOL_SYSTEMMEM, &staging_tex); + tex = staging_tex; } else { hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex); - buftex = NULL; } + if (FAILED(hr)) - return hr; + { + FIXME("Texture creation failed.\n"); + goto err; + }
+ TRACE("Texture created correctly. Now loading the texture data into it.\n"); hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info); if (FAILED(hr)) { - IDirect3DCubeTexture9_Release(tex); - return hr; + FIXME("Texture loading failed.\n"); + goto err; }
loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter); if (FAILED(hr)) { - IDirect3DCubeTexture9_Release(tex); - return hr; + FIXME("Texture filtering failed.\n"); + goto err; }
- if (buftex) + if (staging_tex) { - hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex); + hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, cube_texture); if (FAILED(hr)) - { - IDirect3DCubeTexture9_Release(buftex); - return hr; - } + goto err;
- IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex); - IDirect3DCubeTexture9_Release(buftex); + IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)staging_tex, (IDirect3DBaseTexture9 *)(*cube_texture)); + IDirect3DCubeTexture9_Release(staging_tex); + } + else + { + *cube_texture = tex; }
if (src_info) *src_info = img_info;
- *cube_texture = tex; - return D3D_OK; + return hr; + +err: + if (tex) + IDirect3DCubeTexture9_Release(tex); + + return hr; }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/texture.c | 51 +++++++++++------------------------------ 1 file changed, 13 insertions(+), 38 deletions(-)
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 5659c0d76d0..e59a1c19943 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1378,15 +1378,12 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, DWORD filter, DWORD mip_filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info, PALETTEENTRY *palette, IDirect3DCubeTexture9 **cube_texture) { - HRESULT hr; - D3DCAPS9 caps; - UINT loaded_miplevels; - D3DXIMAGE_INFO img_info; - BOOL dynamic_texture; - BOOL file_size = FALSE; - BOOL file_format = FALSE; - BOOL file_mip_levels = FALSE; + BOOL dynamic_texture, format_specified = FALSE; IDirect3DCubeTexture9 *tex, *staging_tex; + uint32_t loaded_miplevels; + D3DXIMAGE_INFO img_info; + D3DCAPS9 caps; + HRESULT hr;
TRACE("device %p, src_data %p, src_data_size %u, size %u, mip_levels %u, usage %#lx, " "format %#x, pool %#x, filter %#lx, mip_filter %#lx, color_key 0x%08lx, src_info %p, " @@ -1408,31 +1405,14 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, if (img_info.Width != img_info.Height) return D3DXERR_INVALIDDATA;
- if (size == 0 || size == D3DX_DEFAULT_NONPOW2) - size = img_info.Width; - if (size == D3DX_DEFAULT) - size = make_pow2(img_info.Width); - - if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT) - format = img_info.Format; - - if (size == D3DX_FROM_FILE) - { - file_size = TRUE; - size = img_info.Width; - } + /* Handle default values. */ + if (!size || size == D3DX_DEFAULT_NONPOW2 || size == D3DX_FROM_FILE || size == D3DX_DEFAULT) + size = (size == D3DX_DEFAULT) ? make_pow2(img_info.Width) : img_info.Width;
- if (format == D3DFMT_FROM_FILE) - { - file_format = TRUE; + format_specified = (format != D3DFMT_UNKNOWN && format != D3DX_DEFAULT); + if (format == D3DFMT_FROM_FILE || format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT) format = img_info.Format; - } - - if (mip_levels == D3DX_FROM_FILE) - { - file_mip_levels = TRUE; - mip_levels = img_info.MipLevels; - } + mip_levels = (mip_levels == D3DX_FROM_FILE) ? img_info.MipLevels : mip_levels;
hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool); if (FAILED(hr)) @@ -1441,13 +1421,8 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, goto err; }
- if ((file_size && size != img_info.Width) - || (file_format && format != img_info.Format) - || (file_mip_levels && mip_levels != img_info.MipLevels)) - { - hr = D3DERR_NOTAVAILABLE; - goto err; - } + if (color_key && !format_specified) + format = get_alpha_replacement_format(format);
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); if (FAILED(hr))
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 4 ++-- dlls/d3dx9_36/texture.c | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index b3e05253a25..83a6848e37d 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2422,10 +2422,10 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device) ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#lx, expected %#lx\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &cube_texture); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
hr = D3DXCreateCubeTextureFromFileInMemory(device, bmp_32bpp_4_4_argb, sizeof(bmp_32bpp_4_4_argb), &cube_texture); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture); if (SUCCEEDED(hr)) diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index e59a1c19943..ea8536c3720 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1380,7 +1380,8 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, { BOOL dynamic_texture, format_specified = FALSE; IDirect3DCubeTexture9 *tex, *staging_tex; - uint32_t loaded_miplevels; + uint32_t loaded_miplevels, skip_levels; + struct d3dx_image image; D3DXIMAGE_INFO img_info; D3DCAPS9 caps; HRESULT hr; @@ -1395,15 +1396,29 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, return D3DERR_INVALIDCALL;
staging_tex = tex = *cube_texture = NULL; - hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info); + skip_levels = mip_filter != D3DX_DEFAULT ? mip_filter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0; + skip_levels &= D3DX_SKIP_DDS_MIP_LEVELS_MASK; + if (skip_levels) + FIXME("Skipping mip levels is currently unsupported for cube textures.\n"); + hr = d3dx_image_init(src_data, src_data_size, &image, 0, 0); if (FAILED(hr)) + { + FIXME("Unrecognized file format, returning failure.\n"); return hr; + }
- if (img_info.ImageFileFormat != D3DXIFF_DDS) - return D3DXERR_INVALIDDATA; + d3dximage_info_from_d3dx_image(&img_info, &image); + if (img_info.ResourceType != D3DRTYPE_CUBETEXTURE) + { + hr = E_FAIL; + goto err; + }
if (img_info.Width != img_info.Height) - return D3DXERR_INVALIDDATA; + { + hr = D3DXERR_INVALIDDATA; + goto err; + }
/* Handle default values. */ if (!size || size == D3DX_DEFAULT_NONPOW2 || size == D3DX_FROM_FILE || size == D3DX_DEFAULT) @@ -1479,12 +1494,14 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, *cube_texture = tex; }
+ d3dx_image_cleanup(&image); if (src_info) *src_info = img_info;
return hr;
err: + d3dx_image_cleanup(&image); if (tex) IDirect3DCubeTexture9_Release(tex);
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 7 +-- dlls/d3dx9_36/surface.c | 92 +++++++++++++---------------------- dlls/d3dx9_36/tests/texture.c | 8 +-- dlls/d3dx9_36/texture.c | 49 ++++++++++++++++--- dlls/d3dx9_36/volume.c | 2 +- 5 files changed, 83 insertions(+), 75 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 34a9f6eec7f..248b6a69b00 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -106,8 +106,10 @@ struct d3dx_image
struct volume size; uint32_t mip_levels; + uint32_t layer_count;
BYTE *pixels; + uint32_t layer_pitch;
/* * image_buf and palette are pointers to allocated memory used to store @@ -123,7 +125,8 @@ struct d3dx_image 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, uint32_t mip_level, struct d3dx_pixels *pixels); +HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, uint32_t mip_level, + struct d3dx_pixels *pixels); void d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image);
struct d3dx_include_from_file @@ -172,8 +175,6 @@ 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_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 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 79ee4edcbc1..344a491765e 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -475,6 +475,23 @@ static HRESULT d3dx_calculate_pixels_size(D3DFORMAT format, uint32_t width, uint return D3D_OK; }
+static uint32_t d3dx_calculate_layer_pixels_size(D3DFORMAT format, uint32_t width, uint32_t height, uint32_t depth, + uint32_t mip_levels) +{ + uint32_t layer_size, row_pitch, slice_pitch, i; + struct volume dims = { width, height, depth }; + + layer_size = 0; + for (i = 0; i < mip_levels; ++i) + { + d3dx_calculate_pixels_size(format, dims.width, dims.height, &row_pitch, &slice_pitch); + layer_size += slice_pitch * dims.depth; + d3dx_get_next_mip_level_size(&dims); + } + + return layer_size; +} + static UINT calculate_dds_file_size(D3DFORMAT format, UINT width, UINT height, UINT depth, UINT miplevels, UINT faces) { @@ -566,65 +583,11 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur return D3D_OK; }
-HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data, - const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) -{ - HRESULT hr; - int face; - UINT mip_level; - UINT size; - RECT src_rect; - UINT src_pitch; - UINT mip_levels; - UINT mip_level_size; - IDirect3DSurface9 *surface; - const struct dds_header *header = src_data; - const BYTE *pixels = (BYTE *)(header + 1); - - if (src_info->ResourceType != D3DRTYPE_CUBETEXTURE) - return D3DXERR_INVALIDDATA; - - if ((header->caps2 & DDS_CAPS2_CUBEMAP_ALL_FACES) != DDS_CAPS2_CUBEMAP_ALL_FACES) - { - WARN("Only full cubemaps are supported\n"); - return D3DXERR_INVALIDDATA; - } - - mip_levels = min(src_info->MipLevels, IDirect3DCubeTexture9_GetLevelCount(cube_texture)); - for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; face++) - { - size = src_info->Width; - for (mip_level = 0; mip_level < src_info->MipLevels; mip_level++) - { - hr = d3dx_calculate_pixels_size(src_info->Format, size, size, &src_pitch, &mip_level_size); - if (FAILED(hr)) return hr; - - /* if texture has fewer mip levels than DDS file, skip excessive mip levels */ - if (mip_level < mip_levels) - { - SetRect(&src_rect, 0, 0, size, size); - - IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, face, 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; - } - - pixels += mip_level_size; - size = max(1, size / 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) { const struct dds_header *header = src_data; uint32_t expected_src_data_size; - uint32_t faces = 1;
if (src_data_size < sizeof(*header) || header->pixel_format.size != sizeof(header->pixel_format)) return D3DXERR_INVALIDDATA; @@ -633,6 +596,7 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src set_volume_struct(&image->size, header->width, header->height, 1); image->mip_levels = header->miplevels ? header->miplevels : 1; image->format = dds_pixel_format_to_d3dformat(&header->pixel_format); + image->layer_count = 1;
if (image->format == D3DFMT_UNKNOWN) return D3DXERR_INVALIDDATA; @@ -651,14 +615,15 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src return D3DXERR_INVALIDDATA; }
- faces = 6; + image->layer_count = 6; image->resource_type = D3DRTYPE_CUBETEXTURE; } else image->resource_type = D3DRTYPE_TEXTURE;
- expected_src_data_size = calculate_dds_file_size(image->format, image->size.width, image->size.height, - image->size.depth, image->mip_levels, faces); + image->layer_pitch = d3dx_calculate_layer_pixels_size(image->format, image->size.width, image->size.height, + image->size.depth, image->mip_levels); + expected_src_data_size = (image->layer_pitch * image->layer_count) + sizeof(*header); if (src_data_size < expected_src_data_size) { WARN("File is too short %u, expected at least %u bytes.\n", src_data_size, expected_src_data_size); @@ -1020,6 +985,7 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src
image->size.depth = 1; image->mip_levels = 1; + image->layer_count = 1; image->resource_type = D3DRTYPE_TEXTURE;
exit: @@ -1055,7 +1021,8 @@ void d3dx_image_cleanup(struct d3dx_image *image) free(image->palette); }
-HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, struct d3dx_pixels *pixels) +HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, uint32_t mip_level, + struct d3dx_pixels *pixels) { struct volume mip_level_size = image->size; const BYTE *pixels_ptr = image->pixels; @@ -1069,6 +1036,12 @@ HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, stru return E_FAIL; }
+ if (layer >= image->layer_count) + { + ERR("Tried to retrieve layer %u, but image only has %u layers.\n", layer, image->layer_count); + return E_FAIL; + } + slice_pitch = row_pitch = 0; for (i = 0; i < image->mip_levels; i++) { @@ -1083,6 +1056,7 @@ HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, stru d3dx_get_next_mip_level_size(&mip_level_size); }
+ pixels_ptr += (layer * image->layer_pitch); SetRect(&unaligned_rect, 0, 0, mip_level_size.width, mip_level_size.height); set_d3dx_pixels(pixels, pixels_ptr, row_pitch, slice_pitch, image->palette, mip_level_size.width, mip_level_size.height, mip_level_size.depth, &unaligned_rect); @@ -1294,7 +1268,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, else SetRect(&src_rect, 0, 0, img_info.Width, img_info.Height);
- hr = d3dx_image_get_pixels(&image, 0, &pixels); + hr = d3dx_image_get_pixels(&image, 0, 0, &pixels); if (FAILED(hr)) goto exit;
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index 83a6848e37d..c1e54372fb2 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2632,9 +2632,9 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_DEFAULT), 0, &info, NULL, &cube_texture); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
- check_texture_mip_levels(cube_texture, 1, TRUE); - check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, TRUE); - check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, TRUE); + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, FALSE);
for (i = 0; i < 6; ++i) { @@ -2647,7 +2647,7 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic { for (x = 0; x < desc.Width; ++x) { - check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, TRUE); + 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 ea8536c3720..ab0ca312a2c 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -656,7 +656,7 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi D3DLOCKED_RECT dst_locked_rect; RECT dst_rect;
- hr = d3dx_image_get_pixels(&image, i, &src_pixels); + hr = d3dx_image_get_pixels(&image, 0, i, &src_pixels); if (FAILED(hr)) break;
@@ -1185,7 +1185,7 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic D3DLOCKED_BOX dst_locked_box; RECT dst_rect;
- hr = d3dx_image_get_pixels(&image, i, &src_pixels); + hr = d3dx_image_get_pixels(&image, 0, i, &src_pixels); if (FAILED(hr)) break;
@@ -1378,9 +1378,10 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, DWORD filter, DWORD mip_filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info, PALETTEENTRY *palette, IDirect3DCubeTexture9 **cube_texture) { + const struct pixel_format_desc *src_fmt_desc, *dst_fmt_desc; BOOL dynamic_texture, format_specified = FALSE; + uint32_t loaded_miplevels, skip_levels, i; IDirect3DCubeTexture9 *tex, *staging_tex; - uint32_t loaded_miplevels, skip_levels; struct d3dx_image image; D3DXIMAGE_INFO img_info; D3DCAPS9 caps; @@ -1398,9 +1399,7 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, staging_tex = tex = *cube_texture = NULL; skip_levels = mip_filter != D3DX_DEFAULT ? mip_filter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0; skip_levels &= D3DX_SKIP_DDS_MIP_LEVELS_MASK; - if (skip_levels) - FIXME("Skipping mip levels is currently unsupported for cube textures.\n"); - hr = d3dx_image_init(src_data, src_data_size, &image, 0, 0); + hr = d3dx_image_init(src_data, src_data_size, &image, skip_levels, 0); if (FAILED(hr)) { FIXME("Unrecognized file format, returning failure.\n"); @@ -1465,14 +1464,48 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, }
TRACE("Texture created correctly. Now loading the texture data into it.\n"); - hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info); + dst_fmt_desc = get_format_info(format); + src_fmt_desc = get_format_info(img_info.Format); + loaded_miplevels = min(img_info.MipLevels, IDirect3DCubeTexture9_GetLevelCount(tex)); + for (i = 0; i < loaded_miplevels; ++i) + { + struct d3dx_pixels src_pixels, dst_pixels; + D3DSURFACE_DESC dst_surface_desc; + D3DLOCKED_RECT dst_locked_rect; + RECT dst_rect; + uint32_t face; + + IDirect3DCubeTexture9_GetLevelDesc(tex, i, &dst_surface_desc); + SetRect(&dst_rect, 0, 0, dst_surface_desc.Width, dst_surface_desc.Height); + for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; ++face) + { + hr = d3dx_image_get_pixels(&image, face, i, &src_pixels); + if (FAILED(hr)) + break; + + hr = IDirect3DCubeTexture9_LockRect(tex, face, i, &dst_locked_rect, NULL, 0); + if (FAILED(hr)) + break; + + set_d3dx_pixels(&dst_pixels, dst_locked_rect.pBits, dst_locked_rect.Pitch, 0, palette, + dst_surface_desc.Width, dst_surface_desc.Height, 1, &dst_rect); + + hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, &src_pixels, src_fmt_desc, filter, color_key); + IDirect3DCubeTexture9_UnlockRect(tex, face, i); + if (FAILED(hr)) + break; + } + + if (FAILED(hr)) + break; + } + if (FAILED(hr)) { FIXME("Texture loading failed.\n"); goto err; }
- loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter); if (FAILED(hr)) { diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index 06cae72c51e..2088b70ed4c 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -202,7 +202,7 @@ HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, cons set_d3dbox(&box, 0, 0, image_info.Width, image_info.Height, 0, image_info.Depth); }
- hr = d3dx_image_get_pixels(&image, 0, &pixels); + hr = d3dx_image_get_pixels(&image, 0, 0, &pixels); if (FAILED(hr)) goto exit;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 120 ++++++++++++++++------------------ dlls/d3dx9_36/texture.c | 12 ++-- 2 files changed, 61 insertions(+), 71 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index c1e54372fb2..bbfae36b4e9 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -2485,35 +2485,33 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic */ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) { - check_texture_mip_levels(cube_texture, 1, FALSE); - check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); - check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + const uint32_t expected_color = dds_cube_map_non_square_expected[i];
- IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); - for (i = 0; i < 6; ++i) + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) { - const uint32_t expected_color = dds_cube_map_non_square_expected[i]; - - winetest_push_context("Face %u", i); - get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); - for (y = 0; y < desc.Height; ++y) + for (x = 0; x < desc.Width; ++x) { - for (x = 0; x < desc.Width; ++x) - { - if (y < info.Height) - check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); - else - check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); - } + if (y < info.Height) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); } - release_surface_readback(&surface_rb); - winetest_pop_context(); } - IDirect3DCubeTexture9_Release(cube_texture); + release_surface_readback(&surface_rb); + winetest_pop_context(); } + IDirect3DCubeTexture9_Release(cube_texture);
/* * Load the same cubemap, but this time with a point filter. Source image @@ -2521,67 +2519,63 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic */ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_POINT, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) { - check_texture_mip_levels(cube_texture, 1, FALSE); - check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); - check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + const uint32_t expected_color = dds_cube_map_non_square_expected[i];
- IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); - for (i = 0; i < 6; ++i) + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) { - const uint32_t expected_color = dds_cube_map_non_square_expected[i]; - - winetest_push_context("Face %u", i); - get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); - for (y = 0; y < desc.Height; ++y) + for (x = 0; x < desc.Width; ++x) { - for (x = 0; x < desc.Width; ++x) - { - check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); - } + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); } - release_surface_readback(&surface_rb); - winetest_pop_context(); } - IDirect3DCubeTexture9_Release(cube_texture); + release_surface_readback(&surface_rb); + winetest_pop_context(); } + IDirect3DCubeTexture9_Release(cube_texture);
/* * Cubemap file with a width of 2 and a height of 4. */ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_2_4, sizeof(dds_cube_map_2_4), D3DX_DEFAULT, 1, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); - todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - if (SUCCEEDED(hr)) + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 2, 4, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) { - check_texture_mip_levels(cube_texture, 1, FALSE); - check_image_info(&info, 2, 4, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); - check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + const uint32_t expected_color = dds_cube_map_non_square_expected[i];
- IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); - for (i = 0; i < 6; ++i) + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) { - const uint32_t expected_color = dds_cube_map_non_square_expected[i]; - - winetest_push_context("Face %u", i); - get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); - for (y = 0; y < desc.Height; ++y) + for (x = 0; x < desc.Width; ++x) { - for (x = 0; x < desc.Width; ++x) - { - if (x < info.Width) - check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); - else - check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); - } + if (x < info.Width) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); } - release_surface_readback(&surface_rb); - winetest_pop_context(); } - IDirect3DCubeTexture9_Release(cube_texture); + release_surface_readback(&surface_rb); + winetest_pop_context(); } + IDirect3DCubeTexture9_Release(cube_texture);
/* Multi-mip cubemap DDS file. */ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, D3DX_FROM_FILE, diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index ab0ca312a2c..a65a955cebf 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1413,15 +1413,11 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, goto err; }
- if (img_info.Width != img_info.Height) - { - hr = D3DXERR_INVALIDDATA; - goto err; - } - /* Handle default values. */ - if (!size || size == D3DX_DEFAULT_NONPOW2 || size == D3DX_FROM_FILE || size == D3DX_DEFAULT) - size = (size == D3DX_DEFAULT) ? make_pow2(img_info.Width) : img_info.Width; + if (!size || size == D3DX_DEFAULT_NONPOW2 || size == D3DX_FROM_FILE) + size = max(img_info.Width, img_info.Height); + else if (size == D3DX_DEFAULT) + size = make_pow2(max(img_info.Width, img_info.Height));
format_specified = (format != D3DFMT_UNKNOWN && format != D3DX_DEFAULT); if (format == D3DFMT_FROM_FILE || format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147235
Your paranoid android.
=== debian11b (64 bit WoW report) ===
Report validation errors: dxgi:dxgi has unaccounted for todo messages dxgi:dxgi has unaccounted for skip messages The report seems to have been truncated
On Fri Jul 19 14:40:39 2024 +0000, Matteo Bruni wrote:
Did you check that e.g. a 2x4 image makes a size 2 cube texture?
I don't know why I hadn't considered testing that, but I should've because it looks like it takes the size of the maximum dimension. I've added tests for this. Good idea!
On Fri Jul 19 14:40:54 2024 +0000, Matteo Bruni wrote:
This is kind of a separate change (enabled by the rest of the implementation changes.) Can it be split out without too much fuss?
Split it out into a separate commit.
On Fri Jul 19 14:38:23 2024 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/6040/diffs?diff_id=122998&start_sha=7260135f070ef9ca2f00073808e6875ec50b87d9#e5891b30c0f0a0d106394089d61a67281f349564_109_109)
Changed all variables with `element` to `layer` in the current revision.
On Thu Jul 18 17:41:30 2024 +0000, Matteo Bruni wrote:
I'm a bit torn by this swapping of the layer and level loops. With this we "fight" how the data is actually stored in DDS files, instead of just copying data out sequentially. We do get to avoid a bunch of otherwise redundant `GetLevelDesc()` + `SetRect()` calls though. How would this look for d3dx10/11?
Well, in a way we already have to fight it a bit due to the potential for skipping mip levels, which is possible in d3dx10/11 as well.
In theory I guess we could get the address of the first mip level for each layer, then do the dimension calculations/image pointer offsetting ourselves in the loop. For d3dx10/11 we do have to calculate the mip level sizes ourselves since d3d10/d3d11 has no equivalent to `GetLevelDesc()`.
I feel like the way it is now is visually cleaner, but probably less performant. If you'd prefer it to be closer to the way we'll end up doing it in d3dx10/d3dx11 I can do that.
On Tue Jul 23 23:18:49 2024 +0000, Connor McAdams wrote:
Well, in a way we already have to fight it a bit due to the potential for skipping mip levels, which is possible in d3dx10/11 as well. In theory I guess we could get the address of the first mip level for each layer, then do the dimension calculations/image pointer offsetting ourselves in the loop. For d3dx10/11 we do have to calculate the mip level sizes ourselves since d3d10/d3d11 has no equivalent to `GetLevelDesc()`. I feel like the way it is now is visually cleaner, but probably less performant. If you'd prefer it to be closer to the way we'll end up doing it in d3dx10/d3dx11 I can do that.
I'm not super worried about performance. It's just that, to me, looping by layer first looks more natural. Bonus points if that makes it more similar to what you end up doing for d3dx10/11 anyway.
It might very well be subjective though and ultimately it doesn't seem important.
This merge request was approved by Matteo Bruni.