[PATCH 0/5] MR9089: d3dx10: Add partial support for D3DX10_IMAGE_LOAD_INFO structure fields.
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. :) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
From: Connor McAdams <cmcadams(a)codeweavers.com> Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 826 +++++++++++++++++++++++++++++++++- 1 file changed, 821 insertions(+), 5 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 3ec21ccc7bf..af080f8ff7e 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -732,6 +732,111 @@ static const BYTE test_dds_volume_data[] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x87, 0x0f, 0x78, 0x05, 0x05, 0x50, 0x50, }; +/* + * 4x4x4 24-bit volume dds, 3 mipmaps. Level 0 is red, level 1 is green, level 2 is + * blue. + */ +static const uint8_t dds_volume_24bit_4_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x82,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x03,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,0x20,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,0xff,0x00,0x00 +}; + +/* + * 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 +1027,187 @@ 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; + D3DX10_IMAGE_INFO expected_info; + BOOL todo_resource_desc; +} test_image_load_info[] = +{ + /* + * FirstMipLevel set to 1 - Does not match D3DX_SKIP_DDS_MIP_LEVELS + * behavior from d3dx9, image info values represent mip level 0, and + * texture values are pulled from this. The texture data is loaded + * starting from the specified first mip level, however. + */ + { + dds_volume_24bit_4_4_4, sizeof(dds_volume_24bit_4_4_4), + { + D3DX10_FROM_FILE, D3DX10_DEFAULT, 0, 1, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT + }, + S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE3D, + { + .desc_3d = { 4, 4, 4, 3, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0 } + }, + { 4, 4, 4, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, D3DX10_IFF_DDS }, + }, + /* + * 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) + } + }, + { + 4, 4, 1, 6, 2, DDS_RESOURCE_MISC_TEXTURECUBE, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, + D3DX10_IFF_DDS + }, .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 + } + }, + { + 4, 4, 1, 1, 1, 0, DXGI_FORMAT_BC1_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS + }, .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 +1659,99 @@ 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_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 }; + BOOL matched; + + matched = !memcmp(&expected_desc, 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 != width) + ok_(__FILE__, line)(desc->Width == width, "Expected width %u, got %u.\n", width, desc->Width); + todo_wine_if(wine_todo && desc->Height != height) + ok_(__FILE__, line)(desc->Height == height, "Expected height %u, got %u.\n", height, desc->Height); + todo_wine_if(wine_todo && desc->ArraySize != array_size) + ok_(__FILE__, line)(desc->ArraySize == array_size, "Expected array_size %u, got %u.\n", array_size, + desc->ArraySize); + todo_wine_if(wine_todo && desc->MipLevels != mip_levels) + ok_(__FILE__, line)(desc->MipLevels == mip_levels, "Expected mip_levels %u, got %u.\n", mip_levels, + desc->MipLevels); + todo_wine_if(wine_todo && desc->Format != format) + ok_(__FILE__, line)(desc->Format == format, "Expected texture format %#x, got %#x.\n", format, desc->Format); + todo_wine_if(wine_todo && desc->SampleDesc.Count != sample_count) + ok_(__FILE__, line)(desc->SampleDesc.Count == sample_count, "Expected sample_count %u, got %u.\n", sample_count, + desc->SampleDesc.Count); + todo_wine_if(wine_todo && desc->SampleDesc.Quality != sample_quality) + ok_(__FILE__, line)(desc->SampleDesc.Quality == sample_quality, "Expected sample_quality %u, got %u.\n", sample_quality, + desc->SampleDesc.Quality); + todo_wine_if(wine_todo && desc->Usage != usage) + ok_(__FILE__, line)(desc->Usage == usage, "Expected usage %u, got %u.\n", usage, + desc->Usage); + todo_wine_if(wine_todo && desc->BindFlags != bind_flags) + ok_(__FILE__, line)(desc->BindFlags == bind_flags, "Expected bind_flags %#x, got %#x.\n", bind_flags, + desc->BindFlags); + todo_wine_if(wine_todo && desc->CPUAccessFlags != cpu_access_flags) + ok_(__FILE__, line)(desc->CPUAccessFlags == cpu_access_flags, "Expected cpu_access_flags %#x, got %#x.\n", + cpu_access_flags, desc->CPUAccessFlags); + todo_wine_if(wine_todo && desc->MiscFlags != misc_flags) + ok_(__FILE__, line)(desc->MiscFlags == misc_flags, "Expected misc_flags %#x, got %#x.\n", misc_flags, + desc->MiscFlags); +} + +#define check_texture3d_desc_values(desc, width, height, depth, mip_levels, format, usage, bind_flags, cpu_access_flags, \ + misc_flags, wine_todo) \ + check_texture3d_desc_values_(__LINE__, desc, width, height, depth, mip_levels, format, usage, bind_flags, \ + cpu_access_flags, misc_flags, wine_todo) +static inline void check_texture3d_desc_values_(uint32_t line, const D3D10_TEXTURE3D_DESC *desc, uint32_t width, + uint32_t height, uint32_t depth, uint32_t mip_levels, DXGI_FORMAT format, D3D10_USAGE usage, uint32_t bind_flags, + uint32_t cpu_access_flags, uint32_t misc_flags, BOOL wine_todo) +{ + const D3D10_TEXTURE3D_DESC expected_desc = { width, height, depth, mip_levels, format, usage, bind_flags, + cpu_access_flags, misc_flags }; + BOOL matched; + + matched = !memcmp(&expected_desc, 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 != width) + ok_(__FILE__, line)(desc->Width == width, "Expected width %u, got %u.\n", width, desc->Width); + todo_wine_if(wine_todo && desc->Height != height) + ok_(__FILE__, line)(desc->Height == height, "Expected height %u, got %u.\n", height, desc->Height); + todo_wine_if(wine_todo && desc->Depth != depth) + ok_(__FILE__, line)(desc->Depth == depth, "Expected depth %u, got %u.\n", depth, desc->Depth); + todo_wine_if(wine_todo && desc->MipLevels != mip_levels) + ok_(__FILE__, line)(desc->MipLevels == mip_levels, "Expected mip_levels %u, got %u.\n", mip_levels, + desc->MipLevels); + todo_wine_if(wine_todo && desc->Format != format) + ok_(__FILE__, line)(desc->Format == format, "Expected texture format %#x, got %#x.\n", format, desc->Format); + todo_wine_if(wine_todo && desc->Usage != usage) + ok_(__FILE__, line)(desc->Usage == usage, "Expected usage %u, got %u.\n", usage, + desc->Usage); + todo_wine_if(wine_todo && desc->BindFlags != bind_flags) + ok_(__FILE__, line)(desc->BindFlags == bind_flags, "Expected bind_flags %#x, got %#x.\n", bind_flags, + desc->BindFlags); + todo_wine_if(wine_todo && desc->CPUAccessFlags != cpu_access_flags) + ok_(__FILE__, line)(desc->CPUAccessFlags == cpu_access_flags, "Expected cpu_access_flags %#x, got %#x.\n", + cpu_access_flags, desc->CPUAccessFlags); + todo_wine_if(wine_todo && desc->MiscFlags != misc_flags) + ok_(__FILE__, line)(desc->MiscFlags == misc_flags, "Expected misc_flags %#x, got %#x.\n", misc_flags, + desc->MiscFlags); +} + +static ID3D10Texture2D *get_texture2d_readback_iface(ID3D10Texture2D *texture) { D3D10_TEXTURE2D_DESC desc; ID3D10Texture2D *readback; @@ -1399,7 +1777,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 +1803,64 @@ 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_values_(line, &desc_2d, expected_desc_2d->Width, expected_desc_2d->Height, + expected_desc_2d->MipLevels, expected_desc_2d->ArraySize, expected_desc_2d->Format, + expected_desc_2d->SampleDesc.Count, expected_desc_2d->SampleDesc.Quality, expected_desc_2d->Usage, + expected_desc_2d->BindFlags, expected_desc_2d->CPUAccessFlags, expected_desc_2d->MiscFlags, + 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_values_(line, &desc_3d, expected_desc_3d->Width, expected_desc_3d->Height, + expected_desc_3d->Depth, expected_desc_3d->MipLevels, expected_desc_3d->Format, expected_desc_3d->Usage, + expected_desc_3d->BindFlags, expected_desc_3d->CPUAccessFlags, expected_desc_3d->MiscFlags, + 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 +1985,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 +2039,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 +2097,172 @@ 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 uint32_t get_readback_color(struct resource_readback *rb, uint32_t x, uint32_t y) +{ + return get_readback_u32(rb, x, y); +} + +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); +} + +static BOOL compare_color(uint32_t c1, uint32_t c2, uint8_t max_diff) +{ + return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) + && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff) + && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff) + && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); +} + +#define check_readback_data_color(a, b, c, d) check_readback_data_color_(__LINE__, a, b, c, d) +static void check_readback_data_color_(uint32_t line, struct resource_readback *rb, + const RECT *rect, uint32_t expected_color, uint8_t max_diff) +{ + unsigned int x = 0, y = 0, color = 0; + BOOL all_match = FALSE; + RECT default_rect; + + 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) + { + color = get_readback_color(rb, x, y); + if (!compare_color(color, expected_color, max_diff)) + goto done; + } + } + all_match = TRUE; + +done: + ok_(__FILE__, line)(all_match, + "Got 0x%08x, expected 0x%08x at (%u, %u), sub-resource %u.\n", + color, expected_color, x, y, rb->sub_resource_idx); +} + +#define check_texture_sub_resource_color(a, b, c, d, e) check_texture_sub_resource_color_(__LINE__, a, b, c, d, e) +static void check_texture_sub_resource_color_(uint32_t line, ID3D10Texture2D *texture, + uint32_t sub_resource_idx, const RECT *rect, uint32_t expected_color, uint8_t max_diff) +{ + struct resource_readback rb; + + get_texture_readback(texture, sub_resource_idx, &rb); + check_readback_data_color_(line, &rb, rect, expected_color, max_diff); + release_resource_readback(&rb); +} + +static void set_d3dx10_image_load_info(D3DX10_IMAGE_LOAD_INFO *info, uint32_t width, uint32_t height, uint32_t depth, + uint32_t first_mip_level, uint32_t mip_levels, D3D10_USAGE usage, uint32_t bind_flags, uint32_t cpu_access_flags, + uint32_t misc_flags, DXGI_FORMAT format, uint32_t filter, uint32_t mip_filter, D3DX10_IMAGE_INFO *src_info) +{ + info->Width = width; + info->Height = height; + info->Depth = depth; + info->FirstMipLevel = first_mip_level; + info->MipLevels = mip_levels; + info->Usage = usage; + info->BindFlags = bind_flags; + info->CpuAccessFlags = cpu_access_flags; + info->MiscFlags = misc_flags; + info->Format = format; + info->Filter = filter; + info->MipFilter = mip_filter; + info->pSrcInfo = src_info; +} + static void test_D3DX10UnsetAllDeviceObjects(void) { static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = @@ -2480,6 +3082,35 @@ static void test_D3DX10CreateAsyncTextureProcessor(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]; + 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(); + } + CoUninitialize(); ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); @@ -3520,14 +4151,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; ID3D10Resource *resource; + ID3D10Texture2D *tex_2d; HMODULE resource_module; ID3D10Device *device; WCHAR path[MAX_PATH]; + uint32_t i, mip_level; HRESULT hr, hr2; - unsigned int i; device = create_device(); if (!device) @@ -3594,6 +4230,133 @@ 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); + + 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]; + + if ((test->load_info.FirstMipLevel && test->load_info.FirstMipLevel != D3DX10_DEFAULT) + && D3DX10_SDK_VERSION == 33) + { + skip("FirstMipLevel argument is broken in version 33.\n"); + continue; + } + + winetest_push_context("Test %u", i); + + load_info = test->load_info; + load_info.pSrcInfo = &img_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(); + } + + /* Check behavior of the FirstMipLevel argument. */ + 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)); + set_d3dx10_image_load_info(&load_info, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, i, D3DX10_FROM_FILE, + D3D10_USAGE_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, + D3DX10_DEFAULT, &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, FALSE); + } + + 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); + todo_wine_if(i && mip_level != 3) check_texture_sub_resource_color(tex_2d, mip_level, NULL, + dds_24bit_8_8_mip_level_expected[min(3, mip_level + i)], 0); + 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)); + set_d3dx10_image_load_info(&load_info, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 5, D3DX10_FROM_FILE, + D3D10_USAGE_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, + D3DX10_DEFAULT, &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, FALSE); + } + + 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_color(tex_2d, mip_level, NULL, dds_24bit_8_8_mip_level_expected[mip_level], 0); + 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 +4420,31 @@ 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_image[i].data, test_image[i].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(); + } + /* D3DX10CreateTextureFromResource tests */ hr2 = 0xdeadbeef; @@ -3716,6 +4504,34 @@ 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(); + } + CoUninitialize(); ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
From: Connor McAdams <cmcadams(a)codeweavers.com> Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 130 +++++++++++++++++++++++++++++++--- dlls/d3dx10_43/texture.c | 4 +- 2 files changed, 122 insertions(+), 12 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index af080f8ff7e..45220a51f27 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3025,6 +3025,12 @@ static void test_D3DX10CreateAsyncTextureInfoProcessor(void) CoUninitialize(); } +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 +}; + static void test_D3DX10CreateAsyncTextureProcessor(void) { ID3DX10DataProcessor *dp; @@ -3059,6 +3065,9 @@ static void test_D3DX10CreateAsyncTextureProcessor(void) for (i = 0; i < ARRAY_SIZE(test_image); ++i) { + D3DX10_IMAGE_LOAD_INFO load_info = d3dx10_default_load_info; + D3DX10_IMAGE_INFO info = { 0 }; + winetest_push_context("Test %u", i); hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &dp); @@ -3079,6 +3088,27 @@ static void test_D3DX10CreateAsyncTextureProcessor(void) hr = ID3DX10DataProcessor_Destroy(dp); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + /* Check that D3DX10_IMAGE_INFO argument is set. */ + 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) + { + 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__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + winetest_pop_context(); } @@ -4213,6 +4243,8 @@ static void test_create_texture(void) for (i = 0; i < ARRAY_SIZE(test_image); ++i) { + D3DX10_IMAGE_INFO info = { 0 }; + winetest_push_context("Test %u", i); hr2 = 0xdeadbeef; @@ -4227,6 +4259,22 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); } + /* Check that D3DX10_IMAGE_INFO argument is set. */ + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &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__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + winetest_pop_context(); } @@ -4297,11 +4345,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, FALSE); - } + 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); @@ -4336,11 +4381,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, FALSE); - } + 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); @@ -4389,6 +4431,8 @@ static void test_create_texture(void) for (i = 0; i < ARRAY_SIZE(test_image); ++i) { + D3DX10_IMAGE_INFO info = { 0 }; + winetest_push_context("Test %u", i); create_file(test_filename, test_image[i].data, test_image[i].size, path); @@ -4416,6 +4460,37 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); } + /* Check that D3DX10_IMAGE_INFO argument is set. */ + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &info; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, path, &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__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &info; + 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 == 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__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + delete_file(test_filename); winetest_pop_context(); } @@ -4466,6 +4541,8 @@ static void test_create_texture(void) for (i = 0; i < ARRAY_SIZE(test_image); ++i) { + D3DX10_IMAGE_INFO info = { 0 }; + winetest_push_context("Test %u", i); resource_module = create_resource_module(test_resource_name, test_image[i].data, test_image[i].size); @@ -4500,6 +4577,39 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); } + /* Check that D3DX10_IMAGE_INFO argument is set. */ + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &info; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, resource_module, + test_resource_name, &load_info, NULL, &resource, &hr2); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + if (hr == S_OK) + { + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + load_info = d3dx10_default_load_info; + load_info.pSrcInfo = &info; + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceA(device, resource_module, + get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2); + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#lx.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); + if (hr == S_OK) + { + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + check_image_info(&info, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + delete_resource_module(test_resource_name, resource_module); winetest_pop_context(); } 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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
From: Connor McAdams <cmcadams(a)codeweavers.com> Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com> --- dlls/d3dx10_43/async.c | 11 +++++- dlls/d3dx10_43/tests/d3dx10.c | 35 +++++++++++------- dlls/d3dx10_43/texture.c | 67 ++++++++++++++++++++++++++--------- 3 files changed, 84 insertions(+), 29 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 45220a51f27..0e200f64f36 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> @@ -69,6 +70,8 @@ #define DDS_PF_BUMPLUMINANCE 0x00040000 #define DDS_PF_BUMPDUDV 0x00080000 +static bool wined3d_opengl; + struct dds_pixel_format { DWORD size; @@ -1812,13 +1815,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: @@ -1887,10 +1885,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) { @@ -2083,7 +2080,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))) @@ -6107,6 +6107,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..4e048726310 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -440,9 +440,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; @@ -776,25 +779,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; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
From: Connor McAdams <cmcadams(a)codeweavers.com> Signed-off-by: Connor McAdams <cmcadams(a)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 0e200f64f36..49fbbcc335d 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1137,7 +1137,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 4e048726310..196da13e140 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -647,12 +647,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) @@ -703,9 +697,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)) + { + ERR("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, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
From: Connor McAdams <cmcadams(a)codeweavers.com> Signed-off-by: Connor McAdams <cmcadams(a)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 49fbbcc335d..2a0a81d2318 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1110,7 +1110,7 @@ static const struct test_image_load_info }, { 4, 4, 1, 1, 1, 0, DXGI_FORMAT_BC1_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS - }, .todo_resource_desc = TRUE, + } }, }; diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 196da13e140..419229978fc 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -659,8 +659,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) @@ -687,7 +685,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) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9089
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
+} + +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 uint32_t get_readback_color(struct resource_readback *rb, uint32_t x, uint32_t y) +{ + return get_readback_u32(rb, x, y); +} I think this function is mostly a historical artifact of the d3d10core tests: they originally supported readback only from 8 bpc UNORM texture formats (see e.g. 86aaebc48aa1). We probably don't need to bring it here, likewise for the "color" wording.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117568
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
+ 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_values_(line, &desc_2d, expected_desc_2d->Width, expected_desc_2d->Height, + expected_desc_2d->MipLevels, expected_desc_2d->ArraySize, expected_desc_2d->Format, + expected_desc_2d->SampleDesc.Count, expected_desc_2d->SampleDesc.Quality, expected_desc_2d->Usage, + expected_desc_2d->BindFlags, expected_desc_2d->CPUAccessFlags, expected_desc_2d->MiscFlags, + image_load_info->todo_resource_desc); Unpacking `expected_desc_2d` in the call to `check_texture2d_desc_values_()` to pack it again immediately inside the function seems quite awkward. I'd consider just passing the expected descriptor to the test function, even if it that means adding some extra lines to pack values in an 'expected' structure when calling `check_texture2d_desc_values_()` directly.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117567
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
+ } + + /* Check behavior of the FirstMipLevel argument. */ + 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)); + set_d3dx10_image_load_info(&load_info, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, i, D3DX10_FROM_FILE, + D3D10_USAGE_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, + D3DX10_DEFAULT, &img_info); I find this a bit confusing; the general intent is clear (testing FirstMipLevel) but still it looks kinda messy. Explicitly initializing the load info structure would be a step forward I think.
It's a style matter, so certainly not a blocker or anything. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117570
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
hr = ID3DX10DataProcessor_Destroy(dp); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Check that D3DX10_IMAGE_INFO argument is set. */
Nitpick, probably "filled" would be more appropriate than "set", if the idea is to check that `info` is filled when it's passed to the function via the `pSrcInfo` pointer. It's also possible I misunderstood the test... -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117571
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
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, FALSE); - } + check_image_info_values(&img_info, 8, 8, 1, 1, 4, 0, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3DX10_IFF_DDS, FALSE);
So, this shows that the relevant behavior was already kinda covered by the tests. I'm wondering if some of the additional tests in this patch are actually redundant. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117572
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/texture.c:
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;
Do we have a test for the `load_info->pSrcInfo == NULL` case? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117573
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/texture.c:
}
/* 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)) + { + ERR("Invalid depth value %u for image with dimension %d.\n", load_info->Depth, img_info.ResourceDimension);
This should probably be a `WARN()` given that it's an application-provided value. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117574
Left a bunch of minor comments, looks generally good. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9089#note_117575
participants (3)
-
Connor McAdams -
Connor McAdams (@cmcadams) -
Matteo Bruni (@Mystral)