Rebase against bcd3e1a4de9d6efb177b932a937412bfb962d149.

This commit is contained in:
Alistair Leslie-Hughes
2025-10-01 07:49:50 +10:00
parent ea30d81923
commit 7e9e516c71
17 changed files with 2 additions and 2433 deletions

View File

@@ -1,37 +0,0 @@
From 4d8b800f0ebe625824b12b081026283e4c3c1efc Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Thu, 8 Aug 2024 07:30:25 -0400
Subject: [PATCH] d3dx9: Add an optimization to stb_dxt.
This optimzation helps us to more closely match the output of native
d3dx's DXT compression, which helps with d3dx10 tests.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx9_36/stb_dxt.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/dlls/d3dx9_36/stb_dxt.h b/dlls/d3dx9_36/stb_dxt.h
index c25f6b015da..2b40829deac 100644
--- a/dlls/d3dx9_36/stb_dxt.h
+++ b/dlls/d3dx9_36/stb_dxt.h
@@ -565,6 +565,16 @@ static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src, int
dest[1] = (unsigned char)mn;
dest += 2;
+ /*
+ * Wine specific optimization to more closely match Windows behavior: If
+ * max is equal to minimum, just set all bits to 0 (which means the value
+ * is the value of max in this case).
+ */
+ if (mx == mn) {
+ memset(dest, 0, 6);
+ return;
+ }
+
// determine bias and emit color indices
// given the choice of mx/mn, these indices are optimal:
// http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/
--
2.51.0

View File

@@ -1,222 +0,0 @@
From 3f2a65b69375bc84e10f4a4cc32c1d7ed34d4acb Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Mon, 15 Sep 2025 14:23:52 -0400
Subject: [PATCH] d3dx10: Use shared code in load_texture_data() when possible.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 2 +-
dlls/d3dx10_43/texture.c | 112 +++++++++++++++++++++++++++++++++-
dlls/d3dx9_36/d3dx_helpers.c | 6 +-
dlls/d3dx9_36/d3dx_helpers.h | 4 ++
4 files changed, 118 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 75e4b4023d8..119b74c7ece 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1579,7 +1579,7 @@ static void check_texture2d_data(ID3D10Texture2D *texture, const struct test_ima
{
line_match = !memcmp(expected_data + stride * i,
(BYTE *)map.pData + map.RowPitch * i, stride);
- todo_wine_if(is_block_compressed(image->expected_info.Format)
+ todo_wine_if(is_block_compressed(image->expected_info.Format) && image->data != test_dds_dxt5
&& (image->expected_info.Width % 4 != 0 || image->expected_info.Height % 4 != 0))
ok_(__FILE__, line)(line_match, "Data mismatch for line %u, array slice %u.\n", i, array_slice);
if (!line_match)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index ab488dcfa2f..f578ab0f789 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -873,6 +873,93 @@ static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode
return hr;
}
+static HRESULT d3dx_load_texture_data(struct d3dx_image *image, D3DX10_IMAGE_LOAD_INFO *load_info,
+ const D3DX10_IMAGE_INFO *img_info, D3D10_SUBRESOURCE_DATA **resource_data)
+{
+ const struct pixel_format_desc *fmt_desc, *src_desc;
+ D3DX10_IMAGE_LOAD_INFO tmp_load_info = *load_info;
+ uint32_t i, j, pixels_size, pixels_offset;
+ uint8_t *res_data = NULL, *pixels_buffer;
+ HRESULT hr = S_OK;
+
+ if (img_info->ImageFileFormat == D3DX10_IFF_BMP)
+ return E_NOTIMPL;
+
+ fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(img_info->Format));
+ if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT)
+ {
+ FIXME("Unknown DXGI format supplied, %#x.\n", img_info->Format);
+ return E_NOTIMPL;
+ }
+
+ /* Potentially round up width/height to align with block size. */
+ tmp_load_info.Width = (img_info->Width + fmt_desc->block_width - 1) & ~(fmt_desc->block_width - 1);
+ tmp_load_info.Height = (img_info->Height + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1);
+ tmp_load_info.Depth = img_info->Depth;
+ tmp_load_info.MipLevels = img_info->MipLevels;
+ tmp_load_info.Format = img_info->Format;
+
+ pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, tmp_load_info.Width, tmp_load_info.Height,
+ tmp_load_info.Depth, tmp_load_info.MipLevels) * img_info->ArraySize;
+ pixels_offset = (sizeof(**resource_data) * tmp_load_info.MipLevels * img_info->ArraySize);
+ if (!(res_data = malloc(pixels_size + pixels_offset)))
+ return E_FAIL;
+
+ pixels_buffer = res_data + pixels_offset;
+ *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
+
+ src_desc = get_d3dx_pixel_format_info(image->format);
+ for (i = 0; i < img_info->ArraySize; ++i)
+ {
+ struct volume dst_size = { tmp_load_info.Width, tmp_load_info.Height, tmp_load_info.Depth };
+
+ for (j = 0; j < tmp_load_info.MipLevels; ++j)
+ {
+ const RECT unaligned_rect = { 0, 0, dst_size.width, dst_size.height };
+ struct d3dx_pixels src_pixels, dst_pixels;
+ uint32_t dst_row_pitch, dst_slice_pitch;
+
+ hr = d3dx_image_get_pixels(image, i, j, &src_pixels);
+ if (FAILED(hr))
+ break;
+
+ hr = d3dx_calculate_pixels_size(fmt_desc->format, dst_size.width, dst_size.height, &dst_row_pitch,
+ &dst_slice_pitch);
+ if (FAILED(hr))
+ break;
+
+ set_d3dx_pixels(&dst_pixels, pixels_buffer, dst_row_pitch, dst_slice_pitch, NULL, dst_size.width,
+ dst_size.height, dst_size.depth, &unaligned_rect);
+
+ hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, D3DX10_FILTER_POINT, 0);
+ if (FAILED(hr))
+ break;
+
+ (*resource_data)[i * tmp_load_info.MipLevels + j].pSysMem = pixels_buffer;
+ (*resource_data)[i * tmp_load_info.MipLevels + j].SysMemPitch = dst_row_pitch;
+ (*resource_data)[i * tmp_load_info.MipLevels + j].SysMemSlicePitch = dst_slice_pitch;
+
+ pixels_buffer += dst_slice_pitch * dst_size.depth;
+ d3dx_get_next_mip_level_size(&dst_size);
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ *resource_data = NULL;
+ free(res_data);
+ return hr;
+ }
+
+ *load_info = tmp_load_info;
+ load_info->Usage = D3D10_USAGE_DEFAULT;
+ load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ load_info->CpuAccessFlags = 0;
+ load_info->MiscFlags = img_info->MiscFlags;
+
+ return S_OK;
+}
+
HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info,
D3D10_SUBRESOURCE_DATA **resource_data)
{
@@ -885,9 +972,13 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
BYTE *res_data = NULL, *buffer;
D3DX10_IMAGE_INFO img_info;
IWICStream *stream = NULL;
+ struct d3dx_image image;
const GUID *dst_format;
HRESULT hr;
+ if (!data || !size)
+ return E_FAIL;
+
if (load_info->Width != D3DX10_DEFAULT)
FIXME("load_info->Width is ignored.\n");
if (load_info->Height != D3DX10_DEFAULT)
@@ -915,15 +1006,32 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (load_info->pSrcInfo)
FIXME("load_info->pSrcInfo is ignored.\n");
- if (FAILED(D3DX10GetImageInfoFromMemory(data, size, NULL, &img_info, NULL)))
+ hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10);
+ if (FAILED(hr))
return E_FAIL;
+
+ hr = d3dx10_image_info_from_d3dx_image(&img_info, &image);
+ if (FAILED(hr))
+ {
+ WARN("Invalid or unsupported image file, hr %#lx.\n", hr);
+ hr = E_FAIL;
+ goto end;
+ }
+
if ((!(img_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) || img_info.ArraySize != 6)
&& img_info.ArraySize != 1)
{
FIXME("img_info.ArraySize = %u not supported.\n", img_info.ArraySize);
- return E_NOTIMPL;
+ hr = E_NOTIMPL;
+ goto end;
}
+ if (SUCCEEDED(hr = d3dx_load_texture_data(&image, load_info, &img_info, resource_data)))
+ {
+ TRACE("Successfully used shared code to load texture data.\n");
+ res_data = NULL;
+ goto end;
+ }
if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory)))
goto end;
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index 60394ca1d9b..76763c4521f 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -377,7 +377,7 @@ 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)
+enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format)
{
switch (format)
{
@@ -417,7 +417,7 @@ static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(DXGI_FORM
}
}
-static void d3dx_get_next_mip_level_size(struct volume *size)
+void d3dx_get_next_mip_level_size(struct volume *size)
{
size->width = max(size->width / 2, 1);
size->height = max(size->height / 2, 1);
@@ -431,7 +431,7 @@ static const char *debug_volume(const struct volume *volume)
return wine_dbg_sprintf("(%ux%ux%u)", volume->width, volume->height, volume->depth);
}
-static HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
+HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
uint32_t *pitch, uint32_t *size)
{
const struct pixel_format_desc *format_desc = get_d3dx_pixel_format_info(format);
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h
index 8263d832bfa..91839296b47 100644
--- a/dlls/d3dx9_36/d3dx_helpers.h
+++ b/dlls/d3dx9_36/d3dx_helpers.h
@@ -391,6 +391,10 @@ void format_to_d3dx_color(const struct pixel_format_desc *format, const BYTE *sr
struct d3dx_color *dst);
void format_from_d3dx_color(const struct pixel_format_desc *format, const struct d3dx_color *src, BYTE *dst);
+enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format);
+void d3dx_get_next_mip_level_size(struct volume *size);
+HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
+ uint32_t *pitch, uint32_t *size);
uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
uint32_t depth, uint32_t mip_levels);
HRESULT d3dx_init_dds_header(struct dds_header *header, enum d3dx_resource_type resource_type,
--
2.51.0

View File

@@ -1,119 +0,0 @@
From 38bc3286663b541150cfd34e01b33ee09f738ab7 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Mon, 15 Sep 2025 14:39:47 -0400
Subject: [PATCH] d3dx10: Add support for decompressing BC4 and BC5 formats.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/texture.c | 1 +
dlls/d3dx9_36/bcdec.h | 6 +++---
dlls/d3dx9_36/d3dx_helpers.c | 21 +++++++++++++++++++++
dlls/d3dx9_36/d3dx_helpers.h | 1 +
4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index f578ab0f789..a3acd063ac9 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -113,6 +113,7 @@ static DXGI_FORMAT dxgi_format_from_d3dx_pixel_format_id(enum d3dx_pixel_format_
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_R8_SNORM: return DXGI_FORMAT_R8_SNORM;
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;
diff --git a/dlls/d3dx9_36/bcdec.h b/dlls/d3dx9_36/bcdec.h
index 5ead984c466..1b57a454926 100644
--- a/dlls/d3dx9_36/bcdec.h
+++ b/dlls/d3dx9_36/bcdec.h
@@ -90,9 +90,9 @@
BCDECDEF void bcdec_bc1(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
BCDECDEF void bcdec_bc2(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
-#ifdef WINE_UNUSED /* unused for now in Wine */
BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
+#ifdef WINE_UNUSED /* unused for now in Wine */
BCDECDEF void bcdec_bc6h_float(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
BCDECDEF void bcdec_bc6h_half(const void* compressedBlock, void* decompressedBlock, int destinationPitch, int isSigned);
BCDECDEF void bcdec_bc7(const void* compressedBlock, void* decompressedBlock, int destinationPitch);
@@ -275,8 +275,6 @@ BCDECDEF void bcdec_bc3(const void* compressedBlock, void* decompressedBlock, in
bcdec__smooth_alpha_block(compressedBlock, ((char*)decompressedBlock) + 3, destinationPitch, 4);
}
-#ifdef WINE_UNUSED /* unused for now in Wine */
-
BCDECDEF void bcdec_bc4(const void* compressedBlock, void* decompressedBlock, int destinationPitch) {
bcdec__smooth_alpha_block(compressedBlock, decompressedBlock, destinationPitch, 1);
}
@@ -286,6 +284,8 @@ BCDECDEF void bcdec_bc5(const void* compressedBlock, void* decompressedBlock, in
bcdec__smooth_alpha_block(((char*)compressedBlock) + 8, ((char*)decompressedBlock) + 1, destinationPitch, 2);
}
+#ifdef WINE_UNUSED /* unused for now in Wine */
+
/* http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend */
static int bcdec__extend_sign(int val, int bits) {
return (val << (32 - bits)) >> (32 - bits);
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index 76763c4521f..afbacecf320 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -81,6 +81,7 @@ static const struct pixel_format_desc formats[] =
{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_R8_SNORM, { 0, 8, 0, 0}, { 0, 0, 0, 0}, 1, 1, 1, 1, CTYPE_EMPTY, CTYPE_SNORM, 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 },
@@ -390,6 +391,7 @@ enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format)
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_R8_SNORM: return D3DX_PIXEL_FORMAT_R8_SNORM;
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;
@@ -2553,6 +2555,25 @@ static HRESULT d3dx_pixels_decompress(struct d3dx_pixels *pixels, const struct p
decompress_bcn_block = bcdec_bc3;
break;
+ case D3DX_PIXEL_FORMAT_BC4_UNORM:
+ case D3DX_PIXEL_FORMAT_BC4_SNORM:
+ if (desc->rgb_type == CTYPE_UNORM)
+ uncompressed_desc = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_R8_UNORM);
+ else
+ uncompressed_desc = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_R8_SNORM);
+ decompress_bcn_block = bcdec_bc4;
+ break;
+
+ case D3DX_PIXEL_FORMAT_BC5_UNORM:
+ case D3DX_PIXEL_FORMAT_BC5_SNORM:
+ if (desc->rgb_type == CTYPE_UNORM)
+ uncompressed_desc = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_R8G8_UNORM);
+ else
+ uncompressed_desc = get_d3dx_pixel_format_info(D3DX_PIXEL_FORMAT_R8G8_SNORM);
+ decompress_bcn_block = bcdec_bc5;
+ break;
+
+
default:
FIXME("Unexpected compressed texture format %u.\n", desc->format);
return E_NOTIMPL;
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h
index 91839296b47..663febd279b 100644
--- a/dlls/d3dx9_36/d3dx_helpers.h
+++ b/dlls/d3dx9_36/d3dx_helpers.h
@@ -188,6 +188,7 @@ enum d3dx_pixel_format_id
D3DX_PIXEL_FORMAT_R16G16B16_UNORM,
D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM,
D3DX_PIXEL_FORMAT_R8_UNORM,
+ D3DX_PIXEL_FORMAT_R8_SNORM,
D3DX_PIXEL_FORMAT_R8G8_UNORM,
D3DX_PIXEL_FORMAT_R16_UNORM,
D3DX_PIXEL_FORMAT_R16G16_UNORM,
--
2.51.0

View File

@@ -1,90 +0,0 @@
From 92319f7205bce8ecb23e3c17141d8a371cb01e47 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Mon, 15 Sep 2025 14:46:56 -0400
Subject: [PATCH] d3dx10: Add support for compressing BC4 and BC5 formats.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx9_36/d3dx_helpers.c | 26 ++++++++++++++++++++++++++
dlls/d3dx9_36/stb_dxt.h | 5 -----
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index afbacecf320..aae7efccf69 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -2789,6 +2789,16 @@ static void d3dx_compress_block(enum d3dx_pixel_format_id fmt, uint8_t *block_bu
stb_compress_dxt_block(dst_buf, block_buf, TRUE, 0);
break;
+ case D3DX_PIXEL_FORMAT_BC4_UNORM:
+ case D3DX_PIXEL_FORMAT_BC4_SNORM:
+ stb_compress_bc4_block(dst_buf, block_buf);
+ break;
+
+ case D3DX_PIXEL_FORMAT_BC5_UNORM:
+ case D3DX_PIXEL_FORMAT_BC5_SNORM:
+ stb_compress_bc5_block(dst_buf, block_buf);
+ break;
+
default:
assert(0);
break;
@@ -2818,6 +2828,22 @@ static HRESULT d3dx_pixels_compress(struct d3dx_pixels *src_pixels,
assert(src_desc->format == D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM);
break;
+ case D3DX_PIXEL_FORMAT_BC4_UNORM:
+ assert(src_desc->format == D3DX_PIXEL_FORMAT_R8_UNORM);
+ break;
+
+ case D3DX_PIXEL_FORMAT_BC4_SNORM:
+ assert(src_desc->format == D3DX_PIXEL_FORMAT_R8_SNORM);
+ break;
+
+ case D3DX_PIXEL_FORMAT_BC5_UNORM:
+ assert(src_desc->format == D3DX_PIXEL_FORMAT_R8G8_UNORM);
+ break;
+
+ case D3DX_PIXEL_FORMAT_BC5_SNORM:
+ assert(src_desc->format == D3DX_PIXEL_FORMAT_R8G8_SNORM);
+ break;
+
default:
FIXME("Unexpected compressed texture format %u.\n", dst_desc->format);
return E_NOTIMPL;
diff --git a/dlls/d3dx9_36/stb_dxt.h b/dlls/d3dx9_36/stb_dxt.h
index 2b40829deac..46375273e64 100644
--- a/dlls/d3dx9_36/stb_dxt.h
+++ b/dlls/d3dx9_36/stb_dxt.h
@@ -56,10 +56,8 @@ extern "C" {
#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower.
STBDDEF void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src_rgba_four_bytes_per_pixel, int alpha, int mode);
-#ifdef WINE_UNUSED /* unused for now in Wine */
STBDDEF void stb_compress_bc4_block(unsigned char *dest, const unsigned char *src_r_one_byte_per_pixel);
STBDDEF void stb_compress_bc5_block(unsigned char *dest, const unsigned char *src_rg_two_byte_per_pixel);
-#endif /* WINE_UNUSED */
#define STB_COMPRESS_DXT_BLOCK
@@ -626,8 +624,6 @@ void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int a
stb__CompressColorBlock(dest,(unsigned char*) src,mode);
}
-#ifdef WINE_UNUSED /* unused for now in Wine */
-
void stb_compress_bc4_block(unsigned char *dest, const unsigned char *src)
{
stb__CompressAlphaBlock(dest,(unsigned char*) src, 1);
@@ -638,7 +634,6 @@ void stb_compress_bc5_block(unsigned char *dest, const unsigned char *src)
stb__CompressAlphaBlock(dest,(unsigned char*) src,2);
stb__CompressAlphaBlock(dest + 8,(unsigned char*) src+1,2);
}
-#endif /* WINE_UNUSED */
#endif // STB_DXT_IMPLEMENTATION
--
2.51.0

View File

@@ -1,248 +0,0 @@
From a94c1e21dd77923b37d2ce7ad10d3235c148cbb3 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Thu, 8 Aug 2024 09:06:03 -0400
Subject: [PATCH] d3dx10: Exclusively use shared code to load DDS files in
load_texture_data().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/texture.c | 171 ++++++-----------------------------
dlls/d3dx9_36/d3dx_helpers.c | 4 +
2 files changed, 31 insertions(+), 144 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index a3acd063ac9..7b2490a4d00 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -805,32 +805,6 @@ void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info, D3DX10_IMAGE_LOAD_I
out->pSrcInfo = NULL;
}
-static HRESULT dds_get_frame_info(IWICDdsFrameDecode *frame, const D3DX10_IMAGE_INFO *img_info,
- WICDdsFormatInfo *format_info, unsigned int *stride, unsigned int *frame_size)
-{
- unsigned int width, height;
- HRESULT hr;
-
- if (FAILED(hr = IWICDdsFrameDecode_GetFormatInfo(frame, format_info)))
- return hr;
- if (FAILED(hr = IWICDdsFrameDecode_GetSizeInBlocks(frame, &width, &height)))
- return hr;
-
- if (img_info->Format == format_info->DxgiFormat)
- {
- *stride = width * format_info->BytesPerBlock;
- *frame_size = *stride * height;
- }
- else
- {
- width *= format_info->BlockWidth;
- height *= format_info->BlockHeight;
- *stride = (width * get_bpp_from_format(img_info->Format) + 7) / 8;
- *frame_size = *stride * height;
- }
- return S_OK;
-}
-
static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode *frame,
const GUID *dst_format, unsigned int stride, unsigned int frame_size, BYTE *buffer)
{
@@ -964,12 +938,10 @@ static HRESULT d3dx_load_texture_data(struct d3dx_image *image, D3DX10_IMAGE_LOA
HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info,
D3D10_SUBRESOURCE_DATA **resource_data)
{
- unsigned int stride, frame_size, i, j;
- IWICDdsFrameDecode *dds_frame = NULL;
IWICBitmapFrameDecode *frame = NULL;
IWICImagingFactory *factory = NULL;
- IWICDdsDecoder *dds_decoder = NULL;
IWICBitmapDecoder *decoder = NULL;
+ unsigned int stride, frame_size;
BYTE *res_data = NULL, *buffer;
D3DX10_IMAGE_INFO img_info;
IWICStream *stream = NULL;
@@ -1033,6 +1005,10 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
res_data = NULL;
goto end;
}
+ else if (img_info.ImageFileFormat == D3DX10_IFF_DDS)
+ {
+ goto end;
+ }
if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory)))
goto end;
@@ -1042,122 +1018,32 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
goto end;
if (FAILED(hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder)))
goto end;
+ if (FAILED(hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame)))
+ goto end;
- if (img_info.ImageFileFormat == D3DX10_IFF_DDS)
- {
- WICDdsFormatInfo format_info;
- size_t size = 0;
-
- if (FAILED(hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder)))
- goto end;
-
- for (i = 0; i < img_info.ArraySize; ++i)
- {
- for (j = 0; j < img_info.MipLevels; ++j)
- {
- if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, j, 0, &frame)))
- goto end;
- if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame,
- &IID_IWICDdsFrameDecode, (void **)&dds_frame)))
- goto end;
- if (FAILED(hr = dds_get_frame_info(dds_frame, &img_info, &format_info, &stride, &frame_size)))
- goto end;
-
- if (!i && !j)
- {
- img_info.Width = (img_info.Width + format_info.BlockWidth - 1) & ~(format_info.BlockWidth - 1);
- img_info.Height = (img_info.Height + format_info.BlockHeight - 1) & ~(format_info.BlockHeight - 1);
- }
-
- size += sizeof(**resource_data) + frame_size;
-
- IWICDdsFrameDecode_Release(dds_frame);
- dds_frame = NULL;
- IWICBitmapFrameDecode_Release(frame);
- frame = NULL;
- }
- }
-
- if (!(res_data = malloc(size)))
- {
- hr = E_FAIL;
- goto end;
- }
- *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
+ stride = (img_info.Width * get_bpp_from_format(img_info.Format) + 7) / 8;
+ frame_size = stride * img_info.Height;
- size = 0;
- for (i = 0; i < img_info.ArraySize; ++i)
- {
- for (j = 0; j < img_info.MipLevels; ++j)
- {
- if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, j, 0, &frame)))
- goto end;
- if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame,
- &IID_IWICDdsFrameDecode, (void **)&dds_frame)))
- goto end;
- if (FAILED(hr = dds_get_frame_info(dds_frame, &img_info, &format_info, &stride, &frame_size)))
- goto end;
-
- buffer = res_data + sizeof(**resource_data) * img_info.ArraySize * img_info.MipLevels + size;
- size += frame_size;
-
- if (img_info.Format == format_info.DxgiFormat)
- {
- if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride, frame_size, buffer)))
- goto end;
- }
- else
- {
- if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format)))
- {
- hr = E_FAIL;
- FIXME("Unsupported DXGI format %#x.\n", img_info.Format);
- goto end;
- }
- if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer)))
- goto end;
- }
-
- IWICDdsFrameDecode_Release(dds_frame);
- dds_frame = NULL;
- IWICBitmapFrameDecode_Release(frame);
- frame = NULL;
-
- (*resource_data)[i * img_info.MipLevels + j].pSysMem = buffer;
- (*resource_data)[i * img_info.MipLevels + j].SysMemPitch = stride;
- (*resource_data)[i * img_info.MipLevels + j].SysMemSlicePitch = frame_size;
- }
- }
- }
- else
+ if (!(res_data = malloc(sizeof(**resource_data) + frame_size)))
{
- if (FAILED(hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame)))
- goto end;
-
- stride = (img_info.Width * get_bpp_from_format(img_info.Format) + 7) / 8;
- frame_size = stride * img_info.Height;
-
- if (!(res_data = malloc(sizeof(**resource_data) + frame_size)))
- {
- hr = E_FAIL;
- goto end;
- }
- buffer = res_data + sizeof(**resource_data);
-
- if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format)))
- {
- hr = E_FAIL;
- FIXME("Unsupported DXGI format %#x.\n", img_info.Format);
- goto end;
- }
- if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer)))
- goto end;
+ hr = E_FAIL;
+ goto end;
+ }
+ buffer = res_data + sizeof(**resource_data);
- *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
- (*resource_data)->pSysMem = buffer;
- (*resource_data)->SysMemPitch = stride;
- (*resource_data)->SysMemSlicePitch = frame_size;
+ if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format)))
+ {
+ hr = E_FAIL;
+ FIXME("Unsupported DXGI format %#x.\n", img_info.Format);
+ goto end;
}
+ if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer)))
+ goto end;
+
+ *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
+ (*resource_data)->pSysMem = buffer;
+ (*resource_data)->SysMemPitch = stride;
+ (*resource_data)->SysMemSlicePitch = frame_size;
load_info->Width = img_info.Width;
load_info->Height = img_info.Height;
@@ -1171,10 +1057,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
hr = S_OK;
end:
- if (dds_decoder)
- IWICDdsDecoder_Release(dds_decoder);
- if (dds_frame)
- IWICDdsFrameDecode_Release(dds_frame);
+ d3dx_image_cleanup(&image);
free(res_data);
if (frame)
IWICBitmapFrameDecode_Release(frame);
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index aae7efccf69..23b8bdabd6a 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -408,6 +408,10 @@ enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format)
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_BC4_UNORM: return D3DX_PIXEL_FORMAT_BC4_UNORM;
+ case DXGI_FORMAT_BC4_SNORM: return D3DX_PIXEL_FORMAT_BC4_SNORM;
+ case DXGI_FORMAT_BC5_UNORM: return D3DX_PIXEL_FORMAT_BC5_UNORM;
+ case DXGI_FORMAT_BC5_SNORM: return D3DX_PIXEL_FORMAT_BC5_SNORM;
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;
--
2.51.0

View File

@@ -1,220 +0,0 @@
From 60ece0635b1d6f5176190a4c2fa68fc9b7a8d9cd Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Wed, 17 Sep 2025 15:05:17 -0400
Subject: [PATCH] d3dx10: Set D3DX10_IMAGE_LOAD_INFO pSrcInfo value if passed
in.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 116 ++++++++++++++++++++++++++++++++++
dlls/d3dx10_43/texture.c | 4 +-
2 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 6155855713e..f660b9a2953 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -2964,6 +2964,12 @@ static void test_D3DX10CreateAsyncTextureInfoProcessor(void)
CoUninitialize();
}
+static const D3DX10_IMAGE_LOAD_INFO d3dx10_default_load_info =
+{
+ D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT,
+ D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, NULL
+};
+
static void test_D3DX10CreateAsyncTextureProcessor(void)
{
ID3DX10DataProcessor *dp;
@@ -2998,6 +3004,9 @@ static void test_D3DX10CreateAsyncTextureProcessor(void)
for (i = 0; i < ARRAY_SIZE(test_image); ++i)
{
+ D3DX10_IMAGE_LOAD_INFO load_info = d3dx10_default_load_info;
+ D3DX10_IMAGE_INFO info = { 0 };
+
winetest_push_context("Test %u", i);
hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &dp);
@@ -3018,6 +3027,27 @@ static void test_D3DX10CreateAsyncTextureProcessor(void)
hr = ID3DX10DataProcessor_Destroy(dp);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Check that D3DX10_IMAGE_INFO argument is set. */
+ load_info.pSrcInfo = &info;
+ hr = D3DX10CreateAsyncTextureProcessor(device, &load_info, &dp);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[i].data, test_image[i].size);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ if (hr == S_OK)
+ {
+ hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
+ hr = ID3DX10DataProcessor_Destroy(dp);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
winetest_pop_context();
}
@@ -4117,6 +4147,8 @@ static void test_create_texture(void)
for (i = 0; i < ARRAY_SIZE(test_image); ++i)
{
+ D3DX10_IMAGE_INFO info = { 0 };
+
winetest_push_context("Test %u", i);
hr2 = 0xdeadbeef;
@@ -4131,6 +4163,22 @@ static void test_create_texture(void)
ID3D10Resource_Release(resource);
}
+ /* Check that D3DX10_IMAGE_INFO argument is set. */
+ load_info = d3dx10_default_load_info;
+ load_info.pSrcInfo = &info;
+ hr2 = 0xdeadbeef;
+ hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, &load_info, NULL, &resource, &hr2);
+ ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ if (hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
winetest_pop_context();
}
@@ -4274,6 +4322,8 @@ static void test_create_texture(void)
for (i = 0; i < ARRAY_SIZE(test_image); ++i)
{
+ D3DX10_IMAGE_INFO info = { 0 };
+
winetest_push_context("Test %u", i);
create_file(test_filename, test_image[i].data, test_image[i].size, path);
@@ -4301,6 +4351,37 @@ static void test_create_texture(void)
ID3D10Resource_Release(resource);
}
+ /* Check that D3DX10_IMAGE_INFO argument is set. */
+ load_info = d3dx10_default_load_info;
+ load_info.pSrcInfo = &info;
+ hr2 = 0xdeadbeef;
+ hr = D3DX10CreateTextureFromFileW(device, path, &load_info, NULL, &resource, &hr2);
+ ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ if (hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
+ load_info = d3dx10_default_load_info;
+ load_info.pSrcInfo = &info;
+ hr2 = 0xdeadbeef;
+ hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), &load_info, NULL, &resource, &hr2);
+ ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ if (hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
delete_file(test_filename);
winetest_pop_context();
}
@@ -4351,6 +4432,8 @@ static void test_create_texture(void)
for (i = 0; i < ARRAY_SIZE(test_image); ++i)
{
+ D3DX10_IMAGE_INFO info = { 0 };
+
winetest_push_context("Test %u", i);
resource_module = create_resource_module(test_resource_name, test_image[i].data, test_image[i].size);
@@ -4385,6 +4468,39 @@ static void test_create_texture(void)
ID3D10Resource_Release(resource);
}
+ /* Check that D3DX10_IMAGE_INFO argument is set. */
+ load_info = d3dx10_default_load_info;
+ load_info.pSrcInfo = &info;
+ hr2 = 0xdeadbeef;
+ hr = D3DX10CreateTextureFromResourceW(device, resource_module,
+ test_resource_name, &load_info, NULL, &resource, &hr2);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
+ if (hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
+ load_info = d3dx10_default_load_info;
+ load_info.pSrcInfo = &info;
+ hr2 = 0xdeadbeef;
+ hr = D3DX10CreateTextureFromResourceA(device, resource_module,
+ get_str_a(test_resource_name), &load_info, NULL, &resource, &hr2);
+ ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP),
+ "Got unexpected hr %#lx.\n", hr);
+ ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2);
+ if (hr == S_OK)
+ {
+ check_resource_info(resource, test_image + i, __LINE__);
+ check_resource_data(resource, test_image + i, __LINE__);
+ check_image_info(&info, test_image + i, __LINE__);
+ ID3D10Resource_Release(resource);
+ }
+
delete_resource_module(test_resource_name, resource_module);
winetest_pop_context();
}
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 2c09040838b..4d279bccbd5 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -666,8 +666,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
FIXME("load_info->Filter is ignored.\n");
if (load_info->MipFilter != D3DX10_DEFAULT)
FIXME("load_info->MipFilter is ignored.\n");
- if (load_info->pSrcInfo)
- FIXME("load_info->pSrcInfo is ignored.\n");
*resource_data = NULL;
hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10);
@@ -764,6 +762,8 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE;
load_info->CpuAccessFlags = 0;
load_info->MiscFlags = img_info.MiscFlags;
+ if (load_info->pSrcInfo)
+ *load_info->pSrcInfo = img_info;
end:
d3dx_image_cleanup(&image);
--
2.51.0

View File

@@ -1,138 +0,0 @@
From d86d4e9d383a5853fc494f3bb2bcdfb40c75761e Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Thu, 18 Sep 2025 11:42:06 -0400
Subject: [PATCH] d3dx10: Handle filter value passed in via
D3DX10_IMAGE_LOAD_INFO.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 2 +-
dlls/d3dx10_43/texture.c | 12 +++++++++---
dlls/d3dx9_36/d3dx9_private.h | 10 +---------
dlls/d3dx9_36/d3dx_helpers.c | 9 +++++++++
dlls/d3dx9_36/d3dx_helpers.h | 2 ++
dlls/d3dx9_36/texture.c | 2 +-
6 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 2287e14d36e..083e1ebd628 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1086,7 +1086,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT
},
- D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE
+ D3DERR_INVALIDCALL, D3DERR_INVALIDCALL
},
/* Invalid mipfilter value, only checked if mips are generated. */
{
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 97cccc45223..3ff0b136c0c 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -666,12 +666,18 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
FIXME("load_info->MiscFlags is ignored.\n");
if (load_info->Format != D3DX10_DEFAULT)
FIXME("load_info->Format is ignored.\n");
- if (load_info->Filter != D3DX10_DEFAULT)
- FIXME("load_info->Filter is ignored.\n");
if (load_info->MipFilter != D3DX10_DEFAULT)
FIXME("load_info->MipFilter is ignored.\n");
*resource_data = NULL;
+ if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT)
+ load_info->Filter = D3DX10_FILTER_TRIANGLE | D3DX10_FILTER_DITHER;
+ if (FAILED(hr = d3dx_validate_filter(load_info->Filter)))
+ {
+ ERR("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;
@@ -742,7 +748,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
set_d3dx_pixels(&dst_pixels, pixels_buffer, dst_row_pitch, dst_slice_pitch, NULL, dst_size.width,
dst_size.height, dst_size.depth, &unaligned_rect);
- hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, D3DX10_FILTER_POINT, 0);
+ hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, load_info->Filter, 0);
if (FAILED(hr))
break;
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h
index 655529b004b..394b1a1cee2 100644
--- a/dlls/d3dx9_36/d3dx9_private.h
+++ b/dlls/d3dx9_36/d3dx9_private.h
@@ -35,20 +35,12 @@
#define FOURCC_TX_1 0x54580100
#define D3DX9_FILTER_INVALID_BITS 0xff80fff8
-static inline HRESULT d3dx9_validate_filter(uint32_t filter)
-{
- if ((filter & D3DX9_FILTER_INVALID_BITS) || !(filter & 0x7) || ((filter & 0x7) > D3DX_FILTER_BOX))
- return D3DERR_INVALIDCALL;
-
- return D3D_OK;
-}
-
static inline HRESULT d3dx9_handle_load_filter(DWORD *filter)
{
if (*filter == D3DX_DEFAULT)
*filter = D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER;
- return d3dx9_validate_filter(*filter);
+ return d3dx_validate_filter(*filter);
}
BOOL d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image);
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index 7cf4123fb15..5b489f7e974 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -53,6 +53,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
#define D3DX_FILTER_SRGB_OUT 0x00400000
#define D3DX_FILTER_SRGB 0x00600000
+#define D3DX_FILTER_INVALID_BITS 0xff80fff8
+HRESULT d3dx_validate_filter(uint32_t filter)
+{
+ if ((filter & D3DX_FILTER_INVALID_BITS) || !(filter & 0x7) || ((filter & 0x7) > D3DX_FILTER_BOX))
+ return D3DERR_INVALIDCALL;
+
+ return D3D_OK;
+}
+
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
/************************************************************
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h
index 42b40c1c279..83c213db311 100644
--- a/dlls/d3dx9_36/d3dx_helpers.h
+++ b/dlls/d3dx9_36/d3dx_helpers.h
@@ -394,6 +394,8 @@ static inline BOOL is_conversion_to_supported(const struct pixel_format_desc *fo
&& !is_unknown_format(format);
}
+HRESULT d3dx_validate_filter(uint32_t filter);
+
const struct pixel_format_desc *get_d3dx_pixel_format_info(enum d3dx_pixel_format_id format);
void format_to_d3dx_color(const struct pixel_format_desc *format, const BYTE *src, const PALETTEENTRY *palette,
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index 2896bd1f2b6..0873b686497 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -59,7 +59,7 @@ HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9 *texture,
if (!texture)
return D3DERR_INVALIDCALL;
- if (filter != D3DX_DEFAULT && FAILED(hr = d3dx9_validate_filter(filter)))
+ if (filter != D3DX_DEFAULT && FAILED(hr = d3dx_validate_filter(filter)))
return hr;
if (srclevel == D3DX_DEFAULT)
--
2.51.0

View File

@@ -1,69 +0,0 @@
From 167f1d10d28e0935feabf82b5d9f429cbef2001d Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Thu, 18 Sep 2025 13:18:04 -0400
Subject: [PATCH] d3dx10: Add support for custom texture dimension arguments in
D3DX10_IMAGE_LOAD_INFO.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 2 +-
dlls/d3dx10_43/texture.c | 23 ++++++++++++++---------
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 4be5d37d70d..8248461c970 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1077,7 +1077,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT
},
- E_FAIL, E_FAIL, .todo_hr = TRUE, .todo_process_hr = TRUE
+ E_FAIL, E_FAIL
},
/* Invalid filter value. */
{
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index bb1e1456fc2..fc9841cc279 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -645,12 +645,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (!data || !size)
return E_FAIL;
- if (load_info->Width != D3DX10_DEFAULT)
- FIXME("load_info->Width is ignored.\n");
- if (load_info->Height != D3DX10_DEFAULT)
- FIXME("load_info->Height is ignored.\n");
- if (load_info->Depth != D3DX10_DEFAULT)
- FIXME("load_info->Depth is ignored.\n");
if (load_info->FirstMipLevel != D3DX10_DEFAULT)
FIXME("load_info->FirstMipLevel is ignored.\n");
if (load_info->MipLevels != D3DX10_DEFAULT)
@@ -706,9 +700,20 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
}
/* Potentially round up width/height to align with block size. */
- load_info->Width = (img_info.Width + fmt_desc->block_width - 1) & ~(fmt_desc->block_width - 1);
- load_info->Height = (img_info.Height + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1);
- load_info->Depth = img_info.Depth;
+ if (!load_info->Width || load_info->Width == D3DX10_FROM_FILE || load_info->Width == D3DX10_DEFAULT)
+ load_info->Width = (img_info.Width + fmt_desc->block_width - 1) & ~(fmt_desc->block_width - 1);
+ if (!load_info->Height || load_info->Height == D3DX10_FROM_FILE || load_info->Height == D3DX10_DEFAULT)
+ load_info->Height = (img_info.Height + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1);
+ if (!load_info->Depth || load_info->Depth == D3DX10_FROM_FILE || load_info->Depth == D3DX10_DEFAULT)
+ load_info->Depth = img_info.Depth;
+
+ if ((load_info->Depth > 1) && (img_info.ResourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE3D))
+ {
+ ERR("Invalid depth value %u for image with dimension %d.\n", load_info->Depth, img_info.ResourceDimension);
+ hr = E_FAIL;
+ goto end;
+ }
+
load_info->MipLevels = img_info.MipLevels;
load_info->Format = img_info.Format;
--
2.51.0

View File

@@ -1,323 +0,0 @@
From c69ef561499aa26de02b67d3ef0df888e603b448 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Fri, 19 Sep 2025 10:48:28 -0400
Subject: [PATCH] d3dx10: Add support for generating mipmaps to
load_texture_data().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 3 +-
dlls/d3dx10_43/texture.c | 97 ++++++++++++++++++++++-------------
dlls/d3dx9_36/d3dx_helpers.c | 69 +++++++++++++++++++++++++
dlls/d3dx9_36/d3dx_helpers.h | 17 ++++++
4 files changed, 147 insertions(+), 39 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 8248461c970..6e5cc1bb146 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1104,7 +1104,7 @@ static const struct test_invalid_image_load_info
2, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, 2, (D3D10_USAGE)D3DX10_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7
},
- D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE
+ D3DERR_INVALIDCALL, D3DERR_INVALIDCALL
},
/*
* Usage/BindFlags/CpuAccessFlags are validated in the call to
@@ -1840,7 +1840,6 @@ static void check_resource_info(ID3D10Resource *resource, const struct test_imag
ok_(__FILE__, line)(desc_2d.Height == expected_height,
"Got unexpected Height %u, expected %u.\n",
desc_2d.Height, expected_height);
- todo_wine_if(expected_mip_levels != image->expected_info.MipLevels)
ok_(__FILE__, line)(desc_2d.MipLevels == expected_mip_levels,
"Got unexpected MipLevels %u, expected %u.\n",
desc_2d.MipLevels, expected_mip_levels);
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index fc9841cc279..3348911cdff 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -636,10 +636,11 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
D3D10_SUBRESOURCE_DATA **resource_data)
{
const struct pixel_format_desc *fmt_desc, *src_desc;
- uint32_t i, j, pixels_size, pixels_offset;
- uint8_t *res_data = NULL, *pixels_buffer;
+ struct d3dx_subresource_data *sub_rsrcs = NULL;
+ uint32_t loaded_mip_levels, max_mip_levels;
D3DX10_IMAGE_INFO img_info;
struct d3dx_image image;
+ unsigned int i, j;
HRESULT hr = S_OK;
if (!data || !size)
@@ -647,8 +648,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (load_info->FirstMipLevel != D3DX10_DEFAULT)
FIXME("load_info->FirstMipLevel is ignored.\n");
- if (load_info->MipLevels != D3DX10_DEFAULT)
- FIXME("load_info->MipLevels is ignored.\n");
if (load_info->Usage != D3DX10_DEFAULT)
FIXME("load_info->Usage is ignored.\n");
if (load_info->BindFlags != D3DX10_DEFAULT)
@@ -659,8 +658,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
FIXME("load_info->MiscFlags is ignored.\n");
if (load_info->Format != D3DX10_DEFAULT)
FIXME("load_info->Format is ignored.\n");
- if (load_info->MipFilter != D3DX10_DEFAULT)
- FIXME("load_info->MipFilter is ignored.\n");
*resource_data = NULL;
if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT)
@@ -714,64 +711,90 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
goto end;
}
- load_info->MipLevels = img_info.MipLevels;
+ max_mip_levels = d3dx_get_max_mip_levels_for_size(load_info->Width, load_info->Height, load_info->Depth);
+ if (!load_info->MipLevels || load_info->MipLevels == D3DX10_DEFAULT || load_info->MipLevels == D3DX10_FROM_FILE)
+ load_info->MipLevels = (load_info->MipLevels == D3DX10_FROM_FILE) ? img_info.MipLevels : max_mip_levels;
+ load_info->MipLevels = min(max_mip_levels, load_info->MipLevels);
load_info->Format = img_info.Format;
- pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, load_info->Width, load_info->Height,
- load_info->Depth, load_info->MipLevels) * img_info.ArraySize;
- pixels_offset = (sizeof(**resource_data) * load_info->MipLevels * img_info.ArraySize);
- if (!(res_data = malloc(pixels_size + pixels_offset)))
- {
- hr = E_OUTOFMEMORY;
+ 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))
goto end;
- }
-
- pixels_buffer = res_data + pixels_offset;
- *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
src_desc = get_d3dx_pixel_format_info(image.format);
+ loaded_mip_levels = min(img_info.MipLevels, load_info->MipLevels);
for (i = 0; i < img_info.ArraySize; ++i)
{
struct volume dst_size = { load_info->Width, load_info->Height, load_info->Depth };
- for (j = 0; j < load_info->MipLevels; ++j)
+ for (j = 0; j < loaded_mip_levels; ++j)
{
+ struct d3dx_subresource_data *sub_rsrc = &sub_rsrcs[i * load_info->MipLevels + j];
const RECT unaligned_rect = { 0, 0, dst_size.width, dst_size.height };
struct d3dx_pixels src_pixels, dst_pixels;
- uint32_t dst_row_pitch, dst_slice_pitch;
hr = d3dx_image_get_pixels(&image, i, j, &src_pixels);
if (FAILED(hr))
- break;
+ goto end;
- hr = d3dx_calculate_pixels_size(fmt_desc->format, dst_size.width, dst_size.height, &dst_row_pitch,
- &dst_slice_pitch);
- if (FAILED(hr))
- break;
-
- set_d3dx_pixels(&dst_pixels, pixels_buffer, dst_row_pitch, dst_slice_pitch, NULL, dst_size.width,
+ set_d3dx_pixels(&dst_pixels, sub_rsrc->data, sub_rsrc->row_pitch, sub_rsrc->slice_pitch, NULL, dst_size.width,
dst_size.height, dst_size.depth, &unaligned_rect);
hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, load_info->Filter, 0);
if (FAILED(hr))
- break;
+ goto end;
- (*resource_data)[i * load_info->MipLevels + j].pSysMem = pixels_buffer;
- (*resource_data)[i * load_info->MipLevels + j].SysMemPitch = dst_row_pitch;
- (*resource_data)[i * load_info->MipLevels + j].SysMemSlicePitch = dst_slice_pitch;
-
- pixels_buffer += dst_slice_pitch * dst_size.depth;
d3dx_get_next_mip_level_size(&dst_size);
}
}
- if (FAILED(hr))
+ if (loaded_mip_levels < load_info->MipLevels)
{
- *resource_data = NULL;
- goto end;
+ struct volume base_level_size = { load_info->Width, load_info->Height, load_info->Depth };
+ const uint32_t base_level = loaded_mip_levels - 1;
+
+ if (!load_info->MipFilter || load_info->MipFilter == D3DX10_DEFAULT)
+ load_info->MipFilter = D3DX10_FILTER_LINEAR;
+ if (FAILED(hr = d3dx_validate_filter(load_info->MipFilter)))
+ {
+ ERR("Invalid mip filter argument %#x.\n", load_info->MipFilter);
+ goto end;
+ }
+
+ d3dx_get_mip_level_size(&base_level_size, base_level);
+ for (i = 0; i < img_info.ArraySize; ++i)
+ {
+ struct volume src_size, dst_size;
+
+ src_size = dst_size = base_level_size;
+ for (j = base_level; j < (load_info->MipLevels - 1); ++j)
+ {
+ struct d3dx_subresource_data *dst_data = &sub_rsrcs[i * load_info->MipLevels + j + 1];
+ struct d3dx_subresource_data *src_data = &sub_rsrcs[i * load_info->MipLevels + j];
+ const RECT src_unaligned_rect = { 0, 0, src_size.width, src_size.height };
+ struct d3dx_pixels src_pixels, dst_pixels;
+ RECT dst_unaligned_rect;
+
+ d3dx_get_next_mip_level_size(&dst_size);
+ SetRect(&dst_unaligned_rect, 0, 0, dst_size.width, dst_size.height);
+ set_d3dx_pixels(&dst_pixels, dst_data->data, dst_data->row_pitch, dst_data->slice_pitch, NULL,
+ dst_size.width, dst_size.height, dst_size.depth, &dst_unaligned_rect);
+ set_d3dx_pixels(&src_pixels, src_data->data, src_data->row_pitch, src_data->slice_pitch, NULL,
+ src_size.width, src_size.height, src_size.depth, &src_unaligned_rect);
+
+ hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, load_info->MipFilter, 0);
+ if (FAILED(hr))
+ goto end;
+
+ src_size = dst_size;
+ }
+ }
}
- res_data = NULL;
+ *resource_data = (D3D10_SUBRESOURCE_DATA *)sub_rsrcs;
+ sub_rsrcs = NULL;
+
load_info->Usage = D3D10_USAGE_DEFAULT;
load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE;
load_info->CpuAccessFlags = 0;
@@ -781,7 +804,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
end:
d3dx_image_cleanup(&image);
- free(res_data);
+ free(sub_rsrcs);
return hr;
}
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c
index ddd208913af..7cfa85e1e1f 100644
--- a/dlls/d3dx9_36/d3dx_helpers.c
+++ b/dlls/d3dx9_36/d3dx_helpers.c
@@ -439,6 +439,28 @@ void d3dx_get_next_mip_level_size(struct volume *size)
size->depth = max(size->depth / 2, 1);
}
+void d3dx_get_mip_level_size(struct volume *size, uint32_t level)
+{
+ uint32_t i;
+
+ for (i = 0; i < level; ++i)
+ d3dx_get_next_mip_level_size(size);
+}
+
+uint32_t d3dx_get_max_mip_levels_for_size(uint32_t width, uint32_t height, uint32_t depth)
+{
+ struct volume tmp = { width, height, depth };
+ uint32_t mip_levels = 1;
+
+ while (!(tmp.width == 1 && tmp.height == 1 && tmp.depth == 1))
+ {
+ d3dx_get_next_mip_level_size(&tmp);
+ mip_levels++;
+ }
+
+ return mip_levels;
+}
+
static const char *debug_volume(const struct volume *volume)
{
if (!volume)
@@ -3130,3 +3152,50 @@ void get_aligned_rect(uint32_t left, uint32_t top, uint32_t right, uint32_t bott
aligned_rect->bottom = min((aligned_rect->bottom + fmt_desc->block_height - 1)
& ~(fmt_desc->block_height - 1), height);
}
+
+HRESULT d3dx_create_subresource_data_for_texture(uint32_t width, uint32_t height, uint32_t depth,
+ uint32_t mip_levels, uint32_t layer_count, const struct pixel_format_desc *fmt_desc,
+ struct d3dx_subresource_data **out_sub_rsrc_data)
+{
+ struct d3dx_subresource_data *sub_rsrcs = NULL;
+ uint8_t *sub_rsrc_data = NULL, *pixels_ptr;
+ uint32_t pixels_size, pixels_offset;
+ unsigned int i, j;
+ HRESULT hr = S_OK;
+
+ *out_sub_rsrc_data = NULL;
+ pixels_offset = sizeof(*sub_rsrcs) * mip_levels * layer_count;
+ pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, width, height, depth, mip_levels) * layer_count;
+ if (!(sub_rsrc_data = malloc(pixels_size + pixels_offset)))
+ return E_OUTOFMEMORY;
+
+ sub_rsrcs = (struct d3dx_subresource_data *)sub_rsrc_data;
+ pixels_ptr = sub_rsrc_data + pixels_offset;
+ for (i = 0; i < layer_count; ++i)
+ {
+ struct volume size = { width, height, depth };
+
+ for (j = 0; j < mip_levels; ++j)
+ {
+ uint32_t row_pitch, slice_pitch;
+
+ hr = d3dx_calculate_pixels_size(fmt_desc->format, size.width, size.height, &row_pitch, &slice_pitch);
+ if (FAILED(hr))
+ goto exit;
+
+ sub_rsrcs[i * mip_levels + j].data = pixels_ptr;
+ sub_rsrcs[i * mip_levels + j].row_pitch = row_pitch;
+ sub_rsrcs[i * mip_levels + j].slice_pitch = slice_pitch;
+
+ pixels_ptr += slice_pitch * size.depth;
+ d3dx_get_next_mip_level_size(&size);
+ }
+ }
+
+ *out_sub_rsrc_data = sub_rsrcs;
+ sub_rsrc_data = NULL;
+
+exit:
+ free(sub_rsrc_data);
+ return hr;
+}
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h
index c7292990799..ee189a3a79c 100644
--- a/dlls/d3dx9_36/d3dx_helpers.h
+++ b/dlls/d3dx9_36/d3dx_helpers.h
@@ -396,6 +396,8 @@ void format_from_d3dx_color(const struct pixel_format_desc *format, const struct
enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format);
void d3dx_get_next_mip_level_size(struct volume *size);
+void d3dx_get_mip_level_size(struct volume *size, uint32_t level);
+uint32_t d3dx_get_max_mip_levels_for_size(uint32_t width, uint32_t height, uint32_t depth);
HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
uint32_t *pitch, uint32_t *size);
uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height,
@@ -430,6 +432,21 @@ struct d3dx_buffer_wrapper
HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc,
enum d3dx_image_file_format file_format, const struct d3dx_buffer_wrapper *wrapper, struct d3dx_buffer *dst_buffer);
+/*
+ * Structure that is able to be cast to D3D10_SUBRESOURCE_DATA and
+ * D3D11_SUBRESOURCE_DATA.
+ */
+struct d3dx_subresource_data
+{
+ const void *data;
+ UINT row_pitch;
+ UINT slice_pitch;
+};
+
+HRESULT d3dx_create_subresource_data_for_texture(uint32_t width, uint32_t height, uint32_t depth,
+ uint32_t mip_levels, uint32_t layer_count, const struct pixel_format_desc *fmt_desc,
+ struct d3dx_subresource_data **out_sub_rsrc_data);
+
/* debug helpers */
const char *debug_d3dx_image_file_format(enum d3dx_image_file_format format);
#endif /* __WINE_D3DX_HELPERS_H */
--
2.51.0

View File

@@ -1,50 +0,0 @@
From e851890d08e8b98fc1efc1c28b96244546a63e0c Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Fri, 19 Sep 2025 10:52:08 -0400
Subject: [PATCH] d3dx10: Add support for the format field in
D3DX10_IMAGE_LOAD_INFO.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/texture.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 3348911cdff..302efeccac1 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -656,8 +656,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
FIXME("load_info->CpuAccessFlags is ignored.\n");
if (load_info->MiscFlags != D3DX10_DEFAULT)
FIXME("load_info->MiscFlags is ignored.\n");
- if (load_info->Format != D3DX10_DEFAULT)
- FIXME("load_info->Format is ignored.\n");
*resource_data = NULL;
if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT)
@@ -688,10 +686,12 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
goto end;
}
- fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(img_info.Format));
+ if (load_info->Format == D3DX10_DEFAULT || load_info->Format == DXGI_FORMAT_FROM_FILE)
+ load_info->Format = img_info.Format;
+ fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(load_info->Format));
if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT)
{
- FIXME("Unknown DXGI format supplied, %#x.\n", img_info.Format);
+ FIXME("Unknown DXGI format supplied, %#x.\n", load_info->Format);
hr = E_NOTIMPL;
goto end;
}
@@ -715,7 +715,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (!load_info->MipLevels || load_info->MipLevels == D3DX10_DEFAULT || load_info->MipLevels == D3DX10_FROM_FILE)
load_info->MipLevels = (load_info->MipLevels == D3DX10_FROM_FILE) ? img_info.MipLevels : max_mip_levels;
load_info->MipLevels = min(max_mip_levels, load_info->MipLevels);
- load_info->Format = img_info.Format;
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);
--
2.51.0

View File

@@ -1,68 +0,0 @@
From 1a2093da3b46e635f99bb09d1c0ec336d8206b66 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Fri, 19 Sep 2025 11:37:58 -0400
Subject: [PATCH] d3dx10: Handle FirstMipLevel argument in load_texture_data().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 2 +-
dlls/d3dx10_43/texture.c | 9 +++++----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 6e5cc1bb146..2f26f8e14f1 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -4247,7 +4247,7 @@ static void test_create_texture(void)
for (mip_level = 0; mip_level < 4; ++mip_level)
{
winetest_push_context("MipLevel %u", mip_level);
- todo_wine_if(i && mip_level != 3) check_texture_sub_resource_color(tex_2d, mip_level, NULL,
+ check_texture_sub_resource_color(tex_2d, mip_level, NULL,
dds_24bit_8_8_mip_level_expected[min(3, mip_level + i)], 0);
winetest_pop_context();
}
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index 302efeccac1..cd5fc112110 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -646,8 +646,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (!data || !size)
return E_FAIL;
- if (load_info->FirstMipLevel != D3DX10_DEFAULT)
- FIXME("load_info->FirstMipLevel is ignored.\n");
if (load_info->Usage != D3DX10_DEFAULT)
FIXME("load_info->Usage is ignored.\n");
if (load_info->BindFlags != D3DX10_DEFAULT)
@@ -686,6 +684,9 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
goto end;
}
+ if (load_info->FirstMipLevel == D3DX10_DEFAULT || (load_info->FirstMipLevel >= img_info.MipLevels))
+ load_info->FirstMipLevel = 0;
+
if (load_info->Format == D3DX10_DEFAULT || load_info->Format == DXGI_FORMAT_FROM_FILE)
load_info->Format = img_info.Format;
fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(load_info->Format));
@@ -722,7 +723,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
goto end;
src_desc = get_d3dx_pixel_format_info(image.format);
- loaded_mip_levels = min(img_info.MipLevels, load_info->MipLevels);
+ loaded_mip_levels = min((img_info.MipLevels - load_info->FirstMipLevel), load_info->MipLevels);
for (i = 0; i < img_info.ArraySize; ++i)
{
struct volume dst_size = { load_info->Width, load_info->Height, load_info->Depth };
@@ -733,7 +734,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
const RECT unaligned_rect = { 0, 0, dst_size.width, dst_size.height };
struct d3dx_pixels src_pixels, dst_pixels;
- hr = d3dx_image_get_pixels(&image, i, j, &src_pixels);
+ hr = d3dx_image_get_pixels(&image, i, j + load_info->FirstMipLevel, &src_pixels);
if (FAILED(hr))
goto end;
--
2.51.0

View File

@@ -1,109 +0,0 @@
From ee999e236f7de9c21cc6cdd9d1e2ecfe85ee43e7 Mon Sep 17 00:00:00 2001
From: Connor McAdams <cmcadams@codeweavers.com>
Date: Fri, 19 Sep 2025 11:45:26 -0400
Subject: [PATCH] d3dx10: Pass D3DX10_IMAGE_LOAD_INFO texture creation
arguments through in load_texture_data().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
---
dlls/d3dx10_43/tests/d3dx10.c | 12 ++++++------
dlls/d3dx10_43/texture.c | 18 +++++-------------
2 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c
index 2f26f8e14f1..c6cd1fa88cd 100644
--- a/dlls/d3dx10_43/tests/d3dx10.c
+++ b/dlls/d3dx10_43/tests/d3dx10.c
@@ -1034,7 +1034,7 @@ test_image_load_info[] =
(D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET), 0,
(D3D10_RESOURCE_MISC_GENERATE_MIPS | D3D10_RESOURCE_MISC_TEXTURECUBE) } },
{ 4, 4, 1, 6, 3, DDS_RESOURCE_MISC_TEXTURECUBE, DXGI_FORMAT_BC1_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D,
- D3DX10_IFF_DDS }, .todo_resource_desc = TRUE,
+ D3DX10_IFF_DDS }
},
/*
* Even with the autogen mips misc flag specified, the mip levels argument
@@ -1050,7 +1050,7 @@ test_image_load_info[] =
(D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET), 0,
(D3D10_RESOURCE_MISC_GENERATE_MIPS | D3D10_RESOURCE_MISC_TEXTURECUBE) } },
{ 4, 4, 1, 6, 3, DDS_RESOURCE_MISC_TEXTURECUBE, DXGI_FORMAT_BC1_UNORM, D3D10_RESOURCE_DIMENSION_TEXTURE2D,
- D3DX10_IFF_DDS }, .todo_resource_desc = TRUE,
+ D3DX10_IFF_DDS }
},
};
@@ -1116,7 +1116,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_CPU_ACCESS_READ, D3D10_USAGE_DYNAMIC,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT
},
- E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE,
+ E_INVALIDARG, S_OK, E_INVALIDARG
},
{
test_dds_32bpp, sizeof(test_dds_32bpp),
@@ -1124,7 +1124,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT,
D3D10_BIND_DEPTH_STENCIL, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT
},
- E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE,
+ E_INVALIDARG, S_OK, E_INVALIDARG
},
/*
* D3D10_RESOURCE_MISC_GENERATE_MIPS requires binding as a shader resource
@@ -1136,7 +1136,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_GENERATE_MIPS, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT
},
- E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE,
+ E_INVALIDARG, S_OK, E_INVALIDARG
},
/* Can't set the cube texture flag if the image isn't a cube texture. */
{
@@ -1145,7 +1145,7 @@ static const struct test_invalid_image_load_info
D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT,
D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_TEXTURECUBE, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT
},
- E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE,
+ E_INVALIDARG, S_OK, E_INVALIDARG
},
};
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c
index cd5fc112110..80f17fdde0f 100644
--- a/dlls/d3dx10_43/texture.c
+++ b/dlls/d3dx10_43/texture.c
@@ -646,15 +646,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (!data || !size)
return E_FAIL;
- if (load_info->Usage != D3DX10_DEFAULT)
- FIXME("load_info->Usage is ignored.\n");
- if (load_info->BindFlags != D3DX10_DEFAULT)
- FIXME("load_info->BindFlags is ignored.\n");
- if (load_info->CpuAccessFlags != D3DX10_DEFAULT)
- FIXME("load_info->CpuAccessFlags is ignored.\n");
- if (load_info->MiscFlags != D3DX10_DEFAULT)
- FIXME("load_info->MiscFlags is ignored.\n");
-
*resource_data = NULL;
if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT)
load_info->Filter = D3DX10_FILTER_TRIANGLE | D3DX10_FILTER_DITHER;
@@ -795,10 +786,11 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
*resource_data = (D3D10_SUBRESOURCE_DATA *)sub_rsrcs;
sub_rsrcs = NULL;
- load_info->Usage = D3D10_USAGE_DEFAULT;
- load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE;
- load_info->CpuAccessFlags = 0;
- load_info->MiscFlags = img_info.MiscFlags;
+ load_info->Usage = (load_info->Usage == D3DX10_DEFAULT) ? D3D10_USAGE_DEFAULT : load_info->Usage;
+ load_info->BindFlags = (load_info->BindFlags == D3DX10_DEFAULT) ? D3D10_BIND_SHADER_RESOURCE : load_info->BindFlags;
+ load_info->CpuAccessFlags = (load_info->CpuAccessFlags == D3DX10_DEFAULT) ? 0 : load_info->CpuAccessFlags;
+ load_info->MiscFlags = (load_info->MiscFlags == D3DX10_DEFAULT) ? 0 : load_info->MiscFlags;
+ load_info->MiscFlags |= img_info.MiscFlags;
if (load_info->pSrcInfo)
*load_info->pSrcInfo = img_info;
--
2.51.0

View File

@@ -1 +1,2 @@
Fixes: [45533] - Implement D3DX11CreateTextureFromMemory
Disabled: True

View File

@@ -1,220 +0,0 @@
From 7ba5e4a89be15deeb704078ad8321c7cc5aa02eb Mon Sep 17 00:00:00 2001
From: Christian Costa <titan.costa@gmail.com>
Date: Mon, 22 Jul 2013 21:51:20 +0200
Subject: [PATCH] d3dx9_36: Implement ID3DXSkinInfoImpl_UpdateSkinnedMesh.
This patch fixes last problem of bug 32572.
---
dlls/d3dx9_36/skin.c | 86 ++++++++++++++++++++++++++++++++++++--
dlls/d3dx9_36/tests/mesh.c | 83 ++++++++++++++++++++++++++++++++++++
2 files changed, 166 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx9_36/skin.c b/dlls/d3dx9_36/skin.c
index b81fb6863d3..75ee6d44a95 100644
--- a/dlls/d3dx9_36/skin.c
+++ b/dlls/d3dx9_36/skin.c
@@ -2,6 +2,7 @@
* Skin Info operations specific to D3DX9.
*
* Copyright (C) 2011 Dylan Smith
+ * Copyright (C) 2013 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -399,10 +400,89 @@ static HRESULT WINAPI d3dx9_skin_info_GetDeclaration(ID3DXSkinInfo *iface,
static HRESULT WINAPI d3dx9_skin_info_UpdateSkinnedMesh(ID3DXSkinInfo *iface, const D3DXMATRIX *bone_transforms,
const D3DXMATRIX *bone_inv_transpose_transforms, const void *src_vertices, void *dst_vertices)
{
- FIXME("iface %p, bone_transforms %p, bone_inv_transpose_transforms %p, src_vertices %p, dst_vertices %p stub!\n",
- iface, bone_transforms, bone_inv_transpose_transforms, src_vertices, dst_vertices);
+ struct d3dx9_skin_info *skin = impl_from_ID3DXSkinInfo(iface);
+ DWORD size = D3DXGetFVFVertexSize(skin->fvf);
+ DWORD i, j;
- return E_NOTIMPL;
+ TRACE("iface %p, bone_transforms %p, bone_inv_transpose_transforms %p, src_vertices %p, dst_vertices %p\n",
+ skin, bone_transforms, bone_inv_transpose_transforms, src_vertices, dst_vertices);
+
+ if (bone_inv_transpose_transforms)
+ FIXME("Skinning vertices with two position elements not supported\n");
+
+ if ((skin->fvf & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) {
+ FIXME("Vertex type %#lx not supported\n", skin->fvf & D3DFVF_POSITION_MASK);
+ return E_FAIL;
+ }
+
+ /* Reset all positions */
+ for (i = 0; i < skin->num_vertices; i++) {
+ D3DXVECTOR3 *position = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * i);
+ position->x = 0.0f;
+ position->y = 0.0f;
+ position->z = 0.0f;
+ }
+
+ /* Update positions that are influenced by bones */
+ for (i = 0; i < skin->num_bones; i++) {
+ D3DXMATRIX bone_inverse, matrix;
+
+ D3DXMatrixInverse(&bone_inverse, NULL, &skin->bones[i].transform);
+ D3DXMatrixMultiply(&matrix, &bone_transforms[i], &bone_inverse);
+ D3DXMatrixMultiply(&matrix, &matrix, &skin->bones[i].transform);
+
+ for (j = 0; j < skin->bones[i].num_influences; j++) {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 *position_src = (D3DXVECTOR3*)((BYTE*)src_vertices + size * skin->bones[i].vertices[j]);
+ D3DXVECTOR3 *position_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * skin->bones[i].vertices[j]);
+ FLOAT weight = skin->bones[i].weights[j];
+
+ D3DXVec3TransformCoord(&position, position_src, &matrix);
+ position_dest->x += weight * position.x;
+ position_dest->y += weight * position.y;
+ position_dest->z += weight * position.z;
+ }
+ }
+
+ if (skin->fvf & D3DFVF_NORMAL) {
+ /* Reset all normals */
+ for (i = 0; i < skin->num_vertices; i++) {
+ D3DXVECTOR3 *normal = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * i + sizeof(D3DXVECTOR3));
+ normal->x = 0.0f;
+ normal->y = 0.0f;
+ normal->z = 0.0f;
+ }
+
+ /* Update normals that are influenced by bones */
+ for (i = 0; i < skin->num_bones; i++) {
+ D3DXMATRIX bone_inverse, matrix;
+
+ D3DXMatrixInverse(&bone_inverse, NULL, &skin->bones[i].transform);
+ D3DXMatrixMultiply(&matrix, &skin->bones[i].transform, &bone_transforms[i]);
+
+ for (j = 0; j < skin->bones[i].num_influences; j++) {
+ D3DXVECTOR3 normal;
+ D3DXVECTOR3 *normal_src = (D3DXVECTOR3*)((BYTE*)src_vertices + size * skin->bones[i].vertices[j] + sizeof(D3DXVECTOR3));
+ D3DXVECTOR3 *normal_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * skin->bones[i].vertices[j] + sizeof(D3DXVECTOR3));
+ FLOAT weight = skin->bones[i].weights[j];
+
+ D3DXVec3TransformNormal(&normal, normal_src, &bone_inverse);
+ D3DXVec3TransformNormal(&normal, &normal, &matrix);
+ normal_dest->x += weight * normal.x;
+ normal_dest->y += weight * normal.y;
+ normal_dest->z += weight * normal.z;
+ }
+ }
+
+ /* Normalize all normals that are influenced by bones*/
+ for (i = 0; i < skin->num_vertices; i++) {
+ D3DXVECTOR3 *normal_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + (i * size) + sizeof(D3DXVECTOR3));
+ if ((normal_dest->x != 0.0f) && (normal_dest->y != 0.0f) && (normal_dest->z != 0.0f))
+ D3DXVec3Normalize(normal_dest, normal_dest);
+ }
+ }
+
+ return D3D_OK;
}
static HRESULT WINAPI d3dx9_skin_info_ConvertToBlendedMesh(ID3DXSkinInfo *iface, ID3DXMesh *mesh_in,
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c
index 1daec158a5f..64b02276843 100644
--- a/dlls/d3dx9_36/tests/mesh.c
+++ b/dlls/d3dx9_36/tests/mesh.c
@@ -5241,6 +5241,88 @@ static void test_create_skin_info(void)
ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#lx\n", hr);
}
+static void test_update_skinned_mesh(void)
+{
+ static DWORD bone0_vertices[2] = { 1, 3 };
+ static FLOAT bone0_weights[2] = { 1.0f, 0.5f };
+ static DWORD bone1_vertices[2] = { 2, 3 };
+ static FLOAT bone1_weights[2] = { 1.0f, 0.5f };
+ static D3DMATRIX bones_matrix[2] =
+ { { { {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 2.0f, 2.0f, 4.0f, 1.0f
+ } } },
+ { { {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -4.0f, -4.0f, 4.0f, 1.0f
+ } } } };
+ static D3DVECTOR vertices_src[] = {{ 1.0f, 1.0f, 1.0f },
+ { 1.0f, 0.0f, 0.0f },
+ { 1.0f, 1.0f, -1.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { -1.0f, -1.0f, 1.0f },
+ { 0.0f, 0.0f, 1.0f },
+ { -1.0f, -1.0f, -1.0f },
+ { -1.0f, 0.0f, 0.0f },
+ };
+ static D3DVECTOR vertices_ref[] = {{ 0.0f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 0.0f },
+ { 3.0f, 3.0f, 3.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { -5.0f, -5.0f, 5.0f },
+ { 0.0f, 0.0f, 1.0f },
+ { -2.0f, -2.0f, 3.0f },
+ { -1.0f, 0.0f, 0.0f },
+ };
+ D3DVECTOR vertices_dest[8];
+ HRESULT hr;
+ ID3DXSkinInfo *skin_info;
+ D3DXMATRIX matrix;
+ int i;
+
+ D3DXMatrixIdentity(&matrix);
+ for (i = 0; i < 8; i++)
+ {
+ vertices_dest[i].x = 10000.0f;
+ vertices_dest[i].y = 10000.0f;
+ vertices_dest[i].z = 10000.0f;
+ }
+
+ hr = D3DXCreateSkinInfoFVF(4, D3DFVF_XYZ | D3DFVF_NORMAL, 2, &skin_info);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+
+ skin_info->lpVtbl->SetBoneInfluence(skin_info, 0, 2, bone0_vertices, bone0_weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+ skin_info->lpVtbl->SetBoneOffsetMatrix(skin_info, 0, &matrix);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+ skin_info->lpVtbl->SetBoneInfluence(skin_info, 1, 2, bone1_vertices, bone1_weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+ skin_info->lpVtbl->SetBoneOffsetMatrix(skin_info, 1, &matrix);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+ skin_info->lpVtbl->UpdateSkinnedMesh(skin_info, bones_matrix, NULL, vertices_src, vertices_dest);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#lx\n", hr);
+ for (i = 0; i < 4; i++)
+ {
+ ok(compare(vertices_dest[i*2].x, vertices_ref[i*2].x), "Vertex[%d].position.x: got %g, expected %g\n",
+ i, vertices_dest[i*2].x, vertices_ref[i*2].x);
+ ok(compare(vertices_dest[i*2].y, vertices_ref[i*2].y), "Vertex[%d].position.y: got %g, expected %g\n",
+ i, vertices_dest[i*2].y, vertices_ref[i*2].y);
+ ok(compare(vertices_dest[i*2].z, vertices_ref[i*2].z), "Vertex[%d].position.z: got %g, expected %g\n",
+ i, vertices_dest[i*2].z, vertices_ref[i*2].z);
+ ok(compare(vertices_dest[i*2+1].x, vertices_ref[i*2+1].x), "Vertex[%d].normal.x: got %g, expected %g\n",
+ i, vertices_dest[i*2+1].x, vertices_ref[i*2+1].x);
+ ok(compare(vertices_dest[i*2+1].y, vertices_ref[i*2+1].y), "Vertex[%d].normal.y: got %g, expected %g\n",
+ i, vertices_dest[i*2+1].y, vertices_ref[i*2+1].y);
+ ok(compare(vertices_dest[i*2+1].z, vertices_ref[i*2+1].z), "Vertex[%d].normal.z: got %g, expected %g\n",
+ i, vertices_dest[i*2+1].z, vertices_ref[i*2+1].z);
+ }
+ skin_info->lpVtbl->Release(skin_info);
+}
+
static void test_convert_adjacency_to_point_reps(void)
{
HRESULT hr;
@@ -11484,6 +11566,7 @@ START_TEST(mesh)
D3DXGenerateAdjacencyTest();
test_update_semantics();
test_create_skin_info();
+ test_update_skinned_mesh();
test_convert_adjacency_to_point_reps();
test_convert_point_reps_to_adjacency();
test_weld_vertices();
--
2.38.1

View File

@@ -1 +0,0 @@
Fixes: [32572] Support for ID3DXSkinInfoImpl_UpdateSkinnedMesh

View File

@@ -1 +1 @@
7fb9d22a7932aaf32383ecebb59487d57a503754
bcd3e1a4de9d6efb177b932a937412bfb962d149