[PATCH 0/7] MR10513: d3dx{9,10,11}: Add support for premultiplied alpha and SRGB conversions.
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 86 +++++++++++++++++++++++++++++++++++ dlls/d3dx11_43/tests/d3dx11.c | 86 +++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 3ea4499f20e..91778dc5a0f 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -5601,6 +5601,91 @@ static void test_image_filters(void) ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); } +/* + * DXT2 and DXT4 are decoded without taking premultiplied alpha + * into account on d3dx10/d3dx11. + */ +static void test_dxt_formats(void) +{ + static const uint8_t expected_dst[] = + { + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + }; + static const uint8_t test_dxt2_dxt3_data[] = + { + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const uint8_t test_dxt4_dxt5_data[] = + { + 0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const DWORD test_dds_fmt[] = + { + MAKEFOURCC('D','X','T','2'), MAKEFOURCC('D','X','T','3'), + MAKEFOURCC('D','X','T','4'), MAKEFOURCC('D','X','T','5'), + }; + struct + { + DWORD magic; + struct dds_header header; + BYTE data[256]; + } dds; + D3DX10_IMAGE_LOAD_INFO load_info; + struct resource_readback rb; + ID3D10Resource *resource; + ID3D10Device *device; + unsigned int i; + HRESULT hr; + + device = create_device(); + if (!device) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + CoInitialize(NULL); + + dds.magic = MAKEFOURCC('D','D','S',' '); + fill_dds_header(&dds.header); + dds.header.pixel_format.flags = DDS_PF_FOURCC; + dds.header.pixel_format.bpp = 0; + dds.header.pixel_format.rmask = 0; + dds.header.pixel_format.gmask = 0; + dds.header.pixel_format.bmask = 0; + dds.header.pixel_format.amask = 0; + + memset(dds.data, 0, sizeof(dds.data)); + load_info = d3dx10_default_load_info; + load_info.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + load_info.Filter = load_info.MipFilter = D3DX10_FILTER_NONE; + + for (i = 0; i < ARRAY_SIZE(test_dds_fmt); ++i) + { + winetest_push_context("Test %u (%s)", i, debugstr_fourcc(test_dds_fmt[i])); + if (i < 2) + memcpy(dds.data, test_dxt2_dxt3_data, sizeof(test_dxt2_dxt3_data)); + else + memcpy(dds.data, test_dxt4_dxt5_data, sizeof(test_dxt4_dxt5_data)); + dds.header.pixel_format.fourcc = test_dds_fmt[i]; + + hr = D3DX10CreateTextureFromMemory(device, &dds, sizeof(dds), &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + check_test_readback(&rb, expected_dst, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D10Resource_Release(resource); + winetest_pop_context(); + } + + CoUninitialize(); + ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); +} + #define check_rect(rect, left, top, right, bottom) _check_rect(__LINE__, rect, left, top, right, bottom) static inline void _check_rect(unsigned int line, const RECT *rect, int left, int top, int right, int bottom) { @@ -7090,4 +7175,5 @@ START_TEST(d3dx10) test_legacy_dds_header_image_info(); test_dxt10_dds_header_image_info(); test_image_filters(); + test_dxt_formats(); } diff --git a/dlls/d3dx11_43/tests/d3dx11.c b/dlls/d3dx11_43/tests/d3dx11.c index 4801506b039..b562b6265e1 100644 --- a/dlls/d3dx11_43/tests/d3dx11.c +++ b/dlls/d3dx11_43/tests/d3dx11.c @@ -4419,6 +4419,91 @@ static void test_image_filters(void) ok(!ID3D11Device_Release(device), "Unexpected refcount.\n"); } +/* + * DXT2 and DXT4 are decoded without taking premultiplied alpha + * into account on d3dx10/d3dx11. + */ +static void test_dxt_formats(void) +{ + static const uint8_t expected_dst[] = + { + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + }; + static const uint8_t test_dxt2_dxt3_data[] = + { + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const uint8_t test_dxt4_dxt5_data[] = + { + 0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const DWORD test_dds_fmt[] = + { + MAKEFOURCC('D','X','T','2'), MAKEFOURCC('D','X','T','3'), + MAKEFOURCC('D','X','T','4'), MAKEFOURCC('D','X','T','5'), + }; + struct + { + DWORD magic; + struct dds_header header; + BYTE data[256]; + } dds; + D3DX11_IMAGE_LOAD_INFO load_info; + struct resource_readback rb; + ID3D11Resource *resource; + ID3D11Device *device; + unsigned int i; + HRESULT hr; + + device = create_device(); + if (!device) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + CoInitialize(NULL); + + dds.magic = MAKEFOURCC('D','D','S',' '); + fill_dds_header(&dds.header); + dds.header.pixel_format.flags = DDS_PF_FOURCC; + dds.header.pixel_format.bpp = 0; + dds.header.pixel_format.rmask = 0; + dds.header.pixel_format.gmask = 0; + dds.header.pixel_format.bmask = 0; + dds.header.pixel_format.amask = 0; + + memset(dds.data, 0, sizeof(dds.data)); + load_info = d3dx11_default_load_info; + load_info.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + load_info.Filter = load_info.MipFilter = D3DX11_FILTER_NONE; + + for (i = 0; i < ARRAY_SIZE(test_dds_fmt); ++i) + { + winetest_push_context("Test %u (%s)", i, debugstr_fourcc(test_dds_fmt[i])); + if (i < 2) + memcpy(dds.data, test_dxt2_dxt3_data, sizeof(test_dxt2_dxt3_data)); + else + memcpy(dds.data, test_dxt4_dxt5_data, sizeof(test_dxt4_dxt5_data)); + dds.header.pixel_format.fourcc = test_dds_fmt[i]; + + hr = D3DX11CreateTextureFromMemory(device, &dds, sizeof(dds), &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + check_test_readback(&rb, expected_dst, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D11Resource_Release(resource); + winetest_pop_context(); + } + + CoUninitialize(); + ok(!ID3D11Device_Release(device), "Unexpected refcount.\n"); +} + static BOOL create_directory(const WCHAR *dir) { WCHAR path[MAX_PATH]; @@ -4591,4 +4676,5 @@ START_TEST(d3dx11) test_legacy_dds_header_image_info(); test_dxt10_dds_header_image_info(); test_image_filters(); + test_dxt_formats(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx9_36/d3dx_helpers.c | 91 +++++++++++++++++++++++++++++------ dlls/d3dx9_36/d3dx_helpers.h | 8 +++ dlls/d3dx9_36/tests/surface.c | 15 ++---- 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 4c0f49be1d4..7a4647c2385 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -53,6 +53,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); #define D3DX_FILTER_SRGB_OUT 0x00400000 #define D3DX_FILTER_SRGB 0x00600000 +/* These are custom Wine only filter flags. */ +#define D3DX_FILTER_PMA_IN 0x00800000 +#define D3DX_FILTER_PMA_OUT 0x01000000 +#define D3DX_FILTER_PMA 0x01800000 + #define D3DX_FILTER_INVALID_BITS 0xff80fff8 HRESULT d3dx_validate_filter(uint32_t filter) { @@ -62,6 +67,16 @@ HRESULT d3dx_validate_filter(uint32_t filter) return D3D_OK; } +static uint32_t d3dx_conv_flags_from_filter(uint32_t filter) +{ + uint32_t conv_flags = 0; + + if ((filter & D3DX_FILTER_PMA) && ((filter & D3DX_FILTER_PMA) != D3DX_FILTER_PMA)) + conv_flags |= (filter & D3DX_FILTER_PMA_IN) ? CONV_FLAG_PM_ALPHA_IN : CONV_FLAG_PM_ALPHA_OUT; + + return conv_flags; +} + HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); /************************************************************ @@ -100,9 +115,9 @@ static const struct pixel_format_desc formats[] = {D3DX_PIXEL_FORMAT_L8_UNORM, { 0, 8, 0, 0}, { 0, 0, 0, 0}, 1, 1, 1, 1, CTYPE_EMPTY, CTYPE_LUMA, 0 }, {D3DX_PIXEL_FORMAT_L16_UNORM, { 0, 16, 0, 0}, { 0, 0, 0, 0}, 2, 1, 1, 2, CTYPE_EMPTY, CTYPE_LUMA, 0 }, {D3DX_PIXEL_FORMAT_DXT1_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 8, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT}, - {D3DX_PIXEL_FORMAT_DXT2_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT}, + {D3DX_PIXEL_FORMAT_DXT2_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT|FMT_FLAG_PM_ALPHA}, {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_DXT4_UNORM, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 1, 4, 4, 16, CTYPE_UNORM, CTYPE_UNORM, FMT_FLAG_DXT|FMT_FLAG_PM_ALPHA}, {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}, @@ -1205,6 +1220,16 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src if ((image->format = d3dx_pixel_format_id_from_dds_pixel_format(&header->pixel_format)) == D3DX_PIXEL_FORMAT_COUNT) return D3DXERR_INVALIDDATA; + if (flags & D3DX_IMAGE_SUPPORT_DXT10 && (image->format == D3DX_PIXEL_FORMAT_DXT2_UNORM + || image->format == D3DX_PIXEL_FORMAT_DXT4_UNORM)) + { + TRACE("Loading a DXT%d texture on d3dx10+, ignoring premultiplied alpha.\n", + image->format == D3DX_PIXEL_FORMAT_DXT2_UNORM ? 2 : 4); + if (image->format == D3DX_PIXEL_FORMAT_DXT2_UNORM) + image->format = D3DX_PIXEL_FORMAT_DXT3_UNORM; + else + image->format = D3DX_PIXEL_FORMAT_DXT5_UNORM; + } image->image_file_format = D3DX_IMAGE_FILE_FORMAT_DDS; image->layer_count = 1; @@ -1632,7 +1657,7 @@ struct d3dx_color_key; static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, const struct d3dx_color_key *color_key, - const PALETTEENTRY *palette); + const PALETTEENTRY *palette, uint32_t conv_flags); static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_size, uint32_t src_header_size, struct d3dx_image *image) @@ -1678,7 +1703,7 @@ static HRESULT d3dx_image_tga_decode(const void *src_data, uint32_t src_data_siz dst_desc = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM); d3dx_calculate_pixels_size(dst_desc->format, 256, 1, &dst_row_pitch, &dst_slice_pitch); convert_argb_pixels(src_palette, src_row_pitch, src_slice_pitch, &image_map_size, src_desc, (BYTE *)palette, - dst_row_pitch, dst_slice_pitch, &image_map_size, dst_desc, NULL, NULL); + dst_row_pitch, dst_slice_pitch, &image_map_size, dst_desc, NULL, NULL, 0); /* Initialize unused palette entries to 0xff. */ if (header->color_map_length < 256) @@ -2429,14 +2454,29 @@ static void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitc } } +static void premultiply_alpha(struct vec4 *vec) +{ + vec->x *= vec->w; + vec->y *= vec->w; + vec->z *= vec->w; +} + +static void undo_premultiplied_alpha(struct vec4 *vec) +{ + vec->x = (vec->w == 0.0f) ? 0.0f : vec->x / vec->w; + vec->y = (vec->w == 0.0f) ? 0.0f : vec->y / vec->w; + vec->z = (vec->w == 0.0f) ? 0.0f : vec->z / vec->w; +} + static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format_desc *src_fmt, uint8_t *dst_ptr, const struct pixel_format_desc *dst_fmt, const PALETTEENTRY *palette, struct argb_conversion_info *conv_info, const struct d3dx_color_key *color_key, - const struct pixel_format_desc *ck_format, struct argb_conversion_info *ck_conv_info) + const struct pixel_format_desc *ck_format, struct argb_conversion_info *ck_conv_info, uint32_t conv_flags) { unsigned int i; - if (format_types_match(src_fmt, dst_fmt) && src_fmt->bytes_per_pixel <= 4 && dst_fmt->bytes_per_pixel <= 4) + if (format_types_match(src_fmt, dst_fmt) && src_fmt->bytes_per_pixel <= 4 && dst_fmt->bytes_per_pixel <= 4 + && !conv_flags) { DWORD channels[4]; DWORD val; @@ -2467,6 +2507,8 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format struct d3dx_color color, tmp; format_to_d3dx_color(src_fmt, src_ptr, palette, &color); + if (conv_flags & CONV_FLAG_PM_ALPHA_IN) + undo_premultiplied_alpha(&color.value); tmp = color; if (color_key) @@ -2486,6 +2528,8 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format } color = tmp; + if (conv_flags & CONV_FLAG_PM_ALPHA_OUT) + premultiply_alpha(&color.value); format_from_d3dx_color(dst_fmt, &color, dst_ptr); } } @@ -2500,7 +2544,7 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, const struct d3dx_color_key *color_key, - const PALETTEENTRY *palette) + const PALETTEENTRY *palette, uint32_t conv_flags) { /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ const struct pixel_format_desc *ck_format = color_key ? get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM) : NULL; @@ -2532,7 +2576,7 @@ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_sl for (x = 0; x < min_width; x++) { convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, - &conv_info, color_key, ck_format, &ck_conv_info); + &conv_info, color_key, ck_format, &ck_conv_info, conv_flags); src_ptr += src_format->bytes_per_pixel; dst_ptr += dst_format->bytes_per_pixel; @@ -2559,7 +2603,7 @@ static void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_sl static void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, - const struct d3dx_color_key *color_key, const PALETTEENTRY *palette) + const struct d3dx_color_key *color_key, const PALETTEENTRY *palette, uint32_t conv_flags) { /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ const struct pixel_format_desc *ck_format = color_key ? get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM) : NULL; @@ -2591,7 +2635,7 @@ static void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT s const BYTE *src_ptr = src_row_ptr + (x * src_size->width / dst_size->width) * src_format->bytes_per_pixel; convert_argb_pixel(src_ptr, src_format, dst_ptr, dst_format, palette, - &conv_info, color_key, ck_format, &ck_conv_info); + &conv_info, color_key, ck_format, &ck_conv_info, conv_flags); dst_ptr += dst_format->bytes_per_pixel; } } @@ -2640,7 +2684,7 @@ static inline void vec4_scale(struct vec4 *out, const float scale) static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, const struct volume *src_size, const struct pixel_format_desc *src_format, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size, const struct pixel_format_desc *dst_format, - const struct d3dx_color_key *color_key, const PALETTEENTRY *palette) + const struct d3dx_color_key *color_key, const PALETTEENTRY *palette, uint32_t conv_flags) { /* Color keys are always represented in D3DFMT_A8R8G8B8 format. */ const struct pixel_format_desc *ck_format = color_key ? get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM) : NULL; @@ -2681,28 +2725,38 @@ static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src const BYTE *ptr = src_ptr + i * src_slice_pitch; format_to_d3dx_color(src_format, ptr, palette, &tmp); + if (conv_flags & CONV_FLAG_PM_ALPHA_IN) + undo_premultiplied_alpha(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); format_to_d3dx_color(src_format, ptr + src_format->bytes_per_pixel, palette, &tmp); + if (conv_flags & CONV_FLAG_PM_ALPHA_IN) + undo_premultiplied_alpha(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); ptr += src_row_pitch; format_to_d3dx_color(src_format, ptr, palette, &tmp); + if (conv_flags & CONV_FLAG_PM_ALPHA_IN) + undo_premultiplied_alpha(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); format_to_d3dx_color(src_format, ptr + src_format->bytes_per_pixel, palette, &tmp); + if (conv_flags & CONV_FLAG_PM_ALPHA_IN) + undo_premultiplied_alpha(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); } vec4_scale(&color.value, src_size->depth > 1 ? 0.125f : 0.25f); + if (conv_flags & CONV_FLAG_PM_ALPHA_OUT) + premultiply_alpha(&color.value); format_from_d3dx_color(dst_format, &color, dst_ptr); dst_ptr += dst_format->bytes_per_pixel; } @@ -3125,12 +3179,20 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, struct volume src_size, dst_size, dst_size_aligned; const struct d3dx_color_key *d3dx_ck = NULL; struct d3dx_color_key d3dx_color_key; + uint32_t conv_flags; HRESULT hr = S_OK; TRACE("dst_pixels %s, dst_desc %p, src_pixels %s, src_desc %p, filter_flags %#x, color_key %#x.\n", debug_d3dx_pixels(dst_pixels), dst_desc, debug_d3dx_pixels(src_pixels), src_desc, filter_flags, color_key); + if (src_desc->flags & FMT_FLAG_PM_ALPHA) + filter_flags |= D3DX_FILTER_PMA_IN; + + if (dst_desc->flags & FMT_FLAG_PM_ALPHA) + filter_flags |= D3DX_FILTER_PMA_OUT; + + conv_flags = d3dx_conv_flags_from_filter(filter_flags); if (is_compressed_format(src_desc)) set_volume_struct(&src_size, (src_pixels->unaligned_rect.right - src_pixels->unaligned_rect.left), (src_pixels->unaligned_rect.bottom - src_pixels->unaligned_rect.top), src_pixels->size.depth); @@ -3150,6 +3212,7 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, && (dst_size.height == src_size.height && !(dst_size.height % dst_desc->block_height)) && (dst_size.depth == src_size.depth) && color_key == 0 + && !conv_flags && !(src_pixels->unaligned_rect.left & (src_desc->block_width - 1)) && !(src_pixels->unaligned_rect.top & (src_desc->block_height - 1)) && !(dst_pixels->unaligned_rect.left & (dst_desc->block_width - 1)) @@ -3280,13 +3343,13 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, { convert_argb_pixels(src_pixels->data, src_pixels->row_pitch, src_pixels->slice_pitch, &src_size, src_desc, (BYTE *)dst_pixels->data, dst_pixels->row_pitch, dst_pixels->slice_pitch, &dst_size, dst_desc, - d3dx_ck, src_pixels->palette); + d3dx_ck, src_pixels->palette, conv_flags); } else if ((filter_flags & 0xf) == D3DX_FILTER_BOX) { box_filter_argb_pixels(src_pixels->data, src_pixels->row_pitch, src_pixels->slice_pitch, &src_size, src_desc, (BYTE *)dst_pixels->data, dst_pixels->row_pitch, dst_pixels->slice_pitch, &dst_size, - dst_desc, d3dx_ck, src_pixels->palette); + dst_desc, d3dx_ck, src_pixels->palette, conv_flags); } else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ { @@ -3297,7 +3360,7 @@ HRESULT d3dx_load_pixels_from_pixels(struct d3dx_pixels *dst_pixels, * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ point_filter_argb_pixels(src_pixels->data, src_pixels->row_pitch, src_pixels->slice_pitch, &src_size, src_desc, (BYTE *)dst_pixels->data, dst_pixels->row_pitch, dst_pixels->slice_pitch, &dst_size, - dst_desc, d3dx_ck, src_pixels->palette); + dst_desc, d3dx_ck, src_pixels->palette, conv_flags); } exit: diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 9b85149cbaa..5b65f52cfa3 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -242,6 +242,12 @@ enum d3dx_pixel_format_id #define D3DX_PIXEL_FORMAT_BC3_UNORM D3DX_PIXEL_FORMAT_DXT5_UNORM /* for internal use */ +enum conversion_flag +{ + CONV_FLAG_PM_ALPHA_IN = 0x01, + CONV_FLAG_PM_ALPHA_OUT = 0x02, +}; + enum component_type { CTYPE_EMPTY, @@ -264,6 +270,8 @@ enum format_flag * equivalent. */ FMT_FLAG_DXGI = 0x08, + /* Formats with premultiplied alpha, i.e DXT2/DXT4. */ + FMT_FLAG_PM_ALPHA = 0x10, }; struct pixel_format_desc { diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index c72c4a01877..1f2596e1cac 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1326,7 +1326,7 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) { const uint32_t expected_pixel = !(x & 0x01) ? 0xffffffff : 0x00000000; - check_readback_pixel_4bpp(&surface_rb, x, y, expected_pixel, !expected_pixel); + check_readback_pixel_4bpp(&surface_rb, x, y, expected_pixel, FALSE); } } release_surface_readback(&surface_rb); @@ -1348,17 +1348,10 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) */ hr = D3DXLoadSurfaceFromMemory(decomp_surf, NULL, NULL, tests[i].dxt_block, tests[i].pma_fmt, 16, NULL, &src_rect, D3DX_FILTER_NONE, 0); ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); - IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); - for (y = 0; y < 4; ++y) - { - for (x = 0; x < 4; ++x) - { - const uint32_t expected_pixel = dxt_pma_decompressed_expected[(y * 4) + x]; - const BOOL todo = ((expected_pixel >> 24) & 0xff) != 0xff; - todo_wine_if(todo) check_pixel_4bpp(&lock_rect, x, y, expected_pixel); - } - } + IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + check_test_readback(lock_rect.pBits, lock_rect.Pitch, lock_rect.Pitch * 4, dxt_pma_decompressed_expected, 4, 4, + 1, D3DFMT_A8B8G8R8, 1); IDirect3DSurface9_UnlockRect(decomp_surf); /* -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 47 +++++++++++++++++++++++++++++++---- dlls/d3dx11_43/tests/d3dx11.c | 47 +++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 91778dc5a0f..3ff2cab533e 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -806,6 +806,25 @@ static const uint8_t dds_cube_map_4_4[] = 0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00, }; +/* 4x4 DXT10 DDS file with a format of DXGI_FORMAT_R8G8B8A8_UNORM. */ +static const uint8_t dds_dxt10_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,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, + 0x04,0x00,0x00,0x00,0x44,0x58,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x20,0x20,0x20,0x20, + 0x30,0x30,0x30,0x30,0x40,0x40,0x40,0x40,0x50,0x50,0x50,0x50,0x60,0x60,0x60,0x60, + 0x70,0x70,0x70,0x70,0x80,0x80,0x80,0x80,0x90,0x90,0x90,0x90,0xa0,0xa0,0xa0,0xa0, + 0xb0,0xb0,0xb0,0xb0,0xc0,0xc0,0xc0,0xc0,0xd0,0xd0,0xd0,0xd0,0xe0,0xe0,0xe0,0xe0, + 0xf0,0xf0,0xf0,0xf0, +}; + /* 1x1 wmp image */ static const uint8_t test_wmp[] = { @@ -1826,6 +1845,24 @@ static const struct test_image_load_info } } }, + /* + * Pass in invalid filter flags. Ignored if the dimensions and format of the + * destination texture match the source image. + */ + { + dds_dxt10_4_4, sizeof(dds_dxt10_4_4), + { + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 1, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT + }, + S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE2D, + { + .desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0 + } + } + }, }; static const struct test_invalid_image_load_info @@ -5044,7 +5081,7 @@ static void test_create_texture(void) 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); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5245,7 +5282,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5255,7 +5292,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5366,7 +5403,7 @@ static void test_create_texture(void) hr = D3DX10CreateTextureFromResourceW(device, resource_module, test_resource_name, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5377,7 +5414,7 @@ static void test_create_texture(void) hr = D3DX10CreateTextureFromResourceA(device, resource_module, get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); diff --git a/dlls/d3dx11_43/tests/d3dx11.c b/dlls/d3dx11_43/tests/d3dx11.c index b562b6265e1..a5632c72a39 100644 --- a/dlls/d3dx11_43/tests/d3dx11.c +++ b/dlls/d3dx11_43/tests/d3dx11.c @@ -806,6 +806,25 @@ static const uint8_t dds_cube_map_4_4[] = 0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00, }; +/* 4x4 DXT10 DDS file with a format of DXGI_FORMAT_R8G8B8A8_UNORM. */ +static const uint8_t dds_dxt10_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,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, + 0x04,0x00,0x00,0x00,0x44,0x58,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x1c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x20,0x20,0x20,0x20, + 0x30,0x30,0x30,0x30,0x40,0x40,0x40,0x40,0x50,0x50,0x50,0x50,0x60,0x60,0x60,0x60, + 0x70,0x70,0x70,0x70,0x80,0x80,0x80,0x80,0x90,0x90,0x90,0x90,0xa0,0xa0,0xa0,0xa0, + 0xb0,0xb0,0xb0,0xb0,0xc0,0xc0,0xc0,0xc0,0xd0,0xd0,0xd0,0xd0,0xe0,0xe0,0xe0,0xe0, + 0xf0,0xf0,0xf0,0xf0, +}; + /* 1x1 wmp image */ static const uint8_t test_wmp[] = { @@ -1798,6 +1817,24 @@ static const struct test_image_load_info } } }, + /* + * Pass in invalid filter flags. Ignored if the dimensions and format of the + * destination texture match the source image. + */ + { + dds_dxt10_4_4, sizeof(dds_dxt10_4_4), + { + D3DX11_DEFAULT, D3DX11_DEFAULT, D3DX11_DEFAULT, D3DX11_DEFAULT, 1, (D3D11_USAGE)D3DX11_DEFAULT, + D3DX11_DEFAULT, D3DX11_DEFAULT, D3DX11_DEFAULT, D3DX11_DEFAULT, 7, D3DX11_DEFAULT + }, + S_OK, D3D11_RESOURCE_DIMENSION_TEXTURE2D, + { + .desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0 + } + } + }, }; static const struct test_invalid_image_load_info @@ -3868,7 +3905,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromMemory(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); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4063,7 +4100,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4073,7 +4110,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4184,7 +4221,7 @@ static void test_create_texture(void) hr = D3DX11CreateTextureFromResourceW(device, resource_module, test_resource_name, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4195,7 +4232,7 @@ static void test_create_texture(void) hr = D3DX11CreateTextureFromResourceA(device, resource_module, get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 10 +++++----- dlls/d3dx10_43/texture.c | 25 +++++++++++++++++-------- dlls/d3dx11_43/tests/d3dx11.c | 10 +++++----- dlls/d3dx11_43/texture.c | 25 +++++++++++++++++-------- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 3ff2cab533e..ae5ed384ba6 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -5081,7 +5081,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromMemory(device, test->data, test->size, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5282,7 +5282,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5292,7 +5292,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5403,7 +5403,7 @@ static void test_create_texture(void) 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(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -5414,7 +5414,7 @@ static void test_create_texture(void) 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(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index aa173e3f004..bb312ae42ff 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -649,14 +649,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO return E_FAIL; *resource_data = NULL; - if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT) - load_info->Filter = D3DX10_FILTER_LINEAR; - if (FAILED(hr = d3dx_validate_filter(load_info->Filter))) - { - WARN("Invalid filter argument %#x.\n", load_info->Filter); - return hr; - } - hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10); if (FAILED(hr)) return E_FAIL; @@ -710,6 +702,23 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO load_info->MipLevels = (load_info->MipLevels == D3DX10_FROM_FILE) ? img_info.MipLevels : max_mip_level_count; load_info->MipLevels = min(max_mip_level_count, load_info->MipLevels); + if ((load_info->Width != image.size.width) || (load_info->Height != image.size.height) + || (load_info->Depth != image.size.depth) || (load_info->MipLevels != image.mip_levels) + || (fmt_desc->format != image.format)) + { + if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT) + load_info->Filter = D3DX10_FILTER_LINEAR; + if (FAILED(hr = d3dx_validate_filter(load_info->Filter))) + { + WARN("Invalid filter argument %#x.\n", load_info->Filter); + goto end; + } + } + else + { + load_info->Filter = D3DX10_FILTER_NONE; + } + hr = d3dx_create_subresource_data_for_texture(load_info->Width, load_info->Height, load_info->Depth, load_info->MipLevels, img_info.ArraySize, fmt_desc, &sub_rsrcs); if (FAILED(hr)) diff --git a/dlls/d3dx11_43/tests/d3dx11.c b/dlls/d3dx11_43/tests/d3dx11.c index a5632c72a39..adf3ca79511 100644 --- a/dlls/d3dx11_43/tests/d3dx11.c +++ b/dlls/d3dx11_43/tests/d3dx11.c @@ -3905,7 +3905,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromMemory(device, test->data, test->size, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4100,7 +4100,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4110,7 +4110,7 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX11CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4221,7 +4221,7 @@ static void test_create_texture(void) hr = D3DX11CreateTextureFromResourceW(device, resource_module, test_resource_name, &load_info, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); @@ -4232,7 +4232,7 @@ static void test_create_texture(void) hr = D3DX11CreateTextureFromResourceA(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(i == 2) ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); + ok(hr == test->expected_hr, "Got unexpected hr %#lx.\n", hr); if (SUCCEEDED(hr)) { check_test_image_load_info_resource(resource, test); diff --git a/dlls/d3dx11_43/texture.c b/dlls/d3dx11_43/texture.c index e3218e3ec04..21f5b008964 100644 --- a/dlls/d3dx11_43/texture.c +++ b/dlls/d3dx11_43/texture.c @@ -384,14 +384,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX11_IMAGE_LOAD_INFO return E_FAIL; *resource_data = NULL; - if (!load_info->Filter || load_info->Filter == D3DX11_DEFAULT) - load_info->Filter = D3DX11_FILTER_LINEAR; - if (FAILED(hr = d3dx_validate_filter(load_info->Filter))) - { - WARN("Invalid filter argument %#x.\n", load_info->Filter); - return hr; - } - hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10); if (FAILED(hr)) return E_FAIL; @@ -445,6 +437,23 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX11_IMAGE_LOAD_INFO load_info->MipLevels = (load_info->MipLevels == D3DX11_FROM_FILE) ? img_info.MipLevels : max_mip_level_count; load_info->MipLevels = min(max_mip_level_count, load_info->MipLevels); + if ((load_info->Width != image.size.width) || (load_info->Height != image.size.height) + || (load_info->Depth != image.size.depth) || (load_info->MipLevels != image.mip_levels) + || (fmt_desc->format != image.format)) + { + if (!load_info->Filter || load_info->Filter == D3DX11_DEFAULT) + load_info->Filter = D3DX11_FILTER_LINEAR; + if (FAILED(hr = d3dx_validate_filter(load_info->Filter))) + { + WARN("Invalid filter argument %#x.\n", load_info->Filter); + goto end; + } + } + else + { + load_info->Filter = D3DX11_FILTER_NONE; + } + hr = d3dx_create_subresource_data_for_texture(load_info->Width, load_info->Height, load_info->Depth, load_info->MipLevels, img_info.ArraySize, fmt_desc, &sub_rsrcs); if (FAILED(hr)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx9_36/tests/surface.c | 134 +++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 1f2596e1cac..d3ff833f494 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1252,6 +1252,28 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) { 0x22,0xcc,0x86,0xc6,0xe6,0x86,0xc6,0xe6,0x10,0x84,0x10,0x84,0x00,0x00,0x00,0x00, }; + static const uint8_t dxt2_block_srgb[] = + { + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const uint8_t dxt4_block_srgb[] = + { + 0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x31,0x04,0x21,0x11,0x11,0x11,0x11, + }; + static const uint8_t dxt_srgb_in_expected[] = + { + 0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88,0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88, + 0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88,0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88, + 0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88,0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88, + 0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88,0x0b,0x0b,0x0b,0x88,0x1b,0x1a,0x1b,0x88, + }; + static const uint8_t dxt_srgb_out_expected[] = + { + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + 0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88,0x21,0x20,0x21,0x88,0x31,0x31,0x31,0x88, + }; static const uint32_t test_compress_pixels[] = { 0xffffffff, 0x00ffffff, 0xffffffff, 0x00ffffff, 0xffffffff, 0x00ffffff, 0xffffffff, 0x00ffffff, @@ -1269,9 +1291,10 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) { D3DFMT_DXT4, D3DFMT_DXT5, dxt5_block, "DXT4 / DXT5" }, }; static const RECT src_rect = { 0, 0, 4, 4 }; - IDirect3DSurface9 *decomp_surf; + IDirect3DSurface9 *decomp_surf, *comp_surf; D3DLOCKED_RECT lock_rect; uint32_t i, x, y; + uint8_t tmp[16]; HRESULT hr; hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &decomp_surf, NULL); @@ -1374,6 +1397,71 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) IDirect3DTexture9_Release(tex); winetest_pop_context(); } + + /* + * DXT2/DXT4 combined with SRGB filter flags. Premultiplied alpha is + * undone prior to undoing the SRGB conversion, and vice versa. + */ + hr = D3DXLoadSurfaceFromMemory(decomp_surf, NULL, NULL, dxt2_block_srgb, D3DFMT_DXT2, 16, NULL, &src_rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_IN, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); + IDirect3DSurface9_UnlockRect(decomp_surf); + + /* DXT4, SRGB in. */ + hr = D3DXLoadSurfaceFromMemory(decomp_surf, NULL, NULL, dxt4_block_srgb, D3DFMT_DXT4, 16, NULL, &src_rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_IN, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); + IDirect3DSurface9_UnlockRect(decomp_surf); + + /* + * DXT2, SRGB out. SRGB conversion is done first, and then premultiplied + * by alpha. + */ + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT2, D3DPOOL_SCRATCH, &comp_surf, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXLoadSurfaceFromMemory(comp_surf, NULL, NULL, dxt_srgb_in_expected, D3DFMT_A8R8G8B8, 16, NULL, &src_rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_OUT, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(comp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + memcpy(tmp, lock_rect.pBits, 16); + IDirect3DSurface9_UnlockRect(comp_surf); + IDirect3DSurface9_Release(comp_surf); + + hr = D3DXLoadSurfaceFromMemory(decomp_surf, NULL, NULL, tmp, D3DFMT_DXT3, 16, NULL, &src_rect, D3DX_FILTER_NONE, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); + IDirect3DSurface9_UnlockRect(decomp_surf); + + /* DXT4, SRGB out. */ + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_DXT4, D3DPOOL_SCRATCH, &comp_surf, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXLoadSurfaceFromMemory(comp_surf, NULL, NULL, dxt_srgb_in_expected, D3DFMT_A8R8G8B8, 16, NULL, &src_rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_OUT, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(comp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + memcpy(tmp, lock_rect.pBits, 16); + IDirect3DSurface9_UnlockRect(comp_surf); + IDirect3DSurface9_Release(comp_surf); + + hr = D3DXLoadSurfaceFromMemory(decomp_surf, NULL, NULL, tmp, D3DFMT_DXT5, 16, NULL, &src_rect, D3DX_FILTER_NONE, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); + todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); + IDirect3DSurface9_UnlockRect(decomp_surf); + IDirect3DSurface9_Release(decomp_surf); } @@ -2901,6 +2989,50 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DSurface9_UnlockRect(surf); ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); + /* Test SRGB filter flags. */ + SetRect(&rect, 0, 0, 2, 2); + hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r8g8b8, D3DFMT_A8R8G8B8, 8, NULL, &rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_IN, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* SRGB in, no SRGB out. */ + hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); + ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr); + todo_wine check_pixel_4bpp(&lockrect, 0, 0, 0x00010306); + todo_wine check_pixel_4bpp(&lockrect, 1, 0, 0x40141e2a); + todo_wine check_pixel_4bpp(&lockrect, 0, 1, 0x80495b71); + todo_wine check_pixel_4bpp(&lockrect, 1, 1, 0xc0a3c0ff); + hr = IDirect3DSurface9_UnlockRect(surf); + ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); + + hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r8g8b8, D3DFMT_A8R8G8B8, 8, NULL, &rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_OUT, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* No SRGB in, SRGB out. */ + hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); + ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr); + todo_wine check_pixel_4bpp(&lockrect, 0, 0, 0x00486377); + todo_wine check_pixel_4bpp(&lockrect, 1, 0, 0x4097a4af); + todo_wine check_pixel_4bpp(&lockrect, 0, 1, 0x80c5ced7); + todo_wine check_pixel_4bpp(&lockrect, 1, 1, 0xc0e8f0ff); + hr = IDirect3DSurface9_UnlockRect(surf); + ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); + + hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r8g8b8, D3DFMT_A8R8G8B8, 8, NULL, &rect, + D3DX_FILTER_NONE | D3DX_FILTER_SRGB_IN | D3DX_FILTER_SRGB_OUT, 0); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* SRGB in, SRGB out, no changes. */ + hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); + ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr); + check_pixel_4bpp(&lockrect, 0, 0, pixdata_a8r8g8b8[0]); + check_pixel_4bpp(&lockrect, 1, 0, pixdata_a8r8g8b8[1]); + check_pixel_4bpp(&lockrect, 0, 1, pixdata_a8r8g8b8[2]); + check_pixel_4bpp(&lockrect, 1, 1, pixdata_a8r8g8b8[3]); + hr = IDirect3DSurface9_UnlockRect(surf); + ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); + /* Test D3DXLoadSurfaceFromMemory with indexed color image */ if (0) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 59 ++++++++++++++++++++++++++++++++++- dlls/d3dx11_43/tests/d3dx11.c | 59 ++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index ae5ed384ba6..d72ff411e04 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -5432,6 +5432,20 @@ static void test_create_texture(void) static void test_image_filters(void) { + static const uint8_t a8r8g8b8_4_4_srgb_in_expected[] = + { + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x10,0x03,0x03,0x03,0x20,0x06,0x06,0x06,0x30, + 0x0c,0x0c,0x0c,0x40,0x14,0x14,0x14,0x50,0x1e,0x1e,0x1e,0x60,0x2a,0x2a,0x2a,0x70, + 0x38,0x38,0x38,0x80,0x49,0x49,0x49,0x90,0x5b,0x5b,0x5b,0xa0,0x71,0x71,0x71,0xb0, + 0x89,0x89,0x89,0xc0,0xa3,0xa3,0xa3,0xd0,0xc0,0xc0,0xc0,0xe0,0xdf,0xdf,0xdf,0xf0, + }; + static const uint8_t a8r8g8b8_4_4_srgb_out_expected[] = + { + 0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x10,0x63,0x63,0x63,0x20,0x77,0x77,0x77,0x30, + 0x88,0x88,0x88,0x40,0x97,0x97,0x97,0x50,0xa4,0xa4,0xa4,0x60,0xaf,0xaf,0xaf,0x70, + 0xba,0xba,0xba,0x80,0xc5,0xc5,0xc5,0x90,0xce,0xce,0xce,0xa0,0xd7,0xd7,0xd7,0xb0, + 0xe0,0xe0,0xe0,0xc0,0xe8,0xe8,0xe8,0xd0,0xf0,0xf0,0xf0,0xe0,0xf8,0xf8,0xf8,0xf0, + }; static const struct { DWORD filter; @@ -5566,6 +5580,7 @@ static void test_image_filters(void) const uint8_t *expected_dst; struct resource_readback rb; ID3D10Resource *resource; + unsigned int dds_size; ID3D10Device *device; uint32_t src_pitch; unsigned int i, j; @@ -5584,10 +5599,10 @@ static void test_image_filters(void) for (i = 0; i < ARRAY_SIZE(tests); ++i) { const unsigned int fmt_bpp = (get_bpp_from_format(tests[i].format) + 7) / 8; - unsigned int dds_size = sizeof(dds); winetest_push_context("Test %u", i); + dds_size = sizeof(dds); load_info = d3dx10_default_load_info; load_info.Width = tests[i].dst_width; load_info.Height = tests[i].dst_height; @@ -5634,6 +5649,48 @@ static void test_image_filters(void) winetest_pop_context(); } + /* + * Create a 5x4 DXT10 DDS file to test SRGB filter flags. If we did a 4x4 + * image with our 4x4 output texture the filter flags would be ignored. + */ + dds.magic = MAKEFOURCC('D','D','S',' '); + set_dxt10_dds_header(&dds.header, 0, 5, 4, 0, 1, 4 * 5, 0, 0); + set_dds_header_dxt10(&dds.dxt10, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0); + memset(dds.data, 0, sizeof(dds.data)); + for (i = 0; i < 4; i++) + { + BYTE *dst = &dds.data[i * dds.header.pitch_or_linear_size]; + + memcpy(dst, &a8r8g8b8_4_4[i * 4 * 4], 4 * 4); + } + dds_size = (sizeof(dds) - sizeof(dds.data)) + dds.header.pitch_or_linear_size * dds.header.height; + + /* Test conversion from SRGB to non-SRGB. */ + load_info = d3dx10_default_load_info; + load_info.Filter = D3DX10_FILTER_NONE | D3DX10_FILTER_SRGB_IN; + load_info.Width = load_info.Height = 4; + load_info.MipLevels = 1; + hr = D3DX10CreateTextureFromMemory(device, &dds, dds_size, &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D10Resource_Release(resource); + + /* Test conversion from non-SRGB to SRGB. */ + load_info = d3dx10_default_load_info; + load_info.Filter = D3DX10_FILTER_NONE | D3DX10_FILTER_SRGB_OUT; + load_info.Width = load_info.Height = 4; + load_info.MipLevels = 1; + hr = D3DX10CreateTextureFromMemory(device, &dds, dds_size, &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D10Resource_Release(resource); + CoUninitialize(); ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); } diff --git a/dlls/d3dx11_43/tests/d3dx11.c b/dlls/d3dx11_43/tests/d3dx11.c index adf3ca79511..d94dedfef04 100644 --- a/dlls/d3dx11_43/tests/d3dx11.c +++ b/dlls/d3dx11_43/tests/d3dx11.c @@ -4250,6 +4250,20 @@ static void test_create_texture(void) static void test_image_filters(void) { + static const uint8_t a8r8g8b8_4_4_srgb_in_expected[] = + { + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x10,0x03,0x03,0x03,0x20,0x06,0x06,0x06,0x30, + 0x0c,0x0c,0x0c,0x40,0x14,0x14,0x14,0x50,0x1e,0x1e,0x1e,0x60,0x2a,0x2a,0x2a,0x70, + 0x38,0x38,0x38,0x80,0x49,0x49,0x49,0x90,0x5b,0x5b,0x5b,0xa0,0x71,0x71,0x71,0xb0, + 0x89,0x89,0x89,0xc0,0xa3,0xa3,0xa3,0xd0,0xc0,0xc0,0xc0,0xe0,0xdf,0xdf,0xdf,0xf0, + }; + static const uint8_t a8r8g8b8_4_4_srgb_out_expected[] = + { + 0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x10,0x63,0x63,0x63,0x20,0x77,0x77,0x77,0x30, + 0x88,0x88,0x88,0x40,0x97,0x97,0x97,0x50,0xa4,0xa4,0xa4,0x60,0xaf,0xaf,0xaf,0x70, + 0xba,0xba,0xba,0x80,0xc5,0xc5,0xc5,0x90,0xce,0xce,0xce,0xa0,0xd7,0xd7,0xd7,0xb0, + 0xe0,0xe0,0xe0,0xc0,0xe8,0xe8,0xe8,0xd0,0xf0,0xf0,0xf0,0xe0,0xf8,0xf8,0xf8,0xf0, + }; static const struct { DWORD filter; @@ -4384,6 +4398,7 @@ static void test_image_filters(void) const uint8_t *expected_dst; struct resource_readback rb; ID3D11Resource *resource; + unsigned int dds_size; ID3D11Device *device; uint32_t src_pitch; unsigned int i, j; @@ -4402,10 +4417,10 @@ static void test_image_filters(void) for (i = 0; i < ARRAY_SIZE(tests); ++i) { const unsigned int fmt_bpp = (get_bpp_from_format(tests[i].format) + 7) / 8; - unsigned int dds_size = sizeof(dds); winetest_push_context("Test %u", i); + dds_size = sizeof(dds); load_info = d3dx11_default_load_info; load_info.Width = tests[i].dst_width; load_info.Height = tests[i].dst_height; @@ -4452,6 +4467,48 @@ static void test_image_filters(void) winetest_pop_context(); } + /* + * Create a 5x4 DXT10 DDS file to test SRGB filter flags. If we did a 4x4 + * image with our 4x4 output texture the filter flags would be ignored. + */ + dds.magic = MAKEFOURCC('D','D','S',' '); + set_dxt10_dds_header(&dds.header, 0, 5, 4, 0, 1, 4 * 5, 0, 0); + set_dds_header_dxt10(&dds.dxt10, DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, 1, 0); + memset(dds.data, 0, sizeof(dds.data)); + for (i = 0; i < 4; i++) + { + BYTE *dst = &dds.data[i * dds.header.pitch_or_linear_size]; + + memcpy(dst, &a8r8g8b8_4_4[i * 4 * 4], 4 * 4); + } + dds_size = (sizeof(dds) - sizeof(dds.data)) + dds.header.pitch_or_linear_size * dds.header.height; + + /* Test conversion from SRGB to non-SRGB. */ + load_info = d3dx11_default_load_info; + load_info.Filter = D3DX11_FILTER_NONE | D3DX11_FILTER_SRGB_IN; + load_info.Width = load_info.Height = 4; + load_info.MipLevels = 1; + hr = D3DX11CreateTextureFromMemory(device, &dds, dds_size, &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D11Resource_Release(resource); + + /* Test conversion from non-SRGB to SRGB. */ + load_info = d3dx11_default_load_info; + load_info.Filter = D3DX11_FILTER_NONE | D3DX11_FILTER_SRGB_OUT; + load_info.Width = load_info.Height = 4; + load_info.MipLevels = 1; + hr = D3DX11CreateTextureFromMemory(device, &dds, dds_size, &load_info, NULL, &resource, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + get_resource_readback(resource, 0, &rb); + todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + release_resource_readback(&rb); + ID3D11Resource_Release(resource); + CoUninitialize(); ok(!ID3D11Device_Release(device), "Unexpected refcount.\n"); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 4 ++-- dlls/d3dx11_43/tests/d3dx11.c | 4 ++-- dlls/d3dx9_36/d3dx_helpers.c | 30 ++++++++++++++++++++++++++++++ dlls/d3dx9_36/d3dx_helpers.h | 2 ++ dlls/d3dx9_36/tests/surface.c | 24 ++++++++++++------------ 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index d72ff411e04..1bd2388c3d7 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -5674,7 +5674,7 @@ static void test_image_filters(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); get_resource_readback(resource, 0, &rb); - todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); release_resource_readback(&rb); ID3D10Resource_Release(resource); @@ -5687,7 +5687,7 @@ static void test_image_filters(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); get_resource_readback(resource, 0, &rb); - todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); release_resource_readback(&rb); ID3D10Resource_Release(resource); diff --git a/dlls/d3dx11_43/tests/d3dx11.c b/dlls/d3dx11_43/tests/d3dx11.c index d94dedfef04..b396c3fb452 100644 --- a/dlls/d3dx11_43/tests/d3dx11.c +++ b/dlls/d3dx11_43/tests/d3dx11.c @@ -4492,7 +4492,7 @@ static void test_image_filters(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); get_resource_readback(resource, 0, &rb); - todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + check_test_readback(&rb, a8r8g8b8_4_4_srgb_in_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); release_resource_readback(&rb); ID3D11Resource_Release(resource); @@ -4505,7 +4505,7 @@ static void test_image_filters(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); get_resource_readback(resource, 0, &rb); - todo_wine check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + check_test_readback(&rb, a8r8g8b8_4_4_srgb_out_expected, 4, 4, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0); release_resource_readback(&rb); ID3D11Resource_Release(resource); diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 7a4647c2385..4b3ef05c408 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -73,6 +73,8 @@ static uint32_t d3dx_conv_flags_from_filter(uint32_t filter) if ((filter & D3DX_FILTER_PMA) && ((filter & D3DX_FILTER_PMA) != D3DX_FILTER_PMA)) conv_flags |= (filter & D3DX_FILTER_PMA_IN) ? CONV_FLAG_PM_ALPHA_IN : CONV_FLAG_PM_ALPHA_OUT; + if ((filter & D3DX_FILTER_SRGB) && ((filter & D3DX_FILTER_SRGB) != D3DX_FILTER_SRGB)) + conv_flags |= (filter & D3DX_FILTER_SRGB_IN) ? CONV_FLAG_GAMMA_2_2_IN : CONV_FLAG_GAMMA_2_2_OUT; return conv_flags; } @@ -2468,6 +2470,20 @@ static void undo_premultiplied_alpha(struct vec4 *vec) vec->z = (vec->w == 0.0f) ? 0.0f : vec->z / vec->w; } +static void apply_gamma_2_2(struct vec4 *vec) +{ + vec->x = powf(vec->x, 1.0f / 2.2f); + vec->y = powf(vec->y, 1.0f / 2.2f); + vec->z = powf(vec->z, 1.0f / 2.2f); +} + +static void undo_gamma_2_2(struct vec4 *vec) +{ + vec->x = powf(vec->x, 2.2f); + vec->y = powf(vec->y, 2.2f); + vec->z = powf(vec->z, 2.2f); +} + static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format_desc *src_fmt, uint8_t *dst_ptr, const struct pixel_format_desc *dst_fmt, const PALETTEENTRY *palette, struct argb_conversion_info *conv_info, const struct d3dx_color_key *color_key, @@ -2509,6 +2525,8 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format format_to_d3dx_color(src_fmt, src_ptr, palette, &color); if (conv_flags & CONV_FLAG_PM_ALPHA_IN) undo_premultiplied_alpha(&color.value); + if (conv_flags & CONV_FLAG_GAMMA_2_2_IN) + undo_gamma_2_2(&color.value); tmp = color; if (color_key) @@ -2528,6 +2546,8 @@ static void convert_argb_pixel(const uint8_t *src_ptr, const struct pixel_format } color = tmp; + if (conv_flags & CONV_FLAG_GAMMA_2_2_OUT) + apply_gamma_2_2(&color.value); if (conv_flags & CONV_FLAG_PM_ALPHA_OUT) premultiply_alpha(&color.value); format_from_d3dx_color(dst_fmt, &color, dst_ptr); @@ -2727,6 +2747,8 @@ static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src format_to_d3dx_color(src_format, ptr, palette, &tmp); if (conv_flags & CONV_FLAG_PM_ALPHA_IN) undo_premultiplied_alpha(&color.value); + if (conv_flags & CONV_FLAG_GAMMA_2_2_IN) + undo_gamma_2_2(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); @@ -2734,6 +2756,8 @@ static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src format_to_d3dx_color(src_format, ptr + src_format->bytes_per_pixel, palette, &tmp); if (conv_flags & CONV_FLAG_PM_ALPHA_IN) undo_premultiplied_alpha(&color.value); + if (conv_flags & CONV_FLAG_GAMMA_2_2_IN) + undo_gamma_2_2(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); @@ -2742,6 +2766,8 @@ static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src format_to_d3dx_color(src_format, ptr, palette, &tmp); if (conv_flags & CONV_FLAG_PM_ALPHA_IN) undo_premultiplied_alpha(&color.value); + if (conv_flags & CONV_FLAG_GAMMA_2_2_IN) + undo_gamma_2_2(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); @@ -2749,12 +2775,16 @@ static void box_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src format_to_d3dx_color(src_format, ptr + src_format->bytes_per_pixel, palette, &tmp); if (conv_flags & CONV_FLAG_PM_ALPHA_IN) undo_premultiplied_alpha(&color.value); + if (conv_flags & CONV_FLAG_GAMMA_2_2_IN) + undo_gamma_2_2(&color.value); if (color_key) check_color_key(&tmp, color_key, ck_format); vec4_add(&color.value, &tmp.value); } vec4_scale(&color.value, src_size->depth > 1 ? 0.125f : 0.25f); + if (conv_flags & CONV_FLAG_GAMMA_2_2_OUT) + apply_gamma_2_2(&color.value); if (conv_flags & CONV_FLAG_PM_ALPHA_OUT) premultiply_alpha(&color.value); format_from_d3dx_color(dst_format, &color, dst_ptr); diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 5b65f52cfa3..ec93236c891 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -246,6 +246,8 @@ enum conversion_flag { CONV_FLAG_PM_ALPHA_IN = 0x01, CONV_FLAG_PM_ALPHA_OUT = 0x02, + CONV_FLAG_GAMMA_2_2_IN = 0x04, + CONV_FLAG_GAMMA_2_2_OUT = 0x08, }; enum component_type diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index d3ff833f494..9d742816f03 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1407,7 +1407,7 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); - todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); + check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); IDirect3DSurface9_UnlockRect(decomp_surf); /* DXT4, SRGB in. */ @@ -1416,7 +1416,7 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); - todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); + check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_in_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 1); IDirect3DSurface9_UnlockRect(decomp_surf); /* @@ -1439,7 +1439,7 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); - todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); + check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); IDirect3DSurface9_UnlockRect(decomp_surf); /* DXT4, SRGB out. */ @@ -1459,7 +1459,7 @@ static void test_dxt_premultiplied_alpha(IDirect3DDevice9 *device) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); IDirect3DSurface9_LockRect(decomp_surf, &lock_rect, NULL, D3DLOCK_READONLY); - todo_wine check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); + check_test_readback(lock_rect.pBits, lock_rect.Pitch, 0, dxt_srgb_out_expected, 4, 4, 1, D3DFMT_A8R8G8B8, 0); IDirect3DSurface9_UnlockRect(decomp_surf); IDirect3DSurface9_Release(decomp_surf); @@ -2998,10 +2998,10 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) /* SRGB in, no SRGB out. */ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr); - todo_wine check_pixel_4bpp(&lockrect, 0, 0, 0x00010306); - todo_wine check_pixel_4bpp(&lockrect, 1, 0, 0x40141e2a); - todo_wine check_pixel_4bpp(&lockrect, 0, 1, 0x80495b71); - todo_wine check_pixel_4bpp(&lockrect, 1, 1, 0xc0a3c0ff); + check_pixel_4bpp(&lockrect, 0, 0, 0x00010306); + check_pixel_4bpp(&lockrect, 1, 0, 0x40141e2a); + check_pixel_4bpp(&lockrect, 0, 1, 0x80495b71); + check_pixel_4bpp(&lockrect, 1, 1, 0xc0a3c0ff); hr = IDirect3DSurface9_UnlockRect(surf); ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); @@ -3012,10 +3012,10 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) /* No SRGB in, SRGB out. */ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY); ok(hr == D3D_OK, "Failed to lock surface, hr %#lx.\n", hr); - todo_wine check_pixel_4bpp(&lockrect, 0, 0, 0x00486377); - todo_wine check_pixel_4bpp(&lockrect, 1, 0, 0x4097a4af); - todo_wine check_pixel_4bpp(&lockrect, 0, 1, 0x80c5ced7); - todo_wine check_pixel_4bpp(&lockrect, 1, 1, 0xc0e8f0ff); + check_pixel_4bpp(&lockrect, 0, 0, 0x00486377); + check_pixel_4bpp(&lockrect, 1, 0, 0x4097a4af); + check_pixel_4bpp(&lockrect, 0, 1, 0x80c5ced7); + check_pixel_4bpp(&lockrect, 1, 1, 0xc0e8f0ff); hr = IDirect3DSurface9_UnlockRect(surf); ok(hr == D3D_OK, "Failed to unlock surface, hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10513
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/tests/d3dx10.c:
+ dds.header.pixel_format.gmask = 0; + dds.header.pixel_format.bmask = 0; + dds.header.pixel_format.amask = 0; + + memset(dds.data, 0, sizeof(dds.data)); + load_info = d3dx10_default_load_info; + load_info.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + load_info.Filter = load_info.MipFilter = D3DX10_FILTER_NONE; + + for (i = 0; i < ARRAY_SIZE(test_dds_fmt); ++i) + { + winetest_push_context("Test %u (%s)", i, debugstr_fourcc(test_dds_fmt[i])); + if (i < 2) + memcpy(dds.data, test_dxt2_dxt3_data, sizeof(test_dxt2_dxt3_data)); + else + memcpy(dds.data, test_dxt4_dxt5_data, sizeof(test_dxt4_dxt5_data)); Not a big deal but the test data pointer could be stored together with the format inside a `tests[]` array.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10513#note_135308
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/d3dx_helpers.c:
vec->z = (vec->w == 0.0f) ? 0.0f : vec->z / vec->w; }
+static void apply_gamma_2_2(struct vec4 *vec) +{ + vec->x = powf(vec->x, 1.0f / 2.2f); + vec->y = powf(vec->y, 1.0f / 2.2f); + vec->z = powf(vec->z, 1.0f / 2.2f); +}
I seem to recall that you tried with the "accurate" piecewise sRGB definition previously (i.e. the one that's linear in the very low end and then uses a 2.4 exponent for the rest) but that didn't quite match as nicely? Maybe it makes sense to leave a small comment to that point, here or elsewhere. Separately, a bit of a nitpick. `apply_gamma_2_2()` might be slightly confusing: does it mean that gamma is applied to an sRGB color value to return the corresponding linear value or does it transform a linear color value into the corresponding sRGB value? In this case it's the latter, but you see the problem :slight_smile: Personally I'd just go with something like `srgb_from_linear()` and `linear_from_srgb()`, respectively. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10513#note_135310
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/texture.c:
load_info->MipLevels = (load_info->MipLevels == D3DX10_FROM_FILE) ? img_info.MipLevels : max_mip_level_count; load_info->MipLevels = min(max_mip_level_count, load_info->MipLevels);
+ if ((load_info->Width != image.size.width) || (load_info->Height != image.size.height) + || (load_info->Depth != image.size.depth) || (load_info->MipLevels != image.mip_levels) + || (fmt_desc->format != image.format))
It doesn't look like mip levels should be checked here. I tried to tweak the new test from the previous commit to use a different mip count and it still passed. I only tested d3dx10_43 32-bit; hopefully the behavior isn't version or bitness-specific. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10513#note_135309
On Tue Apr 7 17:33:31 2026 +0000, Matteo Bruni wrote:
It doesn't look like mip levels should be checked here. I tried to tweak the new test from the previous commit to use a different mip count and it still passed. I only tested d3dx10_43 32-bit; hopefully the behavior isn't version or bitness-specific. Can you give me a diff to test? Any changes I make to this test like:
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 5a22240d37b..dd8b5b848b6 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1852,7 +1852,7 @@ static const struct test_image_load_info
{
dds_dxt10_4_4, sizeof(dds_dxt10_4_4),
{
- D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 1, (D3D10_USAGE)D3DX10_DEFAULT,
+ D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 2, (D3D10_USAGE)D3DX10_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT
},
S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE2D,
Results in failure on native, both 32 and 64 bit tests on both d3dx10_43 and d3dx10_33. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10513#note_135710
On Thu Apr 9 22:57:05 2026 +0000, Connor McAdams wrote:
Can you give me a diff to test? Any changes I make to this test like: ``` diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 5a22240d37b..dd8b5b848b6 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1852,7 +1852,7 @@ static const struct test_image_load_info { dds_dxt10_4_4, sizeof(dds_dxt10_4_4), { - D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 1, (D3D10_USAGE)D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 2, (D3D10_USAGE)D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT }, S_OK, D3D10_RESOURCE_DIMENSION_TEXTURE2D, ``` Results in failure on native, both 32 and 64 bit tests on both d3dx10_43 and d3dx10_33. I can't reproduce it anymore, I must have made some silly mistake when I tested it. Sorry for the noise :/
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10513#note_135759
participants (3)
-
Connor McAdams -
Connor McAdams (@cmcadams) -
Matteo Bruni (@Mystral)