Also some patches to address comments made on the last MR. :)
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 | 68 ++++++ dlls/d3dx9_36/tests/texture.c | 284 +++++++++++++++++++++--- 2 files changed, 317 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..df0604868f5 100644 --- a/dlls/d3dx9_36/tests/d3dx9_test_images.h +++ b/dlls/d3dx9_36/tests/d3dx9_test_images.h @@ -254,6 +254,74 @@ 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, +}; + +/* 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..e4a491c0a74 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_4_2_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,147 @@ 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 width value is + * used for the size of the created cubemap texture. + */ + 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_4_2_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_4_2_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); + } + + /* 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_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); + check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, 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_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, TRUE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, 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 e4a491c0a74..ba4d39fe9a7 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 | 86 ++++++++++++++++---------------- dlls/d3dx9_36/texture.c | 55 +++++++++++++++------ dlls/d3dx9_36/volume.c | 2 +- 5 files changed, 120 insertions(+), 122 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 34a9f6eec7f..280401f1852 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 elements;
BYTE *pixels; + uint32_t element_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 element, 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..51d2895d908 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_element_pixels_size(D3DFORMAT format, uint32_t width, uint32_t height, uint32_t depth, + uint32_t mip_levels) +{ + uint32_t element_size, row_pitch, slice_pitch, i; + struct volume dims = { width, height, depth }; + + element_size = 0; + for (i = 0; i < mip_levels; ++i) + { + d3dx_calculate_pixels_size(format, dims.width, dims.height, &row_pitch, &slice_pitch); + element_size += slice_pitch * dims.depth; + d3dx_get_next_mip_level_size(&dims); + } + + return element_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->elements = 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->elements = 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->element_pitch = d3dx_calculate_element_pixels_size(image->format, image->size.width, image->size.height, + image->size.depth, image->mip_levels); + expected_src_data_size = (image->element_pitch * image->elements) + 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->elements = 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 element, 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 (element >= image->elements) + { + ERR("Tried to retrieve element %u, but image only has %u elements.\n", element, image->elements); + 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 += (element * image->element_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 ba4d39fe9a7..6b488e877b1 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_4_2_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_4_2_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,32 +2519,30 @@ 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_4_2_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_4_2_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);
/* Multi-mip cubemap DDS file. */ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, D3DX_FROM_FILE, @@ -2597,9 +2593,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_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, TRUE); - check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, TRUE); + check_texture_mip_levels(cube_texture, 1, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, FALSE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE);
for (i = 0; i < 6; ++i) { @@ -2612,7 +2608,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..2301d7e2fb3 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"); @@ -1414,12 +1413,6 @@ 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; @@ -1465,14 +1458,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;
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=146962
Your paranoid android.
=== debian11 (build log) ===
WineRunWineTest.pl:error: The task timed out
=== debian11b (64 bit WoW report) ===
ddraw: ddraw1.c:3645: Test failed: Expected (0,0)-(640,480), got (-32000,-32000)-(-31840,-31969).
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/texture.c:
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 width value is
* used for the size of the created cubemap texture.
*/
Did you check that e.g. a 2x4 image makes a size 2 cube texture?
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/texture.c:
}
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_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);
- check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE);
Absolutely trivial nit: the order of these `check_` calls is different compared to the test above.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/d3dx9_private.h:
struct volume size; uint32_t mip_levels;
- uint32_t elements;
Those are usually called "layers" in modern 3D lingo, so probably `layer_count`.
(Ideally it should have been `level_count` right above it as well, like for example in wined3d. Alas I missed it at the time...)
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/texture.c:
goto err; }
- if (img_info.Width != img_info.Height)
- {
hr = D3DXERR_INVALIDDATA;
goto err;
- }
This is kind of a separate change (enabled by the rest of the implementation changes.) Can it be split out without too much fuss?
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/texture.c:
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)
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?
Sorry, it took me a while to get through this :/
I've got a small spread of comments, mostly curious about the 4x2 vs 2x4 one.