This MR adds support for the simpler fields in `D3DX10_IMAGE_LOAD_INFO`. I've deferred handling the `Filter` fields to another MR as I'm currently in the process of figuring out what the default values for those fields are. :)
-- v2: d3dx10: Add support for handling the format field in D3DX10_IMAGE_LOAD_INFO. d3dx10: Add support for custom texture dimension arguments in D3DX10_IMAGE_LOAD_INFO. d3dx10: Create 3D textures for images representing 3D textures. d3dx10: Fill pSrcInfo structure in D3DX10_IMAGE_LOAD_INFO if passed in. d3dx10/tests: Add tests for the D3DX10_IMAGE_LOAD_INFO structure argument.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 903 +++++++++++++++++++++++++++++++++- 1 file changed, 898 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 3ec21ccc7bf..21e148501b0 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -23,6 +23,12 @@ #include "wine/test.h" #include <stdint.h>
+static const D3DX10_IMAGE_LOAD_INFO d3dx10_default_load_info = +{ + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, NULL +}; + #define D3DERR_INVALIDCALL 0x8876086c
#ifndef MAKEFOURCC @@ -732,6 +738,81 @@ static const BYTE test_dds_volume_data[] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x87, 0x0f, 0x78, 0x05, 0x05, 0x50, 0x50, };
+/* + * 8x8 24-bit dds, 4 mipmaps. Level 0 is red, level 1 is green, level 2 is + * blue, and level 3 is black. + */ +static const uint8_t dds_24bit_8_8[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x08,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,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,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, + 0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, + 0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, + 0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, + 0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00, + 0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,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, + 0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0xff,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, +}; + /* 1x1 wmp image */ static const BYTE test_wmp[] = { @@ -922,6 +1003,161 @@ test_image[] = }, };
+static const struct test_image_load_info +{ + const uint8_t *data; + uint32_t size; + D3DX10_IMAGE_LOAD_INFO load_info; + HRESULT expected_hr; + + D3D10_RESOURCE_DIMENSION expected_type; + union + { + D3D10_TEXTURE2D_DESC desc_2d; + D3D10_TEXTURE3D_DESC desc_3d; + } expected_resource_desc; + BOOL todo_resource_desc; +} test_image_load_info[] = +{ + /* + * Autogen mips misc flag specified. In the case of a cube texture image, + * the autogen mips flag is OR'd against D3D10_RESOURCE_MISC_TEXTURECUBE, + * even if it isn't specified in the load info structure. + */ + { + dds_cube_map_4_4, sizeof(dds_cube_map_4_4), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, + (D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET), D3DX10_DEFAULT, D3D10_RESOURCE_MISC_GENERATE_MIPS, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE2D, + { + .desc_2d = + { + 4, 4, 3, 6, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, + (D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET), 0, + (D3D10_RESOURCE_MISC_GENERATE_MIPS | D3D10_RESOURCE_MISC_TEXTURECUBE) + } + }, .todo_resource_desc = TRUE, + }, + /* + * Pass in different dimensions and texture format than the source image. + */ + { + test_dds_dxt1, sizeof(test_dds_dxt1), + { + 8, 8, D3DX10_DEFAULT, D3DX10_DEFAULT, 1, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, D3DX10_DEFAULT, + D3DX10_DEFAULT + }, + S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE2D, + { + .desc_2d = + { + 8, 8, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0 + } + }, .todo_resource_desc = TRUE, + }, +}; + +static const struct test_invalid_image_load_info +{ + const uint8_t *data; + uint32_t size; + D3DX10_IMAGE_LOAD_INFO load_info; + HRESULT expected_hr; + HRESULT expected_process_hr; + HRESULT expected_create_device_object_hr; + BOOL todo_hr; + BOOL todo_process_hr; + BOOL todo_create_device_object_hr; +} test_invalid_image_load_info[] = +{ + /* + * A depth value that isn't D3DX10_FROM_FILE/D3DX10_DEFAULT/0 on a 2D + * texture results in failure. + */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + E_FAIL, E_FAIL, .todo_hr = TRUE, .todo_process_hr = TRUE + }, + /* Invalid filter value. */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT + }, + D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE + }, + /* Invalid mipfilter value, only validated if mips are generated. */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7 + }, + S_OK, S_OK, S_OK + }, + /* Invalid mipfilter value. */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + 2, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, 2, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7 + }, + D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE + }, + /* + * Usage/BindFlags/CpuAccessFlags are validated in the call to + * CreateDeviceObject(). + */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_CPU_ACCESS_READ, D3D10_USAGE_DYNAMIC, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + }, + /* 5. */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, + D3D10_BIND_DEPTH_STENCIL, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + }, + /* + * D3D10_RESOURCE_MISC_GENERATE_MIPS requires binding as a shader resource + * and a render target. + */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_GENERATE_MIPS, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + }, + /* Can't set the cube texture flag if the image isn't a cube texture. */ + { + test_dds_32bpp, sizeof(test_dds_32bpp), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_TEXTURECUBE, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + }, +}; + + static WCHAR temp_dir[MAX_PATH];
static DXGI_FORMAT block_compressed_formats[] = @@ -1373,7 +1609,108 @@ static inline void check_image_info_values_(uint32_t line, const D3DX10_IMAGE_IN image_file_format, info->ImageFileFormat); }
-static ID3D10Texture2D *get_texture2d_readback(ID3D10Texture2D *texture) +#define check_texture2d_desc(desc, expected, wine_todo) check_texture2d_desc_(__LINE__, desc, expected, wine_todo) +static inline void check_texture2d_desc_(uint32_t line, const D3D10_TEXTURE2D_DESC *desc, const D3D10_TEXTURE2D_DESC *expected, + BOOL wine_todo) +{ + BOOL matched; + + matched = !memcmp(expected, desc, sizeof(*desc)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected 2D texture desc values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && desc->Width != expected->Width) + ok_(__FILE__, line)(desc->Width == expected->Width, "Expected width %u, got %u.\n", expected->Width, + desc->Width); + todo_wine_if(wine_todo && desc->Height != expected->Height) + ok_(__FILE__, line)(desc->Height == expected->Height, "Expected height %u, got %u.\n", expected->Height, + desc->Height); + todo_wine_if(wine_todo && desc->ArraySize != expected->ArraySize) + ok_(__FILE__, line)(desc->ArraySize == expected->ArraySize, "Expected array size %u, got %u.\n", + expected->ArraySize, desc->ArraySize); + todo_wine_if(wine_todo && desc->MipLevels != expected->MipLevels) + ok_(__FILE__, line)(desc->MipLevels == expected->MipLevels, "Expected mip levels %u, got %u.\n", + expected->MipLevels, desc->MipLevels); + todo_wine_if(wine_todo && desc->Format != expected->Format) + ok_(__FILE__, line)(desc->Format == expected->Format, "Expected texture format %#x, got %#x.\n", + expected->Format, desc->Format); + todo_wine_if(wine_todo && desc->SampleDesc.Count != expected->SampleDesc.Count) + ok_(__FILE__, line)(desc->SampleDesc.Count == expected->SampleDesc.Count, "Expected sample count %u, got %u.\n", + expected->SampleDesc.Count, desc->SampleDesc.Count); + todo_wine_if(wine_todo && desc->SampleDesc.Quality != expected->SampleDesc.Quality) + ok_(__FILE__, line)(desc->SampleDesc.Quality == expected->SampleDesc.Quality, + "Expected sample quality %u, got %u.\n", expected->SampleDesc.Quality, desc->SampleDesc.Quality); + todo_wine_if(wine_todo && desc->Usage != expected->Usage) + ok_(__FILE__, line)(desc->Usage == expected->Usage, "Expected usage %u, got %u.\n", expected->Usage, + desc->Usage); + todo_wine_if(wine_todo && desc->BindFlags != expected->BindFlags) + ok_(__FILE__, line)(desc->BindFlags == expected->BindFlags, "Expected bind flags %#x, got %#x.\n", + expected->BindFlags, desc->BindFlags); + todo_wine_if(wine_todo && desc->CPUAccessFlags != expected->CPUAccessFlags) + ok_(__FILE__, line)(desc->CPUAccessFlags == expected->CPUAccessFlags, + "Expected CPU access flags %#x, got %#x.\n", expected->CPUAccessFlags, desc->CPUAccessFlags); + todo_wine_if(wine_todo && desc->MiscFlags != expected->MiscFlags) + ok_(__FILE__, line)(desc->MiscFlags == expected->MiscFlags, "Expected misc flags %#x, got %#x.\n", + expected->MiscFlags, desc->MiscFlags); +} + +#define check_texture2d_desc_values(desc, width, height, mip_levels, array_size, format, sample_count, sample_quality, \ + usage, bind_flags, cpu_access_flags, misc_flags, wine_todo) \ + check_texture2d_desc_values_(__LINE__, desc, width, height, mip_levels, array_size, format, sample_count, sample_quality, \ + usage, bind_flags, cpu_access_flags, misc_flags, wine_todo) +static inline void check_texture2d_desc_values_(uint32_t line, const D3D10_TEXTURE2D_DESC *desc, uint32_t width, + uint32_t height, uint32_t mip_levels, uint32_t array_size, DXGI_FORMAT format, uint32_t sample_count, + uint32_t sample_quality, D3D10_USAGE usage, uint32_t bind_flags, uint32_t cpu_access_flags, uint32_t misc_flags, + BOOL wine_todo) +{ + const D3D10_TEXTURE2D_DESC expected_desc = { width, height, mip_levels, array_size, format, { sample_count, sample_quality }, + usage, bind_flags, cpu_access_flags, misc_flags }; + + check_texture2d_desc_(line, desc, &expected_desc, wine_todo); +} + +#define check_texture3d_desc(desc, expected, wine_todo) check_texture3d_desc_(__LINE__, desc, expected, wine_todo) +static inline void check_texture3d_desc_(uint32_t line, const D3D10_TEXTURE3D_DESC *desc, + const D3D10_TEXTURE3D_DESC *expected, BOOL wine_todo) +{ + BOOL matched; + + matched = !memcmp(expected, desc, sizeof(*desc)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected 3D texture desc values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && desc->Width != expected->Width) + ok_(__FILE__, line)(desc->Width == expected->Width, "Expected width %u, got %u.\n", expected->Width, + desc->Width); + todo_wine_if(wine_todo && desc->Height != expected->Height) + ok_(__FILE__, line)(desc->Height == expected->Height, "Expected height %u, got %u.\n", expected->Height, + desc->Height); + todo_wine_if(wine_todo && desc->Depth != expected->Depth) + ok_(__FILE__, line)(desc->Depth == expected->Depth, "Expected depth %u, got %u.\n", expected->Depth, + desc->Depth); + todo_wine_if(wine_todo && desc->MipLevels != expected->MipLevels) + ok_(__FILE__, line)(desc->MipLevels == expected->MipLevels, "Expected mip levels %u, got %u.\n", + expected->MipLevels, desc->MipLevels); + todo_wine_if(wine_todo && desc->Format != expected->Format) + ok_(__FILE__, line)(desc->Format == expected->Format, "Expected texture format %#x, got %#x.\n", + expected->Format, desc->Format); + todo_wine_if(wine_todo && desc->Usage != expected->Usage) + ok_(__FILE__, line)(desc->Usage == expected->Usage, "Expected usage %u, got %u.\n", expected->Usage, + desc->Usage); + todo_wine_if(wine_todo && desc->BindFlags != expected->BindFlags) + ok_(__FILE__, line)(desc->BindFlags == expected->BindFlags, "Expected bind flags %#x, got %#x.\n", + expected->BindFlags, desc->BindFlags); + todo_wine_if(wine_todo && desc->CPUAccessFlags != expected->CPUAccessFlags) + ok_(__FILE__, line)(desc->CPUAccessFlags == expected->CPUAccessFlags, + "Expected CPU access flags %#x, got %#x.\n", expected->CPUAccessFlags, desc->CPUAccessFlags); + todo_wine_if(wine_todo && desc->MiscFlags != expected->MiscFlags) + ok_(__FILE__, line)(desc->MiscFlags == expected->MiscFlags, "Expected misc flags %#x, got %#x.\n", + expected->MiscFlags, desc->MiscFlags); +} + +static ID3D10Texture2D *get_texture2d_readback_iface(ID3D10Texture2D *texture) { D3D10_TEXTURE2D_DESC desc; ID3D10Texture2D *readback; @@ -1399,7 +1736,7 @@ static ID3D10Texture2D *get_texture2d_readback(ID3D10Texture2D *texture) return readback; }
-static ID3D10Texture3D *get_texture3d_readback(ID3D10Texture3D *texture) +static ID3D10Texture3D *get_texture3d_readback_iface(ID3D10Texture3D *texture) { D3D10_TEXTURE3D_DESC desc; ID3D10Texture3D *readback; @@ -1425,6 +1762,57 @@ static ID3D10Texture3D *get_texture3d_readback(ID3D10Texture3D *texture) return readback; }
+#define check_test_image_load_info_resource(resource, image_load_info) \ + check_test_image_load_info_resource_(__LINE__, resource, image_load_info) +static void check_test_image_load_info_resource_(uint32_t line, ID3D10Resource *resource, + const struct test_image_load_info *image_load_info) +{ + D3D10_RESOURCE_DIMENSION resource_dimension; + HRESULT hr; + + ID3D10Resource_GetType(resource, &resource_dimension); + todo_wine_if(image_load_info->expected_type == D3D10_RESOURCE_DIMENSION_TEXTURE3D) + ok(resource_dimension == image_load_info->expected_type, "Got unexpected ResourceDimension %u, expected %u.\n", + resource_dimension, image_load_info->expected_type); + + if (resource_dimension != image_load_info->expected_type) + return; + + switch (resource_dimension) + { + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + { + const D3D10_TEXTURE2D_DESC *expected_desc_2d = &image_load_info->expected_resource_desc.desc_2d; + D3D10_TEXTURE2D_DESC desc_2d; + ID3D10Texture2D *tex_2d; + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&tex_2d); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID3D10Texture2D_GetDesc(tex_2d, &desc_2d); + check_texture2d_desc_(line, &desc_2d, expected_desc_2d, image_load_info->todo_resource_desc); + ID3D10Texture2D_Release(tex_2d); + break; + } + + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + { + const D3D10_TEXTURE3D_DESC *expected_desc_3d = &image_load_info->expected_resource_desc.desc_3d; + D3D10_TEXTURE3D_DESC desc_3d; + ID3D10Texture3D *tex_3d; + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture3D, (void **)&tex_3d); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID3D10Texture3D_GetDesc(tex_3d, &desc_3d); + check_texture3d_desc_(line, &desc_3d, expected_desc_3d, image_load_info->todo_resource_desc); + ID3D10Texture3D_Release(tex_3d); + break; + } + + default: + break; + } +} + static void check_resource_info(ID3D10Resource *resource, const struct test_image *image, unsigned int line) { unsigned int expected_mip_levels, expected_width, expected_height, max_dimension; @@ -1549,7 +1937,7 @@ static void check_texture2d_data(ID3D10Texture2D *texture, const struct test_ima BOOL line_match; HRESULT hr;
- readback = get_texture2d_readback(texture); + readback = get_texture2d_readback_iface(texture); ok_(__FILE__, line)(readback != NULL, "Failed to get texture readback.\n"); if (!readback) return; @@ -1603,7 +1991,7 @@ static void check_texture3d_data(ID3D10Texture3D *texture, const struct test_ima BOOL line_match; HRESULT hr;
- readback = get_texture3d_readback(texture); + readback = get_texture3d_readback_iface(texture); ok_(__FILE__, line)(readback != NULL, "Failed to get texture readback.\n"); if (!readback) return; @@ -1661,6 +2049,140 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag } }
+/* + * Taken from the d3d10core tests. If there's a missing resource type or + * texture format checking function, check to see if it exists there first. + */ +struct resource_readback +{ + D3D10_RESOURCE_DIMENSION dimension; + ID3D10Resource *resource; + D3D10_MAPPED_TEXTURE3D map_desc; + uint32_t width, height, depth, sub_resource_idx; +}; + +static void get_texture_readback(ID3D10Texture2D *texture, uint32_t sub_resource_idx, + struct resource_readback *rb) +{ + D3D10_TEXTURE2D_DESC texture_desc; + D3D10_MAPPED_TEXTURE2D map_desc; + uint32_t miplevel; + ID3D10Device *device; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + rb->dimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + + ID3D10Texture2D_GetDevice(texture, &device); + + ID3D10Texture2D_GetDesc(texture, &texture_desc); + texture_desc.Usage = D3D10_USAGE_STAGING; + texture_desc.BindFlags = 0; + texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; + texture_desc.MiscFlags = 0; + if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D10Texture2D **)&rb->resource))) + { + trace("Failed to create texture, hr %#lx.\n", hr); + ID3D10Device_Release(device); + return; + } + + miplevel = sub_resource_idx % texture_desc.MipLevels; + rb->width = max(1, texture_desc.Width >> miplevel); + rb->height = max(1, texture_desc.Height >> miplevel); + rb->depth = 1; + rb->sub_resource_idx = sub_resource_idx; + + ID3D10Device_CopyResource(device, rb->resource, (ID3D10Resource *)texture); + if (FAILED(hr = ID3D10Texture2D_Map((ID3D10Texture2D *)rb->resource, sub_resource_idx, + D3D10_MAP_READ, 0, &map_desc))) + { + trace("Failed to map sub-resource %u, hr %#lx.\n", sub_resource_idx, hr); + ID3D10Resource_Release(rb->resource); + rb->resource = NULL; + } + rb->map_desc.pData = map_desc.pData; + rb->map_desc.RowPitch = map_desc.RowPitch; + rb->map_desc.DepthPitch = 0; + + ID3D10Device_Release(device); +} + +static void *get_readback_data(struct resource_readback *rb, uint32_t x, uint32_t y, unsigned byte_width) +{ + return (uint8_t *)rb->map_desc.pData + y * rb->map_desc.RowPitch + x * byte_width; +} + +static uint32_t get_readback_u32(struct resource_readback *rb, uint32_t x, uint32_t y) +{ + return *(uint32_t *)get_readback_data(rb, x, y, sizeof(uint32_t)); +} + +static void release_resource_readback(struct resource_readback *rb) +{ + switch (rb->dimension) + { + case D3D10_RESOURCE_DIMENSION_BUFFER: + ID3D10Buffer_Unmap((ID3D10Buffer *)rb->resource); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE1D: + ID3D10Texture1D_Unmap((ID3D10Texture1D *)rb->resource, rb->sub_resource_idx); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + ID3D10Texture2D_Unmap((ID3D10Texture2D *)rb->resource, rb->sub_resource_idx); + break; + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + ID3D10Texture3D_Unmap((ID3D10Texture3D *)rb->resource, rb->sub_resource_idx); + break; + default: + trace("Unhandled resource dimension %#x.\n", rb->dimension); + break; + } + ID3D10Resource_Release(rb->resource); +} + +#define check_readback_data_u32(a, b, c) check_readback_data_u32_(__LINE__, a, b, c) +static void check_readback_data_u32_(unsigned int line, struct resource_readback *rb, + const RECT *rect, uint32_t expected) +{ + unsigned int x = 0, y = 0; + BOOL all_match = FALSE; + RECT default_rect; + uint32_t got = 0; + + if (!rect) + { + SetRect(&default_rect, 0, 0, rb->width, rb->height); + rect = &default_rect; + } + + for (y = rect->top; y < rect->bottom; ++y) + { + for (x = rect->left; x < rect->right; ++x) + { + if ((got = get_readback_u32(rb, x, y)) != expected) + goto done; + } + } + all_match = TRUE; + +done: + ok_(__FILE__, line)(all_match, + "Got 0x%08x, expected 0x%08x at (%u, %u), sub-resource %u.\n", + got, expected, x, y, rb->sub_resource_idx); +} + +#define check_texture_sub_resource_u32(a, b, c, d) check_texture_sub_resource_u32_(__LINE__, a, b, c, d) +static void check_texture_sub_resource_u32_(uint32_t line, ID3D10Texture2D *texture, + uint32_t sub_resource_idx, const RECT *rect, uint32_t expected) +{ + struct resource_readback rb; + + get_texture_readback(texture, sub_resource_idx, &rb); + check_readback_data_u32_(line, &rb, rect, expected); + release_resource_readback(&rb); +} + static void test_D3DX10UnsetAllDeviceObjects(void) { static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = @@ -2457,6 +2979,9 @@ static void test_D3DX10CreateAsyncTextureProcessor(void)
for (i = 0; i < ARRAY_SIZE(test_image); ++i) { + D3DX10_IMAGE_LOAD_INFO load_info; + D3DX10_IMAGE_INFO info; + winetest_push_context("Test %u", i);
hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &dp); @@ -2477,6 +3002,80 @@ static void test_D3DX10CreateAsyncTextureProcessor(void) hr = ID3DX10DataProcessor_Destroy(dp); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Test behavior with load_info structure values set to defaults. */ + load_info = d3dx10_default_load_info; + + hr = D3DX10CreateAsyncTextureProcessor(device, &load_info, &dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[i].data, test_image[i].size); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* Check that passed in D3DX10_IMAGE_INFO structure is filled. */ + memset(&info, 0, sizeof(info)); + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &info; + + hr = D3DX10CreateAsyncTextureProcessor(device, &load_info, &dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[i].data, test_image[i].size); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + todo_wine ok(!memcmp(&test_image[i].expected_info, &info, sizeof(info)), "Unexpected image info.\n"); + hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + winetest_pop_context(); + } + + for (i = 0; i < ARRAY_SIZE(test_invalid_image_load_info); ++i) + { + const struct test_invalid_image_load_info *test = &test_invalid_image_load_info[i]; + D3DX10_IMAGE_LOAD_INFO load_info = test->load_info; + + winetest_push_context("Test %u", i); + + hr = D3DX10CreateAsyncTextureProcessor(device, &load_info, &dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3DX10DataProcessor_Process(dp, (void *)test->data, test->size); + todo_wine_if(test->todo_process_hr) + ok(hr == test->expected_process_hr, "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + resource = NULL; + hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource); + todo_wine_if(test->todo_create_device_object_hr) + ok(hr == test->expected_create_device_object_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + } + + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + winetest_pop_context(); }
@@ -3520,14 +4119,19 @@ static void test_get_image_info(void)
static void test_create_texture(void) { + static const uint32_t dds_24bit_8_8_mip_level_expected[] = { 0xff0000ff, 0xff00ff00, 0xffff0000, 0xff000000 }; static const WCHAR test_resource_name[] = L"resource.data"; static const WCHAR test_filename[] = L"image.data"; + D3D10_TEXTURE2D_DESC tex_2d_desc; + D3DX10_IMAGE_LOAD_INFO load_info; + D3DX10_IMAGE_INFO img_info; + unsigned int i, mip_level; ID3D10Resource *resource; + ID3D10Texture2D *tex_2d; HMODULE resource_module; ID3D10Device *device; WCHAR path[MAX_PATH]; HRESULT hr, hr2; - unsigned int i;
device = create_device(); if (!device) @@ -3591,9 +4195,177 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); }
+ /* Test behavior with load_info structure values set to defaults. */ + load_info = d3dx10_default_load_info; + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + /* Check that passed in D3DX10_IMAGE_INFO structure is filled. */ + memset(&img_info, 0, sizeof(img_info)); + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &img_info; + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + todo_wine ok(!memcmp(&test_image[i].expected_info, &img_info, sizeof(img_info)), "Unexpected image info.\n"); + ID3D10Resource_Release(resource); + } + + winetest_pop_context(); + } + + for (i = 0; i < ARRAY_SIZE(test_invalid_image_load_info); ++i) + { + const struct test_invalid_image_load_info *test = &test_invalid_image_load_info[i]; + + winetest_push_context("Test %u", i); + + hr2 = 0xdeadbeef; + load_info = test->load_info; + hr = D3DX10CreateTextureFromMemory(device, test->data, test->size, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + todo_wine_if(test->todo_hr) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + + winetest_pop_context(); + } + + for (i = 0; i < ARRAY_SIZE(test_image_load_info); ++i) + { + const struct test_image_load_info *test = &test_image_load_info[i]; + + winetest_push_context("Test %u", i); + + load_info = test->load_info; + resource = NULL; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test->data, test->size, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_test_image_load_info_resource(resource, test); + ID3D10Resource_Release(resource); + } + + winetest_pop_context(); + } + + /* + * Test behavior of the FirstMipLevel argument, including checks of the + * values loaded into each level of the created texture. + */ + for (i = 0; i < 2; ++i) + { + if (i && D3DX10_SDK_VERSION == 33) + { + skip("FirstMipLevel argument is broken in version 33.\n"); + continue; + } + + winetest_push_context("FirstMipLevel %u", i); + memset(&img_info, 0, sizeof(img_info)); + load_info = d3dx10_default_load_info; + load_info.FirstMipLevel = i; + load_info.MipLevels = D3DX10_FROM_FILE; + load_info.pSrcInfo = &img_info; + + resource = NULL; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, dds_24bit_8_8, sizeof(dds_24bit_8_8), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&tex_2d); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + /* + * The FirstMipLevel behavior does not exactly match D3DX_SKIP_DDS_MIP_LEVEL + * from d3dx9, image info values always represent mip level 0 regardless of + * what FirstMipLevel is set to. Further, texture dimensions are + * always based on mip level 0, and the number of mip levels is always the same + * as the number in the image info structure. + */ + ID3D10Texture2D_GetDesc(tex_2d, &tex_2d_desc); + check_texture2d_desc_values(&tex_2d_desc, 8, 8, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 1, 0, D3D10_USAGE_DEFAULT, + D3D10_BIND_SHADER_RESOURCE, 0, 0, FALSE); + if (img_info.Width) + { + check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, TRUE); + } + + /* + * Image data is loaded starting from the mip level provided by + * FirstMipLevel. This behavior does match d3dx9's D3DX_SKIP_DDS_MIP_LEVEL. + */ + for (mip_level = 0; mip_level < 4; ++mip_level) + { + winetest_push_context("MipLevel %u", mip_level); + todo_wine_if(i && mip_level != 3) check_texture_sub_resource_u32(tex_2d, mip_level, NULL, + dds_24bit_8_8_mip_level_expected[min(3, mip_level + i)]); + winetest_pop_context(); + } + + ID3D10Texture2D_Release(tex_2d); + ID3D10Resource_Release(resource); + winetest_pop_context(); + } + + /* + * If FirstMipLevel is set to a value that is larger than the total number + * of mip levels in the image, it falls back to 0. + */ + memset(&img_info, 0, sizeof(img_info)); + load_info = d3dx10_default_load_info; + load_info.FirstMipLevel = 5; + load_info.MipLevels = D3DX10_FROM_FILE; + load_info.pSrcInfo = &img_info; + + resource = NULL; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, dds_24bit_8_8, sizeof(dds_24bit_8_8), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (img_info.Width) + { + check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, TRUE); + } + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&tex_2d); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID3D10Texture2D_GetDesc(tex_2d, &tex_2d_desc); + check_texture2d_desc_values(&tex_2d_desc, 8, 8, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 1, 0, D3D10_USAGE_DEFAULT, + D3D10_BIND_SHADER_RESOURCE, 0, 0, FALSE); + for (mip_level = 0; mip_level < 4; ++mip_level) + { + winetest_push_context("MipLevel %u", mip_level); + check_texture_sub_resource_u32(tex_2d, mip_level, NULL, dds_24bit_8_8_mip_level_expected[mip_level]); winetest_pop_context(); }
+ ID3D10Texture2D_Release(tex_2d); + ID3D10Resource_Release(resource); + hr2 = 0xdeadbeef; add_work_item_count = 0; hr = D3DX10CreateTextureFromMemory(device, test_image[0].data, test_image[0].size, @@ -3657,6 +4429,64 @@ static void test_create_texture(void) winetest_pop_context(); }
+ for (i = 0; i < ARRAY_SIZE(test_invalid_image_load_info); ++i) + { + const struct test_invalid_image_load_info *test = &test_invalid_image_load_info[i]; + + winetest_push_context("Test %u", i); + create_file(test_filename, test->data, test->size, path); + load_info = test->load_info; + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + todo_wine_if(test->todo_hr) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + + hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + todo_wine_if(test->todo_hr) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + + delete_file(test_filename); + winetest_pop_context(); + } + + for (i = 0; i < ARRAY_SIZE(test_image_load_info); ++i) + { + const struct test_image_load_info *test = &test_image_load_info[i]; + + winetest_push_context("Test %u", i); + create_file(test_filename, test->data, test->size, path); + load_info = test->load_info; + + resource = NULL; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_test_image_load_info_resource(resource, test); + ID3D10Resource_Release(resource); + } + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_test_image_load_info_resource(resource, test); + ID3D10Resource_Release(resource); + } + + delete_file(test_filename); + winetest_pop_context(); + } + /* D3DX10CreateTextureFromResource tests */
hr2 = 0xdeadbeef; @@ -3716,6 +4546,69 @@ static void test_create_texture(void) winetest_pop_context(); }
+ for (i = 0; i < ARRAY_SIZE(test_invalid_image_load_info); ++i) + { + const struct test_invalid_image_load_info *test = &test_invalid_image_load_info[i]; + + winetest_push_context("Test %u", i); + resource_module = create_resource_module(test_resource_name, test->data, test->size); + load_info = test->load_info; + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, resource_module, + test_resource_name, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + todo_wine_if(test->todo_hr) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceA(device, resource_module, + get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + todo_wine_if(test->todo_hr) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + ID3D10Resource_Release(resource); + + delete_resource_module(test_resource_name, resource_module); + winetest_pop_context(); + } + + for (i = 0; i < ARRAY_SIZE(test_image_load_info); ++i) + { + const struct test_image_load_info *test = &test_image_load_info[i]; + + winetest_push_context("Test %u", i); + resource_module = create_resource_module(test_resource_name, test->data, test->size); + load_info = test->load_info; + + resource = NULL; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, resource_module, + test_resource_name, &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_test_image_load_info_resource(resource, test); + ID3D10Resource_Release(resource); + } + + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceA(device, resource_module, + get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + check_test_image_load_info_resource(resource, test); + ID3D10Resource_Release(resource); + } + + delete_resource_module(test_resource_name, resource_module); + winetest_pop_context(); + } + CoUninitialize();
ok(!ID3D10Device_Release(device), "Unexpected refcount.\n");
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 18 ++++++------------ dlls/d3dx10_43/texture.c | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 21e148501b0..c86223a5bf3 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3036,7 +3036,7 @@ static void test_D3DX10CreateAsyncTextureProcessor(void) "Got unexpected hr %#lx.\n", hr); if (hr == S_OK) { - todo_wine ok(!memcmp(&test_image[i].expected_info, &info, sizeof(info)), "Unexpected image info.\n"); + ok(!memcmp(&test_image[i].expected_info, &info, sizeof(info)), "Unexpected image info.\n"); hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); check_resource_info(resource, test_image + i, __LINE__); @@ -4224,7 +4224,7 @@ static void test_create_texture(void) { check_resource_info(resource, test_image + i, __LINE__); check_resource_data(resource, test_image + i, __LINE__); - todo_wine ok(!memcmp(&test_image[i].expected_info, &img_info, sizeof(img_info)), "Unexpected image info.\n"); + ok(!memcmp(&test_image[i].expected_info, &img_info, sizeof(img_info)), "Unexpected image info.\n"); ID3D10Resource_Release(resource); }
@@ -4307,11 +4307,8 @@ static void test_create_texture(void) ID3D10Texture2D_GetDesc(tex_2d, &tex_2d_desc); check_texture2d_desc_values(&tex_2d_desc, 8, 8, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 1, 0, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0, FALSE); - if (img_info.Width) - { - check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, - D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, TRUE); - } + check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, FALSE);
/* * Image data is loaded starting from the mip level provided by @@ -4345,11 +4342,8 @@ static void test_create_texture(void) hr = D3DX10CreateTextureFromMemory(device, dds_24bit_8_8, sizeof(dds_24bit_8_8), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (img_info.Width) - { - check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, - D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, TRUE); - } + check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, FALSE);
hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&tex_2d); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 85459cc9a56..46dd323239e 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -668,8 +668,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO FIXME("load_info->Filter is ignored.\n"); if (load_info->MipFilter != D3DX10_DEFAULT) FIXME("load_info->MipFilter is ignored.\n"); - if (load_info->pSrcInfo) - FIXME("load_info->pSrcInfo is ignored.\n");
*resource_data = NULL; hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10); @@ -764,6 +762,8 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO load_info->Usage = D3D10_USAGE_DEFAULT; load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; load_info->MiscFlags = img_info.MiscFlags; + if (load_info->pSrcInfo) + *load_info->pSrcInfo = img_info;
res_data = NULL;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/async.c | 11 ++++- dlls/d3dx10_43/tests/d3dx10.c | 35 ++++++++++------ dlls/d3dx10_43/texture.c | 76 ++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 31 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c index 62627886804..e2cd14a7736 100644 --- a/dlls/d3dx10_43/async.c +++ b/dlls/d3dx10_43/async.c @@ -322,6 +322,8 @@ struct texture_processor { ID3DX10DataProcessor ID3DX10DataProcessor_iface; ID3D10Device *device; + D3DX10_IMAGE_INFO img_info; + D3DX10_IMAGE_INFO *img_info_out; D3DX10_IMAGE_LOAD_INFO load_info; D3D10_SUBRESOURCE_DATA *resource_data; }; @@ -334,6 +336,7 @@ static inline struct texture_processor *texture_processor_from_ID3DX10DataProces static HRESULT WINAPI texture_processor_Process(ID3DX10DataProcessor *iface, void *data, SIZE_T size) { struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface); + HRESULT hr;
TRACE("iface %p, data %p, size %Iu.\n", iface, data, size);
@@ -343,7 +346,10 @@ static HRESULT WINAPI texture_processor_Process(ID3DX10DataProcessor *iface, voi free(processor->resource_data); processor->resource_data = NULL; } - return load_texture_data(data, size, &processor->load_info, &processor->resource_data); + hr = load_texture_data(data, size, &processor->load_info, &processor->resource_data); + if (SUCCEEDED(hr) && processor->img_info_out) + *processor->img_info_out = processor->img_info; + return hr; }
static HRESULT WINAPI texture_processor_CreateDeviceObject(ID3DX10DataProcessor *iface, void **object) @@ -594,7 +600,10 @@ HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *device, object->ID3DX10DataProcessor_iface.lpVtbl = &texture_processor_vtbl; object->device = device; ID3D10Device_AddRef(device); + if (load_info) + object->img_info_out = load_info->pSrcInfo; init_load_info(load_info, &object->load_info); + object->load_info.pSrcInfo = &object->img_info;
*processor = &object->ID3DX10DataProcessor_iface; return S_OK; diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index c86223a5bf3..cc3d8e8378c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -20,6 +20,7 @@ #include "initguid.h" #include "d3d10_1.h" #include "d3dx10.h" +#include "wine/wined3d.h" #include "wine/test.h" #include <stdint.h>
@@ -75,6 +76,8 @@ static const D3DX10_IMAGE_LOAD_INFO d3dx10_default_load_info = #define DDS_PF_BUMPLUMINANCE 0x00040000 #define DDS_PF_BUMPDUDV 0x00080000
+static bool wined3d_opengl; + struct dds_pixel_format { DWORD size; @@ -1771,13 +1774,8 @@ static void check_test_image_load_info_resource_(uint32_t line, ID3D10Resource * HRESULT hr;
ID3D10Resource_GetType(resource, &resource_dimension); - todo_wine_if(image_load_info->expected_type == D3D10_RESOURCE_DIMENSION_TEXTURE3D) - ok(resource_dimension == image_load_info->expected_type, "Got unexpected ResourceDimension %u, expected %u.\n", - resource_dimension, image_load_info->expected_type); - - if (resource_dimension != image_load_info->expected_type) - return; - + ok(resource_dimension == image_load_info->expected_type, "Got unexpected ResourceDimension %u, expected %u.\n", + resource_dimension, image_load_info->expected_type); switch (resource_dimension) { case D3D10_RESOURCE_DIMENSION_TEXTURE2D: @@ -1839,10 +1837,9 @@ static void check_resource_info(ID3D10Resource *resource, const struct test_imag }
ID3D10Resource_GetType(resource, &resource_dimension); - todo_wine_if (image->expected_info.ResourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D) - ok(resource_dimension == image->expected_info.ResourceDimension, - "Got unexpected ResourceDimension %u, expected %u.\n", - resource_dimension, image->expected_info.ResourceDimension); + ok(resource_dimension == image->expected_info.ResourceDimension, + "Got unexpected ResourceDimension %u, expected %u.\n", + resource_dimension, image->expected_info.ResourceDimension);
switch (resource_dimension) { @@ -2035,7 +2032,10 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag
if (SUCCEEDED(ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture3D, (void **)&texture3d))) { - check_texture3d_data(texture3d, image, line); + if (wined3d_opengl && is_block_compressed(image->expected_info.Format)) + skip("Skipping compressed format 3D texture readback test.\n"); + else + check_texture3d_data(texture3d, image, line); ID3D10Texture3D_Release(texture3d); } else if (SUCCEEDED(ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&texture2d))) @@ -6068,6 +6068,17 @@ static void test_preprocess_shader(void)
START_TEST(d3dx10) { + HMODULE wined3d; + + if ((wined3d = GetModuleHandleA("wined3d.dll"))) + { + enum wined3d_renderer (CDECL *p_wined3d_get_renderer)(void); + + if ((p_wined3d_get_renderer = (void *)GetProcAddress(wined3d, "wined3d_get_renderer")) + && p_wined3d_get_renderer() == WINED3D_RENDERER_OPENGL) + wined3d_opengl = true; + } + test_D3DX10UnsetAllDeviceObjects(); test_D3DX10CreateAsyncMemoryLoader(); test_D3DX10CreateAsyncFileLoader(); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 46dd323239e..1d60af1724e 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -23,6 +23,7 @@ #include "d3d10_1.h" #include "d3dx10.h" #include "dxhelpers.h" +#include <assert.h>
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
@@ -440,9 +441,12 @@ static HRESULT create_texture(ID3D10Device *device, const void *data, SIZE_T siz { D3D10_SUBRESOURCE_DATA *resource_data; D3DX10_IMAGE_LOAD_INFO load_info_copy; + D3DX10_IMAGE_INFO img_info; HRESULT hr;
init_load_info(load_info, &load_info_copy); + if (!load_info_copy.pSrcInfo) + load_info_copy.pSrcInfo = &img_info;
if (FAILED((hr = load_texture_data(data, size, &load_info_copy, &resource_data)))) return hr; @@ -762,8 +766,12 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO load_info->Usage = D3D10_USAGE_DEFAULT; load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; load_info->MiscFlags = img_info.MiscFlags; - if (load_info->pSrcInfo) - *load_info->pSrcInfo = img_info; + /* + * Must be present in order to get resource dimension for texture + * creation. + */ + assert(load_info->pSrcInfo); + *load_info->pSrcInfo = img_info;
res_data = NULL;
@@ -776,25 +784,57 @@ end: HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info, D3D10_SUBRESOURCE_DATA *resource_data, ID3D10Resource **texture) { - D3D10_TEXTURE2D_DESC texture_2d_desc; - ID3D10Texture2D *texture_2d; HRESULT hr;
- memset(&texture_2d_desc, 0, sizeof(texture_2d_desc)); - texture_2d_desc.Width = load_info->Width; - texture_2d_desc.Height = load_info->Height; - texture_2d_desc.MipLevels = load_info->MipLevels; - texture_2d_desc.ArraySize = load_info->MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE ? 6 : 1; - texture_2d_desc.Format = load_info->Format; - texture_2d_desc.SampleDesc.Count = 1; - texture_2d_desc.Usage = load_info->Usage; - texture_2d_desc.BindFlags = load_info->BindFlags; - texture_2d_desc.MiscFlags = load_info->MiscFlags; - - if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, resource_data, &texture_2d))) - return hr; + *texture = NULL; + switch (load_info->pSrcInfo->ResourceDimension) + { + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D10_TEXTURE2D_DESC texture_2d_desc = { 0 }; + ID3D10Texture2D *texture_2d; + + texture_2d_desc.Width = load_info->Width; + texture_2d_desc.Height = load_info->Height; + texture_2d_desc.MipLevels = load_info->MipLevels; + texture_2d_desc.ArraySize = load_info->MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE ? 6 : 1; + texture_2d_desc.Format = load_info->Format; + texture_2d_desc.SampleDesc.Count = 1; + texture_2d_desc.Usage = load_info->Usage; + texture_2d_desc.BindFlags = load_info->BindFlags; + texture_2d_desc.MiscFlags = load_info->MiscFlags; + + if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, resource_data, &texture_2d))) + return hr; + *texture = (ID3D10Resource *)texture_2d; + break; + } + + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D10_TEXTURE3D_DESC texture_3d_desc = { 0 }; + ID3D10Texture3D *texture_3d; + + texture_3d_desc.Width = load_info->Width; + texture_3d_desc.Height = load_info->Height; + texture_3d_desc.Depth = load_info->Depth; + texture_3d_desc.MipLevels = load_info->MipLevels; + texture_3d_desc.Format = load_info->Format; + texture_3d_desc.Usage = load_info->Usage; + texture_3d_desc.BindFlags = load_info->BindFlags; + texture_3d_desc.MiscFlags = load_info->MiscFlags; + + if (FAILED(hr = ID3D10Device_CreateTexture3D(device, &texture_3d_desc, resource_data, &texture_3d))) + return hr; + *texture = (ID3D10Resource *)texture_3d; + break; + } + + default: + FIXME("Unhandled resource dimension %d.\n", load_info->pSrcInfo->ResourceDimension); + return E_NOTIMPL; + }
- *texture = (ID3D10Resource *)texture_2d; return S_OK; }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index cc3d8e8378c..a849d552fde 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1087,7 +1087,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, - E_FAIL, E_FAIL, .todo_hr = TRUE, .todo_process_hr = TRUE + E_FAIL, E_FAIL }, /* Invalid filter value. */ { diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 1d60af1724e..aa056fd40c2 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -648,12 +648,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO if (!data || !size) return E_FAIL;
- if (load_info->Width != D3DX10_DEFAULT) - FIXME("load_info->Width is ignored.\n"); - if (load_info->Height != D3DX10_DEFAULT) - FIXME("load_info->Height is ignored.\n"); - if (load_info->Depth != D3DX10_DEFAULT) - FIXME("load_info->Depth is ignored.\n"); if (load_info->FirstMipLevel != D3DX10_DEFAULT) FIXME("load_info->FirstMipLevel is ignored.\n"); if (load_info->MipLevels != D3DX10_DEFAULT) @@ -704,9 +698,20 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO }
/* Potentially round up width/height to align with block size. */ - load_info->Width = (img_info.Width + fmt_desc->block_width - 1) & ~(fmt_desc->block_width - 1); - load_info->Height = (img_info.Height + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1); - load_info->Depth = img_info.Depth; + if (!load_info->Width || load_info->Width == D3DX10_FROM_FILE || load_info->Width == D3DX10_DEFAULT) + load_info->Width = (img_info.Width + fmt_desc->block_width - 1) & ~(fmt_desc->block_width - 1); + if (!load_info->Height || load_info->Height == D3DX10_FROM_FILE || load_info->Height == D3DX10_DEFAULT) + load_info->Height = (img_info.Height + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1); + if (!load_info->Depth || load_info->Depth == D3DX10_FROM_FILE || load_info->Depth == D3DX10_DEFAULT) + load_info->Depth = img_info.Depth; + + if ((load_info->Depth > 1) && (img_info.ResourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE3D)) + { + WARN("Invalid depth value %u for image with dimension %d.\n", load_info->Depth, img_info.ResourceDimension); + hr = E_FAIL; + goto end; + } + load_info->MipLevels = img_info.MipLevels;
pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, load_info->Width, load_info->Height,
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index a849d552fde..230f824a24b 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1060,7 +1060,7 @@ static const struct test_image_load_info { 8, 8, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0 } - }, .todo_resource_desc = TRUE, + } }, };
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index aa056fd40c2..10c939f5e4f 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -660,8 +660,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO FIXME("load_info->CpuAccessFlags is ignored.\n"); if (load_info->MiscFlags != D3DX10_DEFAULT) FIXME("load_info->MiscFlags is ignored.\n"); - if (load_info->Format != D3DX10_DEFAULT) - FIXME("load_info->Format is ignored.\n"); if (load_info->Filter != D3DX10_DEFAULT) FIXME("load_info->Filter is ignored.\n"); if (load_info->MipFilter != D3DX10_DEFAULT) @@ -688,7 +686,8 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end; }
- load_info->Format = img_info.Format; + if (load_info->Format == D3DX10_DEFAULT || load_info->Format == DXGI_FORMAT_FROM_FILE) + load_info->Format = img_info.Format; fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(load_info->Format)); if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT) {
On Mon Oct 6 17:03:20 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#44511a14caf4996235e186fbf0330f9822314c33_773_773)
I've added a few more tests for this in the current revision, as well as an `assert()` to make sure it's not NULL once we start using it to determine the `D3D10_RESOURCE_DIMENSION` for the created texture.
On Mon Oct 6 17:03:19 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#7af4349b75c315543424998c70f7c31a2fc44f6a_4349_4296)
Yes, sorry about that. :/ Normally I'm much more careful not to push rushed patches out. I don't know how I ended up with tests in two separate patches, my theory is I initially wanted to exclude the commit `d3dx10/tests: Add tests for the D3DX10_IMAGE_LOAD_INFO structure argument.`, but then added it in and ended up with redundant tests.
I've generally cleaned up the tests and gotten rid of redundant ones. Hopefully it's better now.
On Mon Oct 6 17:03:19 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#7af4349b75c315543424998c70f7c31a2fc44f6a_3091_3005)
Should be clearer in the current revision. Agreed, that wording wasn't great. :)
On Mon Oct 6 17:03:18 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#7af4349b75c315543424998c70f7c31a2fc44f6a_1835_1790)
I've split this into two separate functions now: `check_texture2d_desc()` which takes two `D3D10_TEXTURE2D_DESC` structures, and then a `check_texture2d_desc_values()` function that packs the arguments into a `D3D10_TEXTURE2D_DESC` before passing them to `check_texture2d_desc()`. Hopefully that's better.
On Mon Oct 6 17:03:19 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#7af4349b75c315543424998c70f7c31a2fc44f6a_2172_2121)
I've gotten rid of the `color` usage across the readback tests, hopefully it's better now.
On Mon Oct 6 17:03:19 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9089/diffs?diff_id=214564&start_sha=3994a075cd9dfab92fcc7c6af29fc1a6a357a251#7af4349b75c315543424998c70f7c31a2fc44f6a_4341_4286)
This test was definitely a bit of a mess. It also didn't help that I had a separate `FirstMipLevel` test in `test_image_load_info` that didn't check the texture data. I've removed the unnecessary test from `test_image_load_info` and added more comments/clarity in this test now, hopefully it's improved.
On Mon Oct 6 17:14:20 2025 +0000, Matteo Bruni wrote:
Left a bunch of minor comments, looks generally good.
Thanks for reviewing, sorry for the messy tests! I've added more tests and removed some of the others in the current revision. It should hopefully be cleaner now...
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
BOOL line_match; HRESULT hr;
- readback = get_texture2d_readback(texture);
- readback = get_texture2d_readback_iface(texture);
Instead of introducing another, separate texture readback and check mechanism, maybe it makes sense to get rid of the old functions and make `check_resource_data()` (or `check_texture2d_data()` + `check_texture3d_data()`) use the new `resource_readback` machinery. Probably as its own patch at the start of the MR, no new tests, just plugging in `resource_readback` in place of the existing (`_iface`) stuff.
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:ID3D10Texture2D_Unmap((ID3D10Texture2D *)rb->resource, rb->sub_resource_idx);break;case D3D10_RESOURCE_DIMENSION_TEXTURE3D:ID3D10Texture3D_Unmap((ID3D10Texture3D *)rb->resource, rb->sub_resource_idx);break;default:trace("Unhandled resource dimension %#x.\n", rb->dimension);break;- }
- ID3D10Resource_Release(rb->resource);
+}
+#define check_readback_data_u32(a, b, c) check_readback_data_u32_(__LINE__, a, b, c) +static void check_readback_data_u32_(unsigned int line, struct resource_readback *rb,
const RECT *rect, uint32_t expected)
(After noticing that this dropped the `max_diff` parameter compared to the previous revision) just curious, I guess we won't need tolerance on the check even in other tests you have sitting around?
On Wed Oct 8 11:33:36 2025 +0000, Connor McAdams wrote:
Thanks for reviewing, sorry for the messy tests! I've added more tests and removed some of the others in the current revision. It should hopefully be cleaner now...
No worries! But I've brought up another potential test cleanup, more deduplication :slight_smile:
On Wed Oct 8 12:00:53 2025 +0000, Matteo Bruni wrote:
(After noticing that this dropped the `max_diff` parameter compared to the previous revision) just curious, I guess we won't need tolerance on the check even in other tests you have sitting around?
After noticing all my patches in this revision were passing `0` as the `max_diff` argument, I went and checked if any of the later ones were passing anything other than 0 and they weren't. It might be necessary to bring this back when implementing filters or for different formats, but I felt like it made sense to avoid adding it until something actually used it. :)