These patches implement the existing functionality of `load_texture_data()` using shared code.
From: Connor McAdams cmcadams@codeweavers.com
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...
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 112 +++++++++++++++++++++++++++++++++- dlls/d3dx9_36/d3dx_helpers.c | 16 +++-- dlls/d3dx9_36/d3dx_helpers.h | 4 ++ 4 files changed, 126 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 9428787099f..3ec21ccc7bf 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 9d0d6063a0b..e3a41ddeec8 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -874,6 +874,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; + BYTE *res_data = NULL, *pixels_buffer; + uint32_t pixels_size, pixels_offset; + unsigned int i, j; + HRESULT hr = S_OK; + + if (img_info->ImageFileFormat == D3DX10_IFF_BMP) + return E_NOTIMPL; + + tmp_load_info.Format = img_info->Format; + fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(tmp_load_info.Format)); + if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT) + { + FIXME("Unknown DXGI format supplied, %#x.\n", tmp_load_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; + + 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->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) { @@ -886,9 +973,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) @@ -916,15 +1007,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 57ca8f1c0a7..41d6db1edc8 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -383,7 +383,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) { @@ -423,7 +423,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); @@ -437,7 +437,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); @@ -1188,9 +1188,15 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src expected_src_data_size = (image->layer_pitch * image->layer_count) + header_size; if (src_data_size < expected_src_data_size) { + const uint32_t dxt10_info_only_flags = D3DX_IMAGE_INFO_ONLY | D3DX_IMAGE_SUPPORT_DXT10; + WARN("File is too short %u, expected at least %u bytes.\n", src_data_size, expected_src_data_size); - /* D3DX10/D3DX11 do not validate the size of the pixels, only the header. */ - if (!(flags & D3DX_IMAGE_SUPPORT_DXT10)) + /* + * D3DX10/D3DX11 do not validate the size of the pixels, only the header. + * However, if we're loading the image data, don't match native + * behavior. + */ + if ((flags & dxt10_info_only_flags) != dxt10_info_only_flags) return D3DXERR_INVALIDDATA; }
diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index a840f99b46e..0126dcd3f1b 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -399,6 +399,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,
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/texture.c | 3 --- dlls/d3dx9_36/d3dx_helpers.c | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index e3a41ddeec8..068795879be 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -884,9 +884,6 @@ static HRESULT d3dx_load_texture_data(struct d3dx_image *image, D3DX10_IMAGE_LOA unsigned int i, j; HRESULT hr = S_OK;
- if (img_info->ImageFileFormat == D3DX10_IFF_BMP) - return E_NOTIMPL; - tmp_load_info.Format = img_info->Format; fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(tmp_load_info.Format)); if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT) diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 41d6db1edc8..1224a6dd303 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -1499,7 +1499,8 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src break; }
- if (image_is_argb(bitmap_frame, image)) + /* D3DX10/D3DX11 ignore alpha channels in X8 bitmaps. */ + if (!(flags & D3DX_IMAGE_SUPPORT_DXT10) && image_is_argb(bitmap_frame, image)) image->format = D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM;
if (!(flags & D3DX_IMAGE_INFO_ONLY))
From: Connor McAdams cmcadams@codeweavers.com
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 068795879be..9792960cad1 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -114,6 +114,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 1224a6dd303..b199fc87e52 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 }, @@ -396,6 +397,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; @@ -2581,6 +2583,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 0126dcd3f1b..42b40c1c279 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,
From: Connor McAdams cmcadams@codeweavers.com
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 b199fc87e52..6ced4b9f62e 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -2817,6 +2817,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; @@ -2846,6 +2856,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
From: Connor McAdams cmcadams@codeweavers.com
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 9792960cad1..0be79fb922d 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -806,32 +806,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) { @@ -962,12 +936,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; @@ -1031,6 +1003,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; @@ -1040,122 +1016,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; @@ -1169,10 +1055,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 6ced4b9f62e..58b048444db 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -414,6 +414,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;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/texture.c | 413 ++++++--------------------------------- 1 file changed, 59 insertions(+), 354 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 0be79fb922d..85459cc9a56 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -22,13 +22,10 @@
#include "d3d10_1.h" #include "d3dx10.h" -#include "wincodec.h" #include "dxhelpers.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
-HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT sdk_version, IWICImagingFactory **imaging_factory); - /* * These are mappings from legacy DDS header formats to DXGI formats. Some * don't map to a DXGI_FORMAT at all, and some only map to the default format. @@ -173,179 +170,6 @@ static D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_fo } }
-static const struct -{ - const GUID *wic_guid; - DXGI_FORMAT dxgi_format; -} -wic_pixel_formats[] = -{ - { &GUID_WICPixelFormatBlackWhite, DXGI_FORMAT_R1_UNORM }, - { &GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM }, - { &GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM }, - { &GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM }, - { &GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT }, - { &GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT }, - { &GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM }, - { &GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM }, - { &GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, - { &GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, - { &GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM }, - { &GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM }, - { &GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, - { &GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM }, - { &GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT }, - { &GUID_WICPixelFormat96bppRGBFloat, DXGI_FORMAT_R32G32B32_FLOAT }, - { &GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT } -}; - -static const GUID *dxgi_format_to_wic_guid(DXGI_FORMAT format) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); ++i) - { - if (wic_pixel_formats[i].dxgi_format == format) - return wic_pixel_formats[i].wic_guid; - } - - return NULL; -} - -static unsigned int get_bpp_from_format(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - return 128; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - return 96; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - return 64; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_YUY2: - return 32; - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - return 24; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_B4G4R4A4_UNORM: - return 16; - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_NV11: - return 12; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 8; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - return 4; - case DXGI_FORMAT_R1_UNORM: - return 1; - default: - return 0; - } -} - HRESULT WINAPI D3DX10GetImageInfoFromFileA(const char *src_file, ID3DX10ThreadPump *pump, D3DX10_IMAGE_INFO *info, HRESULT *result) { @@ -806,146 +630,16 @@ void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info, D3DX10_IMAGE_LOAD_I out->pSrcInfo = NULL; }
-static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode *frame, - const GUID *dst_format, unsigned int stride, unsigned int frame_size, BYTE *buffer) -{ - IWICFormatConverter *converter; - BOOL can_convert; - GUID src_format; - HRESULT hr; - - if (FAILED(hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &src_format))) - return hr; - - if (IsEqualGUID(&src_format, dst_format)) - { - if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer))) - return hr; - return S_OK; - } - - if (FAILED(hr = IWICImagingFactory_CreateFormatConverter(factory, &converter))) - return hr; - if (FAILED(hr = IWICFormatConverter_CanConvert(converter, &src_format, dst_format, &can_convert))) - { - IWICFormatConverter_Release(converter); - return hr; - } - if (!can_convert) - { - WARN("Format converting %s to %s is not supported by WIC.\n", - debugstr_guid(&src_format), debugstr_guid(dst_format)); - IWICFormatConverter_Release(converter); - return E_NOTIMPL; - } - if (FAILED(hr = IWICFormatConverter_Initialize(converter, (IWICBitmapSource *)frame, dst_format, - WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom))) - { - IWICFormatConverter_Release(converter); - return hr; - } - hr = IWICFormatConverter_CopyPixels(converter, NULL, stride, frame_size, buffer); - IWICFormatConverter_Release(converter); - 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) +HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, + D3D10_SUBRESOURCE_DATA **resource_data) { const struct pixel_format_desc *fmt_desc, *src_desc; - D3DX10_IMAGE_LOAD_INFO tmp_load_info = *load_info; BYTE *res_data = NULL, *pixels_buffer; uint32_t pixels_size, pixels_offset; - unsigned int i, j; - HRESULT hr = S_OK; - - tmp_load_info.Format = img_info->Format; - fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(tmp_load_info.Format)); - if (fmt_desc->format == D3DX_PIXEL_FORMAT_COUNT) - { - FIXME("Unknown DXGI format supplied, %#x.\n", tmp_load_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; - - 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->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) -{ - IWICBitmapFrameDecode *frame = NULL; - IWICImagingFactory *factory = NULL; - IWICBitmapDecoder *decoder = NULL; - unsigned int stride, frame_size; - BYTE *res_data = NULL, *buffer; D3DX10_IMAGE_INFO img_info; - IWICStream *stream = NULL; struct d3dx_image image; - const GUID *dst_format; - HRESULT hr; + unsigned int i, j; + HRESULT hr = S_OK;
if (!data || !size) return E_FAIL; @@ -977,6 +671,7 @@ 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");
+ *resource_data = NULL; hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10); if (FAILED(hr)) return E_FAIL; @@ -997,74 +692,84 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end; }
- if (SUCCEEDED(hr = d3dx_load_texture_data(&image, load_info, &img_info, resource_data))) + 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) { - TRACE("Successfully used shared code to load texture data.\n"); - res_data = NULL; + FIXME("Unknown DXGI format supplied, %#x.\n", load_info->Format); + hr = E_NOTIMPL; goto end; } - else if (img_info.ImageFileFormat == D3DX10_IFF_DDS) + + /* 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; + load_info->MipLevels = img_info.MipLevels; + + 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; goto end; }
- if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory))) - goto end; - if (FAILED(hr = IWICImagingFactory_CreateStream(factory, &stream))) - goto end; - if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size))) - 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; - - stride = (img_info.Width * get_bpp_from_format(img_info.Format) + 7) / 8; - frame_size = stride * img_info.Height; + pixels_buffer = res_data + pixels_offset; + *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
- if (!(res_data = malloc(sizeof(**resource_data) + frame_size))) + src_desc = get_d3dx_pixel_format_info(image.format); + for (i = 0; i < img_info.ArraySize; ++i) { - hr = E_FAIL; - goto end; + struct volume dst_size = { load_info->Width, load_info->Height, load_info->Depth }; + + for (j = 0; j < 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 * 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); + } } - buffer = res_data + sizeof(**resource_data);
- if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format))) + if (FAILED(hr)) { - hr = E_FAIL; - FIXME("Unsupported DXGI format %#x.\n", img_info.Format); + *resource_data = NULL; 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; - load_info->MipLevels = img_info.MipLevels; - load_info->Format = img_info.Format; load_info->Usage = D3D10_USAGE_DEFAULT; load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; load_info->MiscFlags = img_info.MiscFlags;
res_data = NULL; - hr = S_OK;
end: d3dx_image_cleanup(&image); free(res_data); - if (frame) - IWICBitmapFrameDecode_Release(frame); - if (decoder) - IWICBitmapDecoder_Release(decoder); - if (stream) - IWICStream_Release(stream); - if (factory) - IWICImagingFactory_Release(factory); return hr; }