-- v2: d3dx10: Exclusively use shared code for parsing all files in get_image_info(). d3dx10: Add support for d3dx10+ image file formats in shared code. d3dx10: Exclusively use shared code for parsing DDS files in get_image_info(). d3dx10: Add support for DXGI formats in d3dx_helpers. d3dx10: Only validate header size for DDS files in d3dx10. d3dx10: Add support for parsing DXT10 DDS headers to shared code. d3dx10/tests: Add more DDS file header handling tests. d3dx10/tests: Add more DDS file DXGI format mapping tests.
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 138 +++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index ded2940ba46..fd8ab5c3496 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -21,6 +21,7 @@ #include "d3d10_1.h" #include "d3dx10.h" #include "wine/test.h" +#include <stdint.h>
#define D3DERR_INVALIDCALL 0x8876086c
@@ -47,6 +48,7 @@ #define DDS_PF_ALPHA 0x00000001 #define DDS_PF_ALPHA_ONLY 0x00000002 #define DDS_PF_FOURCC 0x00000004 +#define DDS_PF_INDEXED 0x00000020 #define DDS_PF_RGB 0x00000040 #define DDS_PF_LUMINANCE 0x00020000 #define DDS_PF_BUMPLUMINANCE 0x00040000 @@ -82,6 +84,15 @@ struct dds_header DWORD reserved2; };
+struct dds_header_dxt10 +{ + uint32_t dxgi_format; + uint32_t resource_dimension; + uint32_t misc_flag; + uint32_t array_size; + uint32_t misc_flags2; +}; + static void fill_dds_header(struct dds_header *header) { memset(header, 0, sizeof(*header)); @@ -102,6 +113,35 @@ static void fill_dds_header(struct dds_header *header) header->caps = DDS_CAPS_TEXTURE; }
+static void set_dxt10_dds_header(struct dds_header *header, uint32_t append_flags, uint32_t width, uint32_t height, + uint32_t depth, uint32_t mip_levels, uint32_t pitch, uint32_t caps, uint32_t caps2) +{ + memset(header, 0, sizeof(*header)); + + header->size = sizeof(*header); + header->flags = DDS_CAPS | DDS_PIXELFORMAT | append_flags; + header->height = height; + header->width = width; + header->depth = depth; + header->miplevels = mip_levels; + header->pitch_or_linear_size = pitch; + header->pixel_format.size = sizeof(header->pixel_format); + header->pixel_format.flags = DDS_PF_FOURCC; + header->pixel_format.fourcc = MAKEFOURCC('D','X','1','0'); + header->caps = caps; + header->caps2 = caps2; +} + +static void set_dds_header_dxt10(struct dds_header_dxt10 *dxt10, DXGI_FORMAT format, uint32_t resource_dimension, + uint32_t misc_flag, uint32_t array_size, uint32_t misc_flags2) +{ + dxt10->dxgi_format = format; + dxt10->resource_dimension = resource_dimension; + dxt10->misc_flag = misc_flag; + dxt10->array_size = array_size; + dxt10->misc_flags2 = misc_flags2; +} + /* 1x1 1bpp bmp image */ static const BYTE test_bmp_1bpp[] = { @@ -2759,10 +2799,8 @@ static void test_D3DX10CreateThreadPump(void) ok(!ret, "Got unexpected refcount %lu.\n", ret); }
-#define check_dds_pixel_format(flags, fourcc, bpp, rmask, gmask, bmask, amask, format) \ - check_dds_pixel_format_(__LINE__, flags, fourcc, bpp, rmask, gmask, bmask, amask, format) -static void check_dds_pixel_format_(unsigned int line, DWORD flags, DWORD fourcc, DWORD bpp, - DWORD rmask, DWORD gmask, DWORD bmask, DWORD amask, DXGI_FORMAT expected_format) +static void check_dds_pixel_format_image_info(unsigned int line, DWORD flags, DWORD fourcc, DWORD bpp, + DWORD rmask, DWORD gmask, DWORD bmask, DWORD amask, HRESULT expected_hr, DXGI_FORMAT expected_format) { D3DX10_IMAGE_INFO info; HRESULT hr; @@ -2770,6 +2808,7 @@ static void check_dds_pixel_format_(unsigned int line, DWORD flags, DWORD fourcc { DWORD magic; struct dds_header header; + PALETTEENTRY palette[256]; BYTE data[256]; } dds;
@@ -2785,14 +2824,49 @@ static void check_dds_pixel_format_(unsigned int line, DWORD flags, DWORD fourcc memset(dds.data, 0, sizeof(dds.data));
hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); - ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx for pixel format %#x.\n", hr, expected_format); - if (SUCCEEDED(hr)) + ok_(__FILE__, line)(hr == expected_hr, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr) && hr == expected_hr) + ok_(__FILE__, line)(info.Format == expected_format, "Unexpected format %#x.\n", info.Format); +} + +#define check_dds_pixel_format(flags, fourcc, bpp, rmask, gmask, bmask, amask, format) \ + check_dds_pixel_format_image_info(__LINE__, flags, fourcc, bpp, rmask, gmask, bmask, amask, S_OK, format) + +#define check_dds_pixel_format_unsupported(flags, fourcc, bpp, rmask, gmask, bmask, amask, expected_hr) \ + check_dds_pixel_format_image_info(__LINE__, flags, fourcc, bpp, rmask, gmask, bmask, amask, expected_hr, \ + DXGI_FORMAT_UNKNOWN) + +static void check_dds_dxt10_format_image_info(unsigned int line, DXGI_FORMAT format, DXGI_FORMAT expected_format, + HRESULT expected_hr, BOOL todo_format) +{ + const unsigned int stride = (4 * get_bpp_from_format(format) + 7) / 8; + D3DX10_IMAGE_INFO info; + HRESULT hr; + struct { - ok_(__FILE__, line)(info.Format == expected_format, "Unexpected format %#x, expected %#x\n", - info.Format, expected_format); - } + DWORD magic; + struct dds_header header; + struct dds_header_dxt10 dxt10; + BYTE data[256]; + } dds; + + dds.magic = MAKEFOURCC('D','D','S',' '); + set_dxt10_dds_header(&dds.header, 0, 4, 4, 1, 1, stride, 0, 0); + set_dds_header_dxt10(&dds.dxt10, format, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0); + + hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); + ok_(__FILE__, line)(hr == expected_hr, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr) && hr == expected_hr) + todo_wine_if(todo_format) ok_(__FILE__, line)(info.Format == expected_format, "Unexpected format %#x.\n", + info.Format); }
+#define check_dds_dxt10_format(format, expected_format, todo_format) \ + check_dds_dxt10_format_image_info(__LINE__, format, expected_format, S_OK, todo_format) + +#define check_dds_dxt10_format_unsupported(format, expected_hr) \ + check_dds_dxt10_format_image_info(__LINE__, format, DXGI_FORMAT_UNKNOWN, expected_hr, FALSE) + static void test_get_image_info(void) { static const WCHAR test_resource_name[] = L"resource.data"; @@ -2935,6 +3009,52 @@ static void test_get_image_info(void) check_dds_pixel_format(DDS_PF_LUMINANCE, 0, 16, 0xffff, 0, 0, 0, DXGI_FORMAT_R16G16B16A16_UNORM); check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 16, 0x00ff, 0, 0, 0xff00, DXGI_FORMAT_R8G8B8A8_UNORM); check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 8, 0x0f, 0, 0, 0xf0, DXGI_FORMAT_R8G8B8A8_UNORM); + check_dds_pixel_format(DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + check_dds_pixel_format(DDS_PF_INDEXED | DDS_PF_ALPHA, 0, 16, 0, 0, 0, 0xff00, DXGI_FORMAT_R8G8B8A8_UNORM); + check_dds_pixel_format(DDS_PF_FOURCC, 0x24, 0, 0, 0, 0, 0, DXGI_FORMAT_R16G16B16A16_UNORM); /* D3DFMT_A16B16G16R16 */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x6e, 0, 0, 0, 0, 0, DXGI_FORMAT_R16G16B16A16_SNORM); /* D3DFMT_Q16W16V16U16 */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x6f, 0, 0, 0, 0, 0, DXGI_FORMAT_R16_FLOAT); /* D3DFMT_R16F */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x70, 0, 0, 0, 0, 0, DXGI_FORMAT_R16G16_FLOAT); /* D3DFMT_G16R16F */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x71, 0, 0, 0, 0, 0, DXGI_FORMAT_R16G16B16A16_FLOAT); /* D3DFMT_A16B16G16R16F */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x72, 0, 0, 0, 0, 0, DXGI_FORMAT_R32_FLOAT); /* D3DFMT_R32F */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x73, 0, 0, 0, 0, 0, DXGI_FORMAT_R32G32_FLOAT); /* D3DFMT_G32R32F */ + check_dds_pixel_format(DDS_PF_FOURCC, 0x74, 0, 0, 0, 0, 0, DXGI_FORMAT_R32G32B32A32_FLOAT); /* D3DFMT_A32B32G32R32F */ + + /* Test for DDS pixel formats that are valid on d3dx9, but not d3dx10. */ + todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0, E_FAIL); + todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0, E_FAIL); + /* Bumpmap formats aren't supported. */ + todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, E_FAIL); + todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, E_FAIL); + todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0xff, 0xff00, 0x00ff0000, 0xff000000, E_FAIL); + todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPLUMINANCE, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0, E_FAIL); + + /* Newer fourCC formats. */ + check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC4_UNORM); + check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','5','U'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC5_UNORM); + check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC4_SNORM); + check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC5_SNORM); + /* ATI1 is unsupported, but ATI2 is supported. */ + todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('A','T','I','1'), 0, 0, 0, 0, 0, E_FAIL); + check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('A','T','I','2'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC5_UNORM); + + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G6R5_UNORM, E_FAIL); + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G5R5A1_UNORM, E_FAIL); + /* Formats that are newer than d3d10. */ + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_UF16, E_FAIL); + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_SF16, E_FAIL); + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC7_UNORM, E_FAIL); + todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B4G4R4A4_UNORM, E_FAIL); + + /* + * These formats should map 1:1 from the DXT10 header, unlike legacy DDS + * file equivalents. + */ + check_dds_dxt10_format(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, TRUE);
/* D3DX10GetImageInfoFromResource tests */
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 367 ++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index fd8ab5c3496..4bc15a78258 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -39,11 +39,26 @@ #define DDS_PIXELFORMAT 0x00001000 #define DDS_MIPMAPCOUNT 0x00020000 #define DDS_LINEARSIZE 0x00080000 +#define DDS_DEPTH 0x00800000
/* dds_header.caps */ #define DDSCAPS_ALPHA 0x00000002 +#define DDS_CAPS_COMPLEX 0x00000008 #define DDS_CAPS_TEXTURE 0x00001000
+/* dds_header.caps2 */ +#define DDS_CAPS2_VOLUME 0x00200000 +#define DDS_CAPS2_CUBEMAP 0x00000200 +#define DDS_CAPS2_CUBEMAP_POSITIVEX 0x00000400 +#define DDS_CAPS2_CUBEMAP_NEGATIVEX 0x00000800 +#define DDS_CAPS2_CUBEMAP_POSITIVEY 0x00001000 +#define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x00002000 +#define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x00004000 +#define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x00008000 +#define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \ + | DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \ + | DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ ) + /* dds_pixel_format.flags */ #define DDS_PF_ALPHA 0x00000001 #define DDS_PF_ALPHA_ONLY 0x00000002 @@ -84,6 +99,7 @@ struct dds_header DWORD reserved2; };
+#define DDS_RESOURCE_MISC_TEXTURECUBE 0x04 struct dds_header_dxt10 { uint32_t dxgi_format; @@ -1316,6 +1332,47 @@ static void check_image_info(D3DX10_IMAGE_INFO *image_info, const struct test_im image_info->ImageFileFormat, image->expected_info.ImageFileFormat); }
+#define check_image_info_values(info, width, height, depth, array_size, mip_levels, misc_flags, format, resource_dimension, \ + image_file_format, wine_todo) \ + check_image_info_values_(__LINE__, info, width, height, depth, array_size, mip_levels, misc_flags, format, resource_dimension, \ + image_file_format, wine_todo) +static inline void check_image_info_values_(uint32_t line, const D3DX10_IMAGE_INFO *info, uint32_t width, + uint32_t height, uint32_t depth, uint32_t array_size, uint32_t mip_levels, uint32_t misc_flags, + DXGI_FORMAT format, D3D10_RESOURCE_DIMENSION resource_dimension, D3DX10_IMAGE_FILE_FORMAT image_file_format, + BOOL wine_todo) +{ + const D3DX10_IMAGE_INFO expected_info = { width, height, depth, array_size, mip_levels, misc_flags, format, + resource_dimension, image_file_format }; + BOOL matched; + + matched = !memcmp(&expected_info, info, sizeof(*info)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected image info values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && info->Width != width) + ok_(__FILE__, line)(info->Width == width, "Expected width %u, got %u.\n", width, info->Width); + todo_wine_if(wine_todo && info->Height != height) + ok_(__FILE__, line)(info->Height == height, "Expected height %u, got %u.\n", height, info->Height); + todo_wine_if(wine_todo && info->Depth != depth) + ok_(__FILE__, line)(info->Depth == depth, "Expected depth %u, got %u.\n", depth, info->Depth); + todo_wine_if(wine_todo && info->ArraySize != array_size) + ok_(__FILE__, line)(info->ArraySize == array_size, "Expected array_size %u, got %u.\n", array_size, + info->ArraySize); + todo_wine_if(wine_todo && info->MipLevels != mip_levels) + ok_(__FILE__, line)(info->MipLevels == mip_levels, "Expected mip_levels %u, got %u.\n", mip_levels, + info->MipLevels); + todo_wine_if(wine_todo && info->MiscFlags != misc_flags) + ok_(__FILE__, line)(info->MiscFlags == misc_flags, "Expected misc_flags %u, got %u.\n", misc_flags, + info->MiscFlags); + ok_(__FILE__, line)(info->Format == format, "Expected texture format %d, got %d.\n", format, info->Format); + todo_wine_if(wine_todo && info->ResourceDimension != resource_dimension) + ok_(__FILE__, line)(info->ResourceDimension == resource_dimension, "Expected resource_dimension %d, got %d.\n", + resource_dimension, info->ResourceDimension); + ok_(__FILE__, line)(info->ImageFileFormat == image_file_format, "Expected image_file_format %d, got %d.\n", + image_file_format, info->ImageFileFormat); +} + static ID3D10Texture2D *get_texture2d_readback(ID3D10Texture2D *texture) { D3D10_TEXTURE2D_DESC desc; @@ -2867,6 +2924,314 @@ static void check_dds_dxt10_format_image_info(unsigned int line, DXGI_FORMAT for #define check_dds_dxt10_format_unsupported(format, expected_hr) \ check_dds_dxt10_format_image_info(__LINE__, format, DXGI_FORMAT_UNKNOWN, expected_hr, FALSE)
+static void test_legacy_dds_header_image_info(void) +{ + struct expected + { + HRESULT hr; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t array_size; + uint32_t mip_levels; + uint32_t misc_flags; + DXGI_FORMAT format; + D3D10_RESOURCE_DIMENSION resource_dimension; + }; + static const struct + { + uint32_t flags; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t row_pitch; + uint32_t mip_levels; + uint32_t caps; + uint32_t caps2; + uint32_t pixel_data_size; + struct expected expected; + BOOL todo_hr; + } tests[] = + { + /* + * Only DDS header size is validated on d3dx10, unlike d3dx9 where image pixel size + * is as well. + */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 3, 0, 0, 0, + { S_OK, 4, 4, 1, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, }, + .todo_hr = TRUE + }, + /* Depth value set to 4, but no caps bits are set. Depth is ignored. */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, 0, 0, 292, + { S_OK, 4, 4, 1, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, }, + }, + /* The volume texture caps2 field is ignored. */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, + (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), DDS_CAPS2_VOLUME, 292, + { S_OK, 4, 4, 1, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, } + }, + /* + * The DDS_DEPTH flag is the only thing checked to determine if a DDS + * file represents a 3D texture. + */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, 0, 0, 292, + { S_OK, 4, 4, 4, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, } + }, + /* Even if the depth field is set to 0, it's still a 3D texture. */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 0, (4 * 4), 3, 0, 0, 292, + { S_OK, 4, 4, 1, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, } + }, + /* + * 5. + * The DDS_DEPTH flag overrides cubemap caps. + */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, + (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), 292, + { S_OK, 4, 4, 4, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, } + }, + /* Cubemap where width field does not equal height. */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 5, 1, (4 * 4), 1, + (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), (80 * 6), + { + S_OK, 4, 5, 1, 6, 1, D3D10_RESOURCE_MISC_TEXTURECUBE, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + } + }, + /* Partial cubemaps are not supported. */ + { + (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 1, + (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_POSITIVEX), (64 * 6), + { E_FAIL, }, .todo_hr = TRUE + }, + }; + D3DX10_IMAGE_INFO info; + unsigned int i; + struct + { + DWORD magic; + struct dds_header header; + } dds; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + const uint32_t file_size = sizeof(dds) + tests[i].pixel_data_size; + + winetest_push_context("Test %u", i); + + dds.magic = MAKEFOURCC('D','D','S',' '); + fill_dds_header(&dds.header); + dds.header.flags = tests[i].flags; + dds.header.width = tests[i].width; + dds.header.height = tests[i].height; + dds.header.depth = tests[i].depth; + dds.header.pitch_or_linear_size = tests[i].row_pitch; + dds.header.miplevels = tests[i].mip_levels; + dds.header.caps = tests[i].caps; + dds.header.caps2 = tests[i].caps2; + + memset(&info, 0, sizeof(info)); + hr = D3DX10GetImageInfoFromMemory(&dds, file_size, NULL, &info, NULL); + todo_wine_if(tests[i].todo_hr) ok(hr == tests[i].expected.hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr) && SUCCEEDED(tests[i].expected.hr)) + check_image_info_values(&info, tests[i].expected.width, tests[i].expected.height, + tests[i].expected.depth, tests[i].expected.array_size, tests[i].expected.mip_levels, + tests[i].expected.misc_flags, tests[i].expected.format, + tests[i].expected.resource_dimension, D3DX10_IFF_DDS, FALSE); + + winetest_pop_context(); + } + + /* + * Image size (e.g, the size of the pixels) isn't validated, but header + * size is. + */ + dds.magic = MAKEFOURCC('D','D','S',' '); + fill_dds_header(&dds.header); + + hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds) - 1, NULL, &info, NULL); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + + hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + +static void test_dxt10_dds_header_image_info(void) +{ + struct expected + { + HRESULT hr; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t array_size; + uint32_t mip_levels; + uint32_t misc_flags; + DXGI_FORMAT format; + D3D10_RESOURCE_DIMENSION resource_dimension; + }; + static const struct + { + uint32_t append_flags; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t row_pitch; + uint32_t mip_levels; + uint32_t caps; + uint32_t caps2; + struct dds_header_dxt10 dxt10; + uint32_t pixel_data_size; + struct expected expected; + BOOL todo_hr; + BOOL todo_info; + } tests[] = + { + /* File size validation isn't done on d3dx10. */ + { + 0, 4, 4, 0, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0, }, 0, + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, }, + .todo_hr = TRUE + }, + /* + * Setting the misc_flags2 field to anything other than 0 results in + * E_FAIL. + */ + { + 0, 4, 4, 0, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 1, }, (4 * 4 * 4), + { E_FAIL }, .todo_hr = TRUE + }, + /* + * The misc_flags field isn't passed through directly, only the + * cube texture flag is (if it's set). + */ + { + 0, 4, 4, 0, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0xfffffffb, 1, 0, }, (4 * 4 * 4), + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, } + }, + /* Resource dimension field of the header isn't validated. */ + { + 0, 4, 4, 0, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, 500, 0, 1, 0, }, (4 * 4 * 4), + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, 500, }, .todo_info = TRUE + }, + /* Depth value of 2, but D3D10_RESOURCE_DIMENSION_TEXTURE2D. */ + { + DDS_DEPTH, 4, 4, 2, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0, }, (4 * 4 * 4 * 2), + { S_OK, 4, 4, 2, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, } + }, + /* + * 5. + * Depth field value is ignored if DDS_DEPTH isn't set. + */ + { + 0, 4, 4, 2, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, 0, 1, 0, }, (4 * 4 * 4 * 2), + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, }, + .todo_info = TRUE + }, + /* + * 3D texture with an array size larger than 1. Technically there's no + * such thing as a 3D texture array, but it succeeds. + */ + { + DDS_DEPTH, 4, 4, 2, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, 0, 2, 0, }, (4 * 4 * 4 * 2 * 2), + { S_OK, 4, 4, 2, 2, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, } + }, + /* Cubemap caps are ignored for DXT10 files. */ + { + 0, 4, 4, 1, (4 * 4), 1, 0, DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0, }, (4 * 4 * 4 * 6), + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D } + }, + /* Array size value is multiplied by 6 for cubemap files. */ + { + 0, 4, 4, 1, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, DDS_RESOURCE_MISC_TEXTURECUBE, 2, 0, }, + (4 * 4 * 4 * 12), + { + S_OK, 4, 4, 1, 12, 1, D3D10_RESOURCE_MISC_TEXTURECUBE, DXGI_FORMAT_R8G8B8A8_UNORM, + D3D10_RESOURCE_DIMENSION_TEXTURE2D + } + }, + /* Resource dimension is validated for cube textures. */ + { + 0, 4, 4, 1, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, DDS_RESOURCE_MISC_TEXTURECUBE, 2, 0, }, + (4 * 4 * 4 * 12), { E_FAIL }, .todo_hr = TRUE + }, + /* + * 10. + * 1D Texture cube, invalid. + */ + { + 0, 4, 4, 1, (4 * 4), 1, 0, 0, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE1D, DDS_RESOURCE_MISC_TEXTURECUBE, 2, 0, }, + (4 * 4 * 4 * 12), { E_FAIL }, .todo_hr = TRUE + }, + }; + D3DX10_IMAGE_INFO info; + unsigned int i; + struct + { + DWORD magic; + struct dds_header header; + struct dds_header_dxt10 dxt10; + } dds; + HRESULT hr; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + const uint32_t file_size = sizeof(dds) + tests[i].pixel_data_size; + + winetest_push_context("Test %u", i); + + dds.magic = MAKEFOURCC('D','D','S',' '); + set_dxt10_dds_header(&dds.header, tests[i].append_flags, tests[i].width, tests[i].height, + tests[i].depth, tests[i].mip_levels, tests[i].row_pitch, tests[i].caps, + tests[i].caps2); + dds.dxt10 = tests[i].dxt10; + + memset(&info, 0, sizeof(info)); + hr = D3DX10GetImageInfoFromMemory(&dds, file_size, NULL, &info, NULL); + todo_wine_if(tests[i].todo_hr) ok(hr == tests[i].expected.hr, "Got unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr) && SUCCEEDED(tests[i].expected.hr)) + check_image_info_values(&info, tests[i].expected.width, tests[i].expected.height, + tests[i].expected.depth, tests[i].expected.array_size, tests[i].expected.mip_levels, + tests[i].expected.misc_flags, tests[i].expected.format, + tests[i].expected.resource_dimension, D3DX10_IFF_DDS, tests[i].todo_info); + + winetest_pop_context(); + } + + /* + * Image size (e.g, the size of the pixels) isn't validated, but header + * size is. + */ + dds.magic = MAKEFOURCC('D','D','S',' '); + set_dxt10_dds_header(&dds.header, tests[0].append_flags, tests[0].width, tests[0].height, + tests[0].depth, tests[0].mip_levels, tests[0].row_pitch, tests[0].caps, tests[0].caps2); + dds.dxt10 = tests[0].dxt10; + + hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds) - 1, NULL, &info, NULL); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + + hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + static void test_get_image_info(void) { static const WCHAR test_resource_name[] = L"resource.data"; @@ -4782,4 +5147,6 @@ START_TEST(d3dx10) test_create_effect_from_file(); test_create_effect_from_resource(); test_preprocess_shader(); + test_legacy_dds_header_image_info(); + test_dxt10_dds_header_image_info(); }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 5 +- dlls/d3dx10_43/texture.c | 55 ++++++++++++- dlls/d3dx9_36/d3dx_helpers.c | 144 +++++++++++++++++++++++++++++----- dlls/d3dx9_36/d3dx_helpers.h | 14 ++++ 4 files changed, 191 insertions(+), 27 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 4bc15a78258..51d55e87d21 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3139,7 +3139,6 @@ static void test_dxt10_dds_header_image_info(void) 0, 4, 4, 2, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, 0, 1, 0, }, (4 * 4 * 4 * 2), { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, }, - .todo_info = TRUE }, /* * 3D texture with an array size larger than 1. Technically there's no @@ -3418,8 +3417,8 @@ static void test_get_image_info(void) check_dds_dxt10_format(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, TRUE); check_dds_dxt10_format(DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, TRUE); check_dds_dxt10_format(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, TRUE); - check_dds_dxt10_format(DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, TRUE); - check_dds_dxt10_format(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, FALSE); + check_dds_dxt10_format(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, FALSE);
/* D3DX10GetImageInfoFromResource tests */
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 70bf062dd33..0a65bfa8b73 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -99,6 +99,48 @@ static DXGI_FORMAT dxgi_format_from_legacy_dds_d3dx_pixel_format_id(enum d3dx_pi } }
+static DXGI_FORMAT dxgi_format_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id format) +{ + switch (format) + { + case D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM; + case D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; + case D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DX_PIXEL_FORMAT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; + case D3DX_PIXEL_FORMAT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; + case D3DX_PIXEL_FORMAT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case D3DX_PIXEL_FORMAT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case D3DX_PIXEL_FORMAT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case D3DX_PIXEL_FORMAT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case D3DX_PIXEL_FORMAT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case D3DX_PIXEL_FORMAT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; + case D3DX_PIXEL_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM; + case D3DX_PIXEL_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM; + case D3DX_PIXEL_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM; + case D3DX_PIXEL_FORMAT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; + case D3DX_PIXEL_FORMAT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM; + case D3DX_PIXEL_FORMAT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM; + case D3DX_PIXEL_FORMAT_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM; + + /* + * These have DXGI_FORMAT equivalents, but are explicitly unsupported on + * d3dx10. + */ + case D3DX_PIXEL_FORMAT_B5G6R5_UNORM: + case D3DX_PIXEL_FORMAT_B5G5R5A1_UNORM: + case D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM: + return DXGI_FORMAT_UNKNOWN; + + default: + FIXME("Unhandled d3dx_pixel_format_id %#x.\n", format); + return DXGI_FORMAT_UNKNOWN; + } +} + static D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_format(enum d3dx_image_file_format iff) { switch (iff) @@ -107,6 +149,7 @@ static D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_fo case D3DX_IMAGE_FILE_FORMAT_JPG: return D3DX10_IFF_JPG; case D3DX_IMAGE_FILE_FORMAT_PNG: return D3DX10_IFF_PNG; case D3DX_IMAGE_FILE_FORMAT_DDS: return D3DX10_IFF_DDS; + case D3DX_IMAGE_FILE_FORMAT_DDS_DXT10: return D3DX10_IFF_DDS; default: FIXME("No D3DX10_IMAGE_FILE_FORMAT for d3dx_image_file_format %d.\n", iff); return D3DX10_IFF_FORCE_DWORD; @@ -510,9 +553,14 @@ HRESULT WINAPI D3DX10GetImageInfoFromResourceW(HMODULE module, const WCHAR *reso static HRESULT d3dx10_image_info_from_d3dx_image(D3DX10_IMAGE_INFO *info, struct d3dx_image *image) { D3DX10_IMAGE_FILE_FORMAT iff = d3dx10_image_file_format_from_d3dx_image_file_format(image->image_file_format); - DXGI_FORMAT format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + DXGI_FORMAT format;
memset(info, 0, sizeof(*info)); + if (image->image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS_DXT10) + format = dxgi_format_from_d3dx_pixel_format_id(image->format); + else + format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + if (format == DXGI_FORMAT_UNKNOWN) { WARN("Tried to load DDS file with unsupported format %#x.\n", image->format); @@ -568,8 +616,9 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf if (!data || !size) return E_FAIL;
- if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY)) - && image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS) + if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10)) + && (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS + || (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS_DXT10))) { if (SUCCEEDED(d3dx10_image_info_from_d3dx_image(img_info, &image))) { diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 800398af0e1..3574bc8324f 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -363,6 +363,42 @@ static HRESULT dds_pixel_format_from_d3dx_pixel_format_id(struct dds_pixel_forma return D3D_OK; }
+static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: return D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM: return D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM: return D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM; + case DXGI_FORMAT_B5G6R5_UNORM: return D3DX_PIXEL_FORMAT_B5G6R5_UNORM; + case DXGI_FORMAT_B5G5R5A1_UNORM: return D3DX_PIXEL_FORMAT_B5G5R5A1_UNORM; + case DXGI_FORMAT_B4G4R4A4_UNORM: return D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM; + case DXGI_FORMAT_R10G10B10A2_UNORM: return D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R16G16B16A16_UNORM: return D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R16G16_UNORM: return D3DX_PIXEL_FORMAT_R16G16_UNORM; + case DXGI_FORMAT_A8_UNORM: return D3DX_PIXEL_FORMAT_A8_UNORM; + case DXGI_FORMAT_R16_FLOAT: return D3DX_PIXEL_FORMAT_R16_FLOAT; + case DXGI_FORMAT_R16G16_FLOAT: return D3DX_PIXEL_FORMAT_R16G16_FLOAT; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT; + case DXGI_FORMAT_R32_FLOAT: return D3DX_PIXEL_FORMAT_R32_FLOAT; + case DXGI_FORMAT_R32G32_FLOAT: return D3DX_PIXEL_FORMAT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32B32A32_FLOAT: return D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT; + case DXGI_FORMAT_G8R8_G8B8_UNORM: return D3DX_PIXEL_FORMAT_G8R8_G8B8_UNORM; + case DXGI_FORMAT_R8G8_B8G8_UNORM: return D3DX_PIXEL_FORMAT_R8G8_B8G8_UNORM; + case DXGI_FORMAT_BC1_UNORM: return D3DX_PIXEL_FORMAT_BC1_UNORM; + case DXGI_FORMAT_BC2_UNORM: return D3DX_PIXEL_FORMAT_BC2_UNORM; + case DXGI_FORMAT_BC3_UNORM: return D3DX_PIXEL_FORMAT_BC3_UNORM; + case DXGI_FORMAT_R8G8B8A8_SNORM: return D3DX_PIXEL_FORMAT_R8G8B8A8_SNORM; + case DXGI_FORMAT_R8G8_SNORM: return D3DX_PIXEL_FORMAT_R8G8_SNORM; + case DXGI_FORMAT_R16G16_SNORM: return D3DX_PIXEL_FORMAT_R16G16_SNORM; + case DXGI_FORMAT_R16G16B16A16_SNORM: return D3DX_PIXEL_FORMAT_R16G16B16A16_SNORM; + + default: + FIXME("Unhandled DXGI format %#x.\n", format); + return D3DX_PIXEL_FORMAT_COUNT; + } +} + static void d3dx_get_next_mip_level_size(struct volume *size) { size->width = max(size->width / 2, 1); @@ -993,8 +1029,44 @@ static BOOL d3dx_get_image_file_format_from_file_signature(const void *src_data, return FALSE; }
+/* These defines match D3D10/D3D11 values. */ +#define DDS_RESOURCE_MISC_TEXTURECUBE 0x04 +#define DDS_RESOURCE_DIMENSION_TEXTURE1D 2 +#define DDS_RESOURCE_DIMENSION_TEXTURE2D 3 +#define DDS_RESOURCE_DIMENSION_TEXTURE3D 4 +struct dds_header_dxt10 +{ + uint32_t dxgi_format; + uint32_t resource_dimension; + uint32_t misc_flags; + uint32_t array_size; + uint32_t misc_flags2; +}; + +static enum d3dx_resource_type dxt10_resource_dimension_to_d3dx_resource_type(uint32_t resource_dimension) +{ + switch (resource_dimension) + { + case DDS_RESOURCE_DIMENSION_TEXTURE1D: return D3DX_RESOURCE_TYPE_TEXTURE_1D; + case DDS_RESOURCE_DIMENSION_TEXTURE2D: return D3DX_RESOURCE_TYPE_TEXTURE_2D; + case DDS_RESOURCE_DIMENSION_TEXTURE3D: return D3DX_RESOURCE_TYPE_TEXTURE_3D; + + default: + break; + } + + FIXME("Unhandled DXT10 resource dimension value %u.\n", resource_dimension); + return D3DX_RESOURCE_TYPE_UNKNOWN; +} + +static BOOL has_extended_header(const struct dds_header *header) +{ + return (header->pixel_format.flags & DDS_PF_FOURCC) && + (header->pixel_format.fourcc == MAKEFOURCC('D', 'X', '1', '0')); +} + static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src_data_size, - struct d3dx_image *image, uint32_t starting_mip_level) + struct d3dx_image *image, uint32_t starting_mip_level, uint32_t flags) { uint32_t expected_src_data_size, header_size; const struct dds_header *header = src_data; @@ -1004,40 +1076,71 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src if (src_data_size < sizeof(*header) || header->pixel_format.size != sizeof(header->pixel_format)) return D3DXERR_INVALIDDATA;
- TRACE("File type is DDS.\n"); is_indexed_fmt = !!(header->pixel_format.flags & DDS_PF_INDEXED); header_size = is_indexed_fmt ? sizeof(*header) + DDS_PALETTE_SIZE : sizeof(*header);
set_volume_struct(&image->size, header->width, header->height, 1); image->mip_levels = header->miplevels ? header->miplevels : 1; - image->format = d3dx_pixel_format_id_from_dds_pixel_format(&header->pixel_format); - image->layer_count = 1; + if (has_extended_header(header) && (flags & D3DX_IMAGE_SUPPORT_DXT10)) + { + const struct dds_header_dxt10 *dxt10 = (const struct dds_header_dxt10 *)((uint8_t *)src_data + header_size);
- if (image->format == D3DX_PIXEL_FORMAT_COUNT) - return D3DXERR_INVALIDDATA; + header_size += sizeof(*dxt10); + if (src_data_size < header_size) + return D3DXERR_INVALIDDATA;
- TRACE("Pixel format is %#x.\n", image->format); - if (header->flags & DDS_DEPTH) - { - image->size.depth = max(header->depth, 1); - image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_3D; - } - else if (header->caps2 & DDS_CAPS2_CUBEMAP) - { - if ((header->caps2 & DDS_CAPS2_CUBEMAP_ALL_FACES) != DDS_CAPS2_CUBEMAP_ALL_FACES) + TRACE("File type is DXT10 DDS.\n"); + if ((image->format = d3dx_pixel_format_id_from_dxgi_format(dxt10->dxgi_format)) == D3DX_PIXEL_FORMAT_COUNT) + return D3DXERR_INVALIDDATA; + + if (dxt10->misc_flags2) { - WARN("Tried to load a partial cubemap DDS file.\n"); + ERR("Invalid misc_flags2 field %#x.\n", dxt10->misc_flags2); return D3DXERR_INVALIDDATA; }
- image->layer_count = 6; - image->resource_type = D3DX_RESOURCE_TYPE_CUBE_TEXTURE; + image->image_file_format = D3DX_IMAGE_FILE_FORMAT_DDS_DXT10; + image->size.depth = (header->flags & DDS_DEPTH) ? max(header->depth, 1) : 1; + image->layer_count = max(1, dxt10->array_size); + image->resource_type = dxt10_resource_dimension_to_d3dx_resource_type(dxt10->resource_dimension); + if (dxt10->misc_flags & DDS_RESOURCE_MISC_TEXTURECUBE) + { + if (image->resource_type != D3DX_RESOURCE_TYPE_TEXTURE_2D) + return D3DXERR_INVALIDDATA; + image->resource_type = D3DX_RESOURCE_TYPE_CUBE_TEXTURE; + image->layer_count *= 6; + } } else { - image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_2D; + TRACE("File type is DDS.\n"); + + if ((image->format = d3dx_pixel_format_id_from_dds_pixel_format(&header->pixel_format)) == D3DX_PIXEL_FORMAT_COUNT) + return D3DXERR_INVALIDDATA; + + image->image_file_format = D3DX_IMAGE_FILE_FORMAT_DDS; + image->layer_count = 1; + if (header->flags & DDS_DEPTH) + { + image->size.depth = max(header->depth, 1); + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_3D; + } + else if (header->caps2 & DDS_CAPS2_CUBEMAP) + { + if ((header->caps2 & DDS_CAPS2_CUBEMAP_ALL_FACES) != DDS_CAPS2_CUBEMAP_ALL_FACES) + { + WARN("Tried to load a partial cubemap DDS file.\n"); + return D3DXERR_INVALIDDATA; + } + + image->layer_count = 6; + image->resource_type = D3DX_RESOURCE_TYPE_CUBE_TEXTURE; + } + else + image->resource_type = D3DX_RESOURCE_TYPE_TEXTURE_2D; }
+ TRACE("Pixel format is %#x.\n", image->format); image->layer_pitch = d3dx_calculate_layer_pixels_size(image->format, image->size.width, image->size.height, image->size.depth, image->mip_levels); if (!image->layer_pitch) @@ -1051,7 +1154,6 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src
image->palette = (is_indexed_fmt) ? (PALETTEENTRY *)(((uint8_t *)src_data) + sizeof(*header)) : NULL; image->pixels = ((BYTE *)src_data) + header_size; - image->image_file_format = D3DX_IMAGE_FILE_FORMAT_DDS; if (starting_mip_level && (image->mip_levels > 1)) { uint32_t i, row_pitch, slice_pitch, initial_mip_levels; @@ -1650,7 +1752,7 @@ HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3d break;
case D3DX_IMAGE_FILE_FORMAT_DDS: - hr = d3dx_initialize_image_from_dds(src_data, src_data_size, image, starting_mip_level); + hr = d3dx_initialize_image_from_dds(src_data, src_data_size, image, starting_mip_level, flags); break;
case D3DX_IMAGE_FILE_FORMAT_PPM: diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 0f440831259..a04290f44d5 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -149,11 +149,15 @@ enum d3dx_image_file_format D3DX_IMAGE_FILE_FORMAT_DIB = 6, D3DX_IMAGE_FILE_FORMAT_HDR = 7, D3DX_IMAGE_FILE_FORMAT_PFM = 8, + /* This is a Wine only file format value. */ + D3DX_IMAGE_FILE_FORMAT_DDS_DXT10 = 100, D3DX_IMAGE_FILE_FORMAT_FORCE_DWORD = 0x7fffffff };
enum d3dx_resource_type { + D3DX_RESOURCE_TYPE_UNKNOWN, + D3DX_RESOURCE_TYPE_TEXTURE_1D, D3DX_RESOURCE_TYPE_TEXTURE_2D, D3DX_RESOURCE_TYPE_TEXTURE_3D, D3DX_RESOURCE_TYPE_CUBE_TEXTURE, @@ -214,6 +218,15 @@ enum d3dx_pixel_format_id D3DX_PIXEL_FORMAT_COUNT, };
+/* These are aliases. */ +#define D3DX_PIXEL_FORMAT_R16G16B16A16_SNORM D3DX_PIXEL_FORMAT_U16V16W16Q16_SNORM +#define D3DX_PIXEL_FORMAT_R16G16_SNORM D3DX_PIXEL_FORMAT_U16V16_SNORM +#define D3DX_PIXEL_FORMAT_R8G8B8A8_SNORM D3DX_PIXEL_FORMAT_U8V8W8Q8_SNORM +#define D3DX_PIXEL_FORMAT_R8G8_SNORM D3DX_PIXEL_FORMAT_U8V8_SNORM +#define D3DX_PIXEL_FORMAT_BC1_UNORM D3DX_PIXEL_FORMAT_DXT1_UNORM +#define D3DX_PIXEL_FORMAT_BC2_UNORM D3DX_PIXEL_FORMAT_DXT3_UNORM +#define D3DX_PIXEL_FORMAT_BC3_UNORM D3DX_PIXEL_FORMAT_DXT5_UNORM + /* for internal use */ enum component_type { @@ -270,6 +283,7 @@ static inline void set_d3dx_pixels(struct d3dx_pixels *pixels, const void *data, }
#define D3DX_IMAGE_INFO_ONLY 1 +#define D3DX_IMAGE_SUPPORT_DXT10 2 struct d3dx_image { enum d3dx_resource_type resource_type;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 6 ++---- dlls/d3dx9_36/d3dx_helpers.c | 4 +++- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 51d55e87d21..988a1584bd2 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2960,7 +2960,6 @@ static void test_legacy_dds_header_image_info(void) { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 3, 0, 0, 0, { S_OK, 4, 4, 1, 1, 3, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, }, - .todo_hr = TRUE }, /* Depth value set to 4, but no caps bits are set. Depth is ignored. */ { @@ -3060,7 +3059,7 @@ static void test_legacy_dds_header_image_info(void) ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
static void test_dxt10_dds_header_image_info(void) @@ -3099,7 +3098,6 @@ static void test_dxt10_dds_header_image_info(void) 0, 4, 4, 0, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0, }, 0, { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, }, - .todo_hr = TRUE }, /* * Setting the misc_flags2 field to anything other than 0 results in @@ -3228,7 +3226,7 @@ static void test_dxt10_dds_header_image_info(void) ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
hr = D3DX10GetImageInfoFromMemory(&dds, sizeof(dds), NULL, &info, NULL); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
static void test_get_image_info(void) diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 3574bc8324f..535461db599 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -1149,7 +1149,9 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src if (src_data_size < expected_src_data_size) { WARN("File is too short %u, expected at least %u bytes.\n", src_data_size, expected_src_data_size); - return D3DXERR_INVALIDDATA; + /* D3DX10/D3DX11 do not validate the size of the pixels, only the header. */ + if (!(flags & D3DX_IMAGE_SUPPORT_DXT10)) + return D3DXERR_INVALIDDATA; }
image->palette = (is_indexed_fmt) ? (PALETTEENTRY *)(((uint8_t *)src_data) + sizeof(*header)) : NULL;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 6 +++--- dlls/d3dx10_43/texture.c | 12 ++++++++++++ dlls/d3dx9_36/d3dx_helpers.c | 18 ++++++++++++++++++ dlls/d3dx9_36/d3dx_helpers.h | 18 ++++++++++++++++++ dlls/d3dx9_36/util.c | 6 +++++- 5 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 988a1584bd2..27a3c38223e 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3412,9 +3412,9 @@ static void test_get_image_info(void) * These formats should map 1:1 from the DXT10 header, unlike legacy DDS * file equivalents. */ - check_dds_dxt10_format(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, TRUE); - check_dds_dxt10_format(DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, TRUE); - check_dds_dxt10_format(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, TRUE); + check_dds_dxt10_format(DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, FALSE); + check_dds_dxt10_format(DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, FALSE); + check_dds_dxt10_format(DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, FALSE); check_dds_dxt10_format(DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, FALSE); check_dds_dxt10_format(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, FALSE);
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 0a65bfa8b73..379a2efc0ad 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -82,6 +82,10 @@ static DXGI_FORMAT dxgi_format_from_legacy_dds_d3dx_pixel_format_id(enum d3dx_pi case D3DX_PIXEL_FORMAT_DXT3_UNORM: return DXGI_FORMAT_BC2_UNORM; case D3DX_PIXEL_FORMAT_DXT4_UNORM: return DXGI_FORMAT_BC3_UNORM; case D3DX_PIXEL_FORMAT_DXT5_UNORM: return DXGI_FORMAT_BC3_UNORM; + case D3DX_PIXEL_FORMAT_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM; + case D3DX_PIXEL_FORMAT_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM; + case D3DX_PIXEL_FORMAT_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM; + case D3DX_PIXEL_FORMAT_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM;
/* These formats are known and explicitly unsupported on d3dx10+. */ case D3DX_PIXEL_FORMAT_U8V8W8Q8_SNORM: @@ -108,6 +112,9 @@ static DXGI_FORMAT dxgi_format_from_d3dx_pixel_format_id(enum d3dx_pixel_format_ case D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM; case D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; case D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DX_PIXEL_FORMAT_R8_UNORM: return DXGI_FORMAT_R8_UNORM; + case D3DX_PIXEL_FORMAT_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM; + case D3DX_PIXEL_FORMAT_R16_UNORM: return DXGI_FORMAT_R16_UNORM; case D3DX_PIXEL_FORMAT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; case D3DX_PIXEL_FORMAT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; case D3DX_PIXEL_FORMAT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; @@ -115,12 +122,17 @@ static DXGI_FORMAT dxgi_format_from_d3dx_pixel_format_id(enum d3dx_pixel_format_ case D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; case D3DX_PIXEL_FORMAT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; case D3DX_PIXEL_FORMAT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case D3DX_PIXEL_FORMAT_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT; case D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; case D3DX_PIXEL_FORMAT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; case D3DX_PIXEL_FORMAT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; case D3DX_PIXEL_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM; case D3DX_PIXEL_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM; case D3DX_PIXEL_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM; + case D3DX_PIXEL_FORMAT_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM; + case D3DX_PIXEL_FORMAT_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM; + case D3DX_PIXEL_FORMAT_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM; + case D3DX_PIXEL_FORMAT_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM; case D3DX_PIXEL_FORMAT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; case D3DX_PIXEL_FORMAT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM; case D3DX_PIXEL_FORMAT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM; diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 535461db599..b44ff3ce6c9 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -80,6 +80,9 @@ static const struct pixel_format_desc formats[] = {D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM, { 2, 10, 10, 10}, {30, 0, 10, 20}, 4, 1, 1, 4, CTYPE_UNORM, CTYPE_UNORM, 0 }, {D3DX_PIXEL_FORMAT_R16G16B16_UNORM, { 0, 16, 16, 16}, { 0, 0, 16, 32}, 6, 1, 1, 6, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_INTERNAL}, {D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM, {16, 16, 16, 16}, {48, 0, 16, 32}, 8, 1, 1, 8, CTYPE_UNORM, CTYPE_UNORM, 0 }, + {D3DX_PIXEL_FORMAT_R8_UNORM, { 0, 8, 0, 0}, { 0, 0, 0, 0}, 1, 1, 1, 1, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_DXGI}, + {D3DX_PIXEL_FORMAT_R8G8_UNORM, { 0, 8, 8, 0}, { 0, 0, 8, 0}, 2, 1, 1, 2, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_DXGI}, + {D3DX_PIXEL_FORMAT_R16_UNORM, { 0, 16, 0, 0}, { 0, 0, 0, 0}, 2, 1, 1, 2, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_DXGI}, {D3DX_PIXEL_FORMAT_R16G16_UNORM, { 0, 16, 16, 0}, { 0, 0, 16, 0}, 4, 1, 1, 4, CTYPE_EMPTY, CTYPE_UNORM, 0 }, {D3DX_PIXEL_FORMAT_A8_UNORM, { 8, 0, 0, 0}, { 0, 0, 0, 0}, 1, 1, 1, 1, CTYPE_UNORM, CTYPE_EMPTY, 0 }, {D3DX_PIXEL_FORMAT_L8A8_UNORM, { 8, 8, 0, 0}, { 8, 0, 0, 0}, 2, 1, 1, 2, CTYPE_UNORM, CTYPE_LUMA, 0 }, @@ -91,11 +94,16 @@ static const struct pixel_format_desc formats[] = {D3DX_PIXEL_FORMAT_DXT3_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT}, {D3DX_PIXEL_FORMAT_DXT4_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT}, {D3DX_PIXEL_FORMAT_DXT5_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT}, + {D3DX_PIXEL_FORMAT_BC4_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 8, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_DXT|FMT_FLAG_DXGI}, + {D3DX_PIXEL_FORMAT_BC4_SNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 8, CTYPE_EMPTY, CTYPE_SNORM, FMT_FLAG_DXT|FMT_FLAG_DXGI}, + {D3DX_PIXEL_FORMAT_BC5_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_EMPTY, CTYPE_UNORM, FMT_FLAG_DXT|FMT_FLAG_DXGI}, + {D3DX_PIXEL_FORMAT_BC5_SNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_EMPTY, CTYPE_SNORM, FMT_FLAG_DXT|FMT_FLAG_DXGI}, {D3DX_PIXEL_FORMAT_R16_FLOAT, { 0, 16, 0, 0}, { 0, 0, 0, 0}, 2, 1, 1, 2, CTYPE_EMPTY, CTYPE_FLOAT, 0 }, {D3DX_PIXEL_FORMAT_R16G16_FLOAT, { 0, 16, 16, 0}, { 0, 0, 16, 0}, 4, 1, 1, 4, CTYPE_EMPTY, CTYPE_FLOAT, 0 }, {D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT, {16, 16, 16, 16}, {48, 0, 16, 32}, 8, 1, 1, 8, CTYPE_FLOAT, CTYPE_FLOAT, 0 }, {D3DX_PIXEL_FORMAT_R32_FLOAT, { 0, 32, 0, 0}, { 0, 0, 0, 0}, 4, 1, 1, 4, CTYPE_EMPTY, CTYPE_FLOAT, 0 }, {D3DX_PIXEL_FORMAT_R32G32_FLOAT, { 0, 32, 32, 0}, { 0, 0, 32, 0}, 8, 1, 1, 8, CTYPE_EMPTY, CTYPE_FLOAT, 0 }, + {D3DX_PIXEL_FORMAT_R32G32B32_FLOAT, { 0, 32, 32, 32}, { 0, 0, 32, 64}, 12, 1, 1, 12, CTYPE_EMPTY, CTYPE_FLOAT, FMT_FLAG_DXGI}, {D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT, {32, 32, 32, 32}, {96, 0, 32, 64}, 16, 1, 1, 16, CTYPE_FLOAT, CTYPE_FLOAT, 0 }, {D3DX_PIXEL_FORMAT_P1_UINT, { 8, 8, 8, 8}, { 0, 0, 0, 0}, 1, 8, 1, 1, CTYPE_INDEX, CTYPE_INDEX, FMT_FLAG_INTERNAL}, {D3DX_PIXEL_FORMAT_P2_UINT, { 8, 8, 8, 8}, { 0, 0, 0, 0}, 1, 4, 1, 1, CTYPE_INDEX, CTYPE_INDEX, FMT_FLAG_INTERNAL}, @@ -217,6 +225,12 @@ static const struct { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','3') }, D3DX_PIXEL_FORMAT_DXT3_UNORM }, { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','4') }, D3DX_PIXEL_FORMAT_DXT4_UNORM }, { { 32, DDS_PF_FOURCC, MAKEFOURCC('D','X','T','5') }, D3DX_PIXEL_FORMAT_DXT5_UNORM }, + { { 32, DDS_PF_FOURCC, MAKEFOURCC('B','C','4','U') }, D3DX_PIXEL_FORMAT_BC4_UNORM }, + { { 32, DDS_PF_FOURCC, MAKEFOURCC('B','C','4','S') }, D3DX_PIXEL_FORMAT_BC4_SNORM }, + /* ATI2 is treated identically to BC5U in d3dx10+. */ + { { 32, DDS_PF_FOURCC, MAKEFOURCC('A','T','I','2') }, D3DX_PIXEL_FORMAT_BC5_UNORM }, + { { 32, DDS_PF_FOURCC, MAKEFOURCC('B','C','5','U') }, D3DX_PIXEL_FORMAT_BC5_UNORM }, + { { 32, DDS_PF_FOURCC, MAKEFOURCC('B','C','5','S') }, D3DX_PIXEL_FORMAT_BC5_SNORM }, /* These aren't actually fourcc values, they're just D3DFMT values. */ { { 32, DDS_PF_FOURCC, 0x24 }, D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM }, { { 32, DDS_PF_FOURCC, 0x6e }, D3DX_PIXEL_FORMAT_U16V16W16Q16_SNORM }, @@ -375,6 +389,9 @@ static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(DXGI_FORM case DXGI_FORMAT_B4G4R4A4_UNORM: return D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM; case DXGI_FORMAT_R10G10B10A2_UNORM: return D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM; case DXGI_FORMAT_R16G16B16A16_UNORM: return D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R8_UNORM: return D3DX_PIXEL_FORMAT_R8_UNORM; + case DXGI_FORMAT_R8G8_UNORM: return D3DX_PIXEL_FORMAT_R8G8_UNORM; + case DXGI_FORMAT_R16_UNORM: return D3DX_PIXEL_FORMAT_R16_UNORM; case DXGI_FORMAT_R16G16_UNORM: return D3DX_PIXEL_FORMAT_R16G16_UNORM; case DXGI_FORMAT_A8_UNORM: return D3DX_PIXEL_FORMAT_A8_UNORM; case DXGI_FORMAT_R16_FLOAT: return D3DX_PIXEL_FORMAT_R16_FLOAT; @@ -382,6 +399,7 @@ static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(DXGI_FORM case DXGI_FORMAT_R16G16B16A16_FLOAT: return D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT; case DXGI_FORMAT_R32_FLOAT: return D3DX_PIXEL_FORMAT_R32_FLOAT; case DXGI_FORMAT_R32G32_FLOAT: return D3DX_PIXEL_FORMAT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32B32_FLOAT: return D3DX_PIXEL_FORMAT_R32G32B32_FLOAT; case DXGI_FORMAT_R32G32B32A32_FLOAT: return D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT; case DXGI_FORMAT_G8R8_G8B8_UNORM: return D3DX_PIXEL_FORMAT_G8R8_G8B8_UNORM; case DXGI_FORMAT_R8G8_B8G8_UNORM: return D3DX_PIXEL_FORMAT_R8G8_B8G8_UNORM; diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index a04290f44d5..b7fc2186b35 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -183,6 +183,9 @@ enum d3dx_pixel_format_id D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM, D3DX_PIXEL_FORMAT_R16G16B16_UNORM, D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM, + D3DX_PIXEL_FORMAT_R8_UNORM, + D3DX_PIXEL_FORMAT_R8G8_UNORM, + D3DX_PIXEL_FORMAT_R16_UNORM, D3DX_PIXEL_FORMAT_R16G16_UNORM, D3DX_PIXEL_FORMAT_A8_UNORM, D3DX_PIXEL_FORMAT_L8A8_UNORM, @@ -194,11 +197,16 @@ enum d3dx_pixel_format_id D3DX_PIXEL_FORMAT_DXT3_UNORM, D3DX_PIXEL_FORMAT_DXT4_UNORM, D3DX_PIXEL_FORMAT_DXT5_UNORM, + D3DX_PIXEL_FORMAT_BC4_UNORM, + D3DX_PIXEL_FORMAT_BC4_SNORM, + D3DX_PIXEL_FORMAT_BC5_UNORM, + D3DX_PIXEL_FORMAT_BC5_SNORM, D3DX_PIXEL_FORMAT_R16_FLOAT, D3DX_PIXEL_FORMAT_R16G16_FLOAT, D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT, D3DX_PIXEL_FORMAT_R32_FLOAT, D3DX_PIXEL_FORMAT_R32G32_FLOAT, + D3DX_PIXEL_FORMAT_R32G32B32_FLOAT, D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT, D3DX_PIXEL_FORMAT_P1_UINT, D3DX_PIXEL_FORMAT_P2_UINT, @@ -244,6 +252,11 @@ enum format_flag FMT_FLAG_PACKED = 0x02, /* Internal only format, has no exact D3DFORMAT equivalent. */ FMT_FLAG_INTERNAL = 0x04, + /* + * For formats that only have a DXGI_FORMAT mapping, no D3DFORMAT + * equivalent. + */ + FMT_FLAG_DXGI = 0x08, };
struct pixel_format_desc { @@ -353,6 +366,11 @@ static inline BOOL is_internal_format(const struct pixel_format_desc *format) return !!(format->flags & FMT_FLAG_INTERNAL); }
+static inline BOOL is_dxgi_format(const struct pixel_format_desc *format) +{ + return !!(format->flags & FMT_FLAG_DXGI); +} + static inline BOOL is_conversion_from_supported(const struct pixel_format_desc *format) { return !is_packed_format(format) && !is_unknown_format(format); diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c index 8a9aade34f8..dd2162d9f6e 100644 --- a/dlls/d3dx9_36/util.c +++ b/dlls/d3dx9_36/util.c @@ -71,9 +71,13 @@ D3DFORMAT d3dformat_from_d3dx_pixel_format_id(enum d3dx_pixel_format_id format) case D3DX_PIXEL_FORMAT_UYVY: return D3DFMT_UYVY; case D3DX_PIXEL_FORMAT_YUY2: return D3DFMT_YUY2; default: - if (!is_internal_format(get_d3dx_pixel_format_info(format))) + { + const struct pixel_format_desc *fmt_desc = get_d3dx_pixel_format_info(format); + + if (!is_internal_format(fmt_desc) && !is_dxgi_format(fmt_desc)) FIXME("Unknown d3dx_pixel_format_id %u.\n", format); return D3DFMT_UNKNOWN; + } } }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 36 +++++++------- dlls/d3dx10_43/texture.c | 93 ++++------------------------------- 2 files changed, 28 insertions(+), 101 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 27a3c38223e..635f15d8eb2 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3007,7 +3007,7 @@ static void test_legacy_dds_header_image_info(void) { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 1, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_POSITIVEX), (64 * 6), - { E_FAIL, }, .todo_hr = TRUE + { E_FAIL, } }, }; D3DX10_IMAGE_INFO info; @@ -3106,7 +3106,7 @@ static void test_dxt10_dds_header_image_info(void) { 0, 4, 4, 0, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 1, }, (4 * 4 * 4), - { E_FAIL }, .todo_hr = TRUE + { E_FAIL } }, /* * The misc_flags field isn't passed through directly, only the @@ -3121,7 +3121,7 @@ static void test_dxt10_dds_header_image_info(void) { 0, 4, 4, 0, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, 500, 0, 1, 0, }, (4 * 4 * 4), - { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, 500, }, .todo_info = TRUE + { S_OK, 4, 4, 1, 1, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM, 500, }, .todo_hr = TRUE }, /* Depth value of 2, but D3D10_RESOURCE_DIMENSION_TEXTURE2D. */ { @@ -3167,7 +3167,7 @@ static void test_dxt10_dds_header_image_info(void) { 0, 4, 4, 1, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE3D, DDS_RESOURCE_MISC_TEXTURECUBE, 2, 0, }, - (4 * 4 * 4 * 12), { E_FAIL }, .todo_hr = TRUE + (4 * 4 * 4 * 12), { E_FAIL } }, /* * 10. @@ -3176,7 +3176,7 @@ static void test_dxt10_dds_header_image_info(void) { 0, 4, 4, 1, (4 * 4), 1, 0, 0, { DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE1D, DDS_RESOURCE_MISC_TEXTURECUBE, 2, 0, }, - (4 * 4 * 4 * 12), { E_FAIL }, .todo_hr = TRUE + (4 * 4 * 4 * 12), { E_FAIL } }, }; D3DX10_IMAGE_INFO info; @@ -3383,13 +3383,13 @@ static void test_get_image_info(void) check_dds_pixel_format(DDS_PF_FOURCC, 0x74, 0, 0, 0, 0, 0, DXGI_FORMAT_R32G32B32A32_FLOAT); /* D3DFMT_A32B32G32R32F */
/* Test for DDS pixel formats that are valid on d3dx9, but not d3dx10. */ - todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0, E_FAIL); - todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0, E_FAIL); /* Bumpmap formats aren't supported. */ - todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, E_FAIL); - todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, E_FAIL); - todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0xff, 0xff00, 0x00ff0000, 0xff000000, E_FAIL); - todo_wine check_dds_pixel_format_unsupported(DDS_PF_BUMPLUMINANCE, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_BUMPDUDV, 0, 32, 0xff, 0xff00, 0x00ff0000, 0xff000000, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_BUMPLUMINANCE, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0, E_FAIL);
/* Newer fourCC formats. */ check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','4','U'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC4_UNORM); @@ -3397,16 +3397,16 @@ static void test_get_image_info(void) check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','4','S'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC4_SNORM); check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('B','C','5','S'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC5_SNORM); /* ATI1 is unsupported, but ATI2 is supported. */ - todo_wine check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('A','T','I','1'), 0, 0, 0, 0, 0, E_FAIL); + check_dds_pixel_format_unsupported(DDS_PF_FOURCC, MAKEFOURCC('A','T','I','1'), 0, 0, 0, 0, 0, E_FAIL); check_dds_pixel_format(DDS_PF_FOURCC, MAKEFOURCC('A','T','I','2'), 0, 0, 0, 0, 0, DXGI_FORMAT_BC5_UNORM);
- todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G6R5_UNORM, E_FAIL); - todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G5R5A1_UNORM, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G6R5_UNORM, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_B5G5R5A1_UNORM, E_FAIL); /* Formats that are newer than d3d10. */ - todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_UF16, E_FAIL); - todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_SF16, E_FAIL); - todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC7_UNORM, E_FAIL); - todo_wine check_dds_dxt10_format_unsupported(DXGI_FORMAT_B4G4R4A4_UNORM, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_UF16, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC6H_SF16, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_BC7_UNORM, E_FAIL); + check_dds_dxt10_format_unsupported(DXGI_FORMAT_B4G4R4A4_UNORM, E_FAIL);
/* * These formats should map 1:1 from the DXT10 header, unlike legacy DDS diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 379a2efc0ad..1f9998ad27a 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -235,22 +235,6 @@ static const GUID *dxgi_format_to_wic_guid(DXGI_FORMAT format) return NULL; }
-static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension) -{ - switch (wic_dimension) - { - case WICDdsTexture1D: - return D3D10_RESOURCE_DIMENSION_TEXTURE1D; - case WICDdsTexture2D: - case WICDdsTextureCube: - return D3D10_RESOURCE_DIMENSION_TEXTURE2D; - case WICDdsTexture3D: - return D3D10_RESOURCE_DIMENSION_TEXTURE3D; - default: - return D3D10_RESOURCE_DIMENSION_UNKNOWN; - } -} - static unsigned int get_bpp_from_format(DXGI_FORMAT format) { switch (format) @@ -385,36 +369,6 @@ static unsigned int get_bpp_from_format(DXGI_FORMAT format) } }
-static DXGI_FORMAT get_d3dx10_dds_format(DXGI_FORMAT format) -{ - static const struct - { - DXGI_FORMAT src; - DXGI_FORMAT dst; - } - format_map[] = - { - {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM}, - }; - - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(format_map); ++i) - { - if (format == format_map[i].src) - return format_map[i].dst; - } - return format; -} - HRESULT WINAPI D3DX10GetImageInfoFromFileA(const char *src_file, ID3DX10ThreadPump *pump, D3DX10_IMAGE_INFO *info, HRESULT *result) { @@ -616,9 +570,7 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf { IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; - IWICDdsDecoder *dds_decoder = NULL; IWICBitmapDecoder *decoder = NULL; - WICDdsParameters dds_params; IWICStream *stream = NULL; unsigned int frame_count; struct d3dx_image image; @@ -631,13 +583,7 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10)) && (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS || (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS_DXT10))) - { - if (SUCCEEDED(d3dx10_image_info_from_d3dx_image(img_info, &image))) - { - TRACE("Successfully retrieved image info from shared code.\n"); - return S_OK; - } - } + return d3dx10_image_info_from_d3dx_image(img_info, &image);
WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); IWICImagingFactory_CreateStream(factory, &stream); @@ -674,37 +620,18 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf
if (img_info->ImageFileFormat == D3DX10_IFF_DDS) { - hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); - if (FAILED(hr)) - goto end; - hr = IWICDdsDecoder_GetParameters(dds_decoder, &dds_params); - if (FAILED(hr)) - goto end; - img_info->ArraySize = dds_params.ArraySize; - img_info->Depth = dds_params.Depth; - img_info->MipLevels = dds_params.MipLevels; - img_info->ResourceDimension = wic_dimension_to_d3dx10_dimension(dds_params.Dimension); - img_info->Format = get_d3dx10_dds_format(dds_params.DxgiFormat); - img_info->MiscFlags = 0; - if (dds_params.Dimension == WICDdsTextureCube) - { - img_info->MiscFlags = D3D10_RESOURCE_MISC_TEXTURECUBE; - img_info->ArraySize *= 6; - } - } - else - { - img_info->ArraySize = 1; - img_info->Depth = 1; - img_info->MipLevels = 1; - img_info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - img_info->Format = DXGI_FORMAT_R8G8B8A8_UNORM; - img_info->MiscFlags = 0; + hr = E_FAIL; + goto end; }
+ img_info->ArraySize = 1; + img_info->Depth = 1; + img_info->MipLevels = 1; + img_info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + img_info->Format = DXGI_FORMAT_R8G8B8A8_UNORM; + img_info->MiscFlags = 0; + end: - if (dds_decoder) - IWICDdsDecoder_Release(dds_decoder); if (frame) IWICBitmapFrameDecode_Release(frame); if (decoder)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/texture.c | 40 +++++++++++++++++++++++++----------- dlls/d3dx9_36/d3dx_helpers.c | 18 ++++++++++++++++ dlls/d3dx9_36/d3dx_helpers.h | 4 ++++ 3 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 1f9998ad27a..ed9cdd0e0f4 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -161,6 +161,9 @@ static D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_fo case D3DX_IMAGE_FILE_FORMAT_JPG: return D3DX10_IFF_JPG; case D3DX_IMAGE_FILE_FORMAT_PNG: return D3DX10_IFF_PNG; case D3DX_IMAGE_FILE_FORMAT_DDS: return D3DX10_IFF_DDS; + case D3DX_IMAGE_FILE_FORMAT_TIFF: return D3DX10_IFF_TIFF; + case D3DX_IMAGE_FILE_FORMAT_GIF: return D3DX10_IFF_GIF; + case D3DX_IMAGE_FILE_FORMAT_WMP: return D3DX10_IFF_WMP; case D3DX_IMAGE_FILE_FORMAT_DDS_DXT10: return D3DX10_IFF_DDS; default: FIXME("No D3DX10_IMAGE_FILE_FORMAT for d3dx_image_file_format %d.\n", iff); @@ -522,20 +525,31 @@ static HRESULT d3dx10_image_info_from_d3dx_image(D3DX10_IMAGE_INFO *info, struct DXGI_FORMAT format;
memset(info, 0, sizeof(*info)); - if (image->image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS_DXT10) - format = dxgi_format_from_d3dx_pixel_format_id(image->format); - else - format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + switch (image->image_file_format) + { + case D3DX_IMAGE_FILE_FORMAT_DDS_DXT10: + format = dxgi_format_from_d3dx_pixel_format_id(image->format); + break; + + case D3DX_IMAGE_FILE_FORMAT_DDS: + format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + break; + + default: + if (iff == D3DX10_IFF_FORCE_DWORD) + return E_FAIL; + + /* All other image file formats use the default format. */ + format = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + }
if (format == DXGI_FORMAT_UNKNOWN) { - WARN("Tried to load DDS file with unsupported format %#x.\n", image->format); + WARN("Tried to load file with unsupported pixel format %#x.\n", image->format); return E_FAIL; }
- if (iff == D3DX10_IFF_FORCE_DWORD) - return E_FAIL; - switch (image->resource_type) { case D3DX_RESOURCE_TYPE_TEXTURE_2D: @@ -580,10 +594,12 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf if (!data || !size) return E_FAIL;
- if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10)) - && (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS - || (image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS_DXT10))) - return d3dx10_image_info_from_d3dx_image(img_info, &image); + if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10))) + { + hr = d3dx10_image_info_from_d3dx_image(img_info, &image); + if (SUCCEEDED(hr)) + return hr; + }
WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); IWICImagingFactory_CreateStream(factory, &stream); diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index b44ff3ce6c9..60394ca1d9b 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -526,6 +526,9 @@ static const GUID *wic_container_guid_from_d3dx_file_format(enum d3dx_image_file case D3DX_IMAGE_FILE_FORMAT_BMP: return &GUID_ContainerFormatBmp; case D3DX_IMAGE_FILE_FORMAT_JPG: return &GUID_ContainerFormatJpeg; case D3DX_IMAGE_FILE_FORMAT_PNG: return &GUID_ContainerFormatPng; + case D3DX_IMAGE_FILE_FORMAT_TIFF: return &GUID_ContainerFormatTiff; + case D3DX_IMAGE_FILE_FORMAT_GIF: return &GUID_ContainerFormatGif; + case D3DX_IMAGE_FILE_FORMAT_WMP: return &GUID_ContainerFormatWmp; default: assert(0 && "Unexpected file format."); return NULL; @@ -1002,6 +1005,12 @@ static const uint8_t ppm_raw_file_signature[] = { 'P', '6' }; static const uint8_t hdr_file_signature[] = { '#', '?', 'R', 'A', 'D', 'I', 'A', 'N', 'C', 'E', '\n' }; static const uint8_t pfm_color_file_signature[] = { 'P', 'F' }; static const uint8_t pfm_gray_file_signature[] = { 'P', 'f' }; +static const uint8_t tiff_le_file_signature[] = { 'I', 'I', 0x2a, 0x00 }; +static const uint8_t tiff_be_file_signature[] = { 'M', 'M', 0x00, 0x2a }; +static const uint8_t gif_87a_file_signature[] = { 'G', 'I', 'F', '8', '7', 'a' }; +static const uint8_t gif_89a_file_signature[] = { 'G', 'I', 'F', '8', '9', 'a' }; +static const uint8_t wmp_v0_file_signature[] = { 'I', 'I', 0xbc, 0x00 }; +static const uint8_t wmp_v1_file_signature[] = { 'I', 'I', 0xbc, 0x01 };
/* * If none of these match, the file is either DIB, TGA, or something we don't @@ -1025,6 +1034,12 @@ static const struct d3dx_file_format_signature file_format_signatures[] = { hdr_file_signature, sizeof(hdr_file_signature), D3DX_IMAGE_FILE_FORMAT_HDR }, { pfm_color_file_signature, sizeof(pfm_color_file_signature), D3DX_IMAGE_FILE_FORMAT_PFM }, { pfm_gray_file_signature, sizeof(pfm_gray_file_signature), D3DX_IMAGE_FILE_FORMAT_PFM }, + { tiff_le_file_signature, sizeof(tiff_le_file_signature), D3DX_IMAGE_FILE_FORMAT_TIFF }, + { tiff_be_file_signature, sizeof(tiff_be_file_signature), D3DX_IMAGE_FILE_FORMAT_TIFF }, + { gif_87a_file_signature, sizeof(gif_87a_file_signature), D3DX_IMAGE_FILE_FORMAT_GIF }, + { gif_89a_file_signature, sizeof(gif_89a_file_signature), D3DX_IMAGE_FILE_FORMAT_GIF }, + { wmp_v0_file_signature, sizeof(wmp_v0_file_signature), D3DX_IMAGE_FILE_FORMAT_WMP }, + { wmp_v1_file_signature, sizeof(wmp_v1_file_signature), D3DX_IMAGE_FILE_FORMAT_WMP }, };
static BOOL d3dx_get_image_file_format_from_file_signature(const void *src_data, uint32_t src_data_size, @@ -1768,6 +1783,9 @@ HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3d case D3DX_IMAGE_FILE_FORMAT_BMP: case D3DX_IMAGE_FILE_FORMAT_JPG: case D3DX_IMAGE_FILE_FORMAT_PNG: + case D3DX_IMAGE_FILE_FORMAT_TIFF: + case D3DX_IMAGE_FILE_FORMAT_GIF: + case D3DX_IMAGE_FILE_FORMAT_WMP: hr = d3dx_initialize_image_from_wic(src_data, src_data_size, image, iff, flags); break;
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index b7fc2186b35..8263d832bfa 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -149,6 +149,10 @@ enum d3dx_image_file_format D3DX_IMAGE_FILE_FORMAT_DIB = 6, D3DX_IMAGE_FILE_FORMAT_HDR = 7, D3DX_IMAGE_FILE_FORMAT_PFM = 8, + /* TIFF/GIF/WMP are only available on D3DX10/D3DX11. */ + D3DX_IMAGE_FILE_FORMAT_TIFF = 10, + D3DX_IMAGE_FILE_FORMAT_GIF = 11, + D3DX_IMAGE_FILE_FORMAT_WMP = 12, /* This is a Wine only file format value. */ D3DX_IMAGE_FILE_FORMAT_DDS_DXT10 = 100, D3DX_IMAGE_FILE_FORMAT_FORCE_DWORD = 0x7fffffff
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 | 97 +---------------------------------- 2 files changed, 3 insertions(+), 96 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 635f15d8eb2..98da6ab786b 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -3277,7 +3277,7 @@ static void test_get_image_info(void) /* 2 bpp is not a valid bit count. */ hr2 = 0xdeadbeef; hr = D3DX10GetImageInfoFromMemory(test_bmp_2bpp, sizeof(test_bmp_2bpp), NULL, &image_info, &hr2); - todo_wine ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr); + ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
for (i = 0; i < ARRAY_SIZE(test_image); ++i) diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index ed9cdd0e0f4..ab488dcfa2f 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -171,22 +171,6 @@ static D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_fo } }
-static const struct -{ - const GUID *wic_container_guid; - D3DX10_IMAGE_FILE_FORMAT d3dx_file_format; -} -file_formats[] = -{ - { &GUID_ContainerFormatBmp, D3DX10_IFF_BMP }, - { &GUID_ContainerFormatJpeg, D3DX10_IFF_JPG }, - { &GUID_ContainerFormatPng, D3DX10_IFF_PNG }, - { &GUID_ContainerFormatDds, D3DX10_IFF_DDS }, - { &GUID_ContainerFormatTiff, D3DX10_IFF_TIFF }, - { &GUID_ContainerFormatGif, D3DX10_IFF_GIF }, - { &GUID_ContainerFormatWmp, D3DX10_IFF_WMP }, -}; - static const struct { const GUID *wic_guid; @@ -213,18 +197,6 @@ wic_pixel_formats[] = { &GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT } };
-static D3DX10_IMAGE_FILE_FORMAT wic_container_guid_to_file_format(GUID *container_format) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(file_formats); ++i) - { - if (IsEqualGUID(file_formats[i].wic_container_guid, container_format)) - return file_formats[i].d3dx_file_format; - } - return D3DX10_IFF_FORCE_DWORD; -} - static const GUID *dxgi_format_to_wic_guid(DXGI_FORMAT format) { unsigned int i; @@ -582,80 +554,15 @@ static HRESULT d3dx10_image_info_from_d3dx_image(D3DX10_IMAGE_INFO *info, struct
HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) { - IWICBitmapFrameDecode *frame = NULL; - IWICImagingFactory *factory = NULL; - IWICBitmapDecoder *decoder = NULL; - IWICStream *stream = NULL; - unsigned int frame_count; struct d3dx_image image; - GUID container_format; HRESULT hr;
if (!data || !size) return E_FAIL;
- if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10))) - { + hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10); + if (SUCCEEDED(hr)) hr = d3dx10_image_info_from_d3dx_image(img_info, &image); - if (SUCCEEDED(hr)) - return hr; - } - - WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - IWICImagingFactory_CreateStream(factory, &stream); - hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size); - if (FAILED(hr)) - { - WARN("Failed to initialize stream.\n"); - goto end; - } - hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder); - if (FAILED(hr)) - goto end; - - hr = IWICBitmapDecoder_GetContainerFormat(decoder, &container_format); - if (FAILED(hr)) - goto end; - img_info->ImageFileFormat = wic_container_guid_to_file_format(&container_format); - if (img_info->ImageFileFormat == D3DX10_IFF_FORCE_DWORD) - { - hr = E_FAIL; - WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format)); - goto end; - } - - hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - if (FAILED(hr) || !frame_count) - goto end; - hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - if (FAILED(hr)) - goto end; - hr = IWICBitmapFrameDecode_GetSize(frame, &img_info->Width, &img_info->Height); - if (FAILED(hr)) - goto end; - - if (img_info->ImageFileFormat == D3DX10_IFF_DDS) - { - hr = E_FAIL; - goto end; - } - - img_info->ArraySize = 1; - img_info->Depth = 1; - img_info->MipLevels = 1; - img_info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - img_info->Format = DXGI_FORMAT_R8G8B8A8_UNORM; - img_info->MiscFlags = 0; - -end: - if (frame) - IWICBitmapFrameDecode_Release(frame); - if (decoder) - IWICBitmapDecoder_Release(decoder); - if (stream) - IWICStream_Release(stream); - if (factory) - IWICImagingFactory_Release(factory);
if (hr != S_OK) {