From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v4: Declare block_compressed_formats[] as const.
dlls/d3dx10_43/tests/d3dx10.c | 4 +- dlls/d3dx10_43/texture.c | 87 ++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index d5d1f02441c..30d766bf244 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1147,6 +1147,8 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag { line_match = !memcmp(image->expected_data + stride * i, (BYTE *)map.pData + map.RowPitch * i, stride); + todo_wine_if(is_block_compressed(image->expected_info.Format) + && (image->expected_info.Width % 4 != 0 || image->expected_info.Height % 4 != 0)) ok_(__FILE__, line)(line_match, "Data mismatch for line %u.\n", i); if (!line_match) break; @@ -1997,7 +1999,7 @@ static void test_create_texture(void) winetest_push_context("Test %u", i);
hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, NULL, NULL, &resource, NULL); - todo_wine_if(is_block_compressed(test_image[i].expected_info.Format)) + todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); if (hr == S_OK) { diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 8765f312f4c..8d30aef8648 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -71,6 +71,17 @@ wic_pixel_formats[] = { &GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT } };
+static const DXGI_FORMAT block_compressed_formats[] = +{ + DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, + DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, + DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, + DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB +}; + static const DXGI_FORMAT to_be_converted_format[] = { DXGI_FORMAT_UNKNOWN, @@ -124,6 +135,17 @@ static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimensio } }
+static BOOL is_block_compressed(DXGI_FORMAT format) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(block_compressed_formats); ++i) + if (format == block_compressed_formats[i]) + return TRUE; + + return FALSE; +} + static unsigned int get_bpp_from_format(DXGI_FORMAT format) { switch (format) @@ -556,6 +578,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s { unsigned int frame_count, width, height, stride, frame_size; IWICFormatConverter *converter = NULL; + IWICDdsFrameDecode *dds_frame = NULL; D3D10_TEXTURE2D_DESC texture_2d_desc; D3D10_SUBRESOURCE_DATA resource_data; IWICBitmapFrameDecode *frame = NULL; @@ -582,6 +605,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
if (FAILED(D3DX10GetImageInfoFromMemory(src_data, src_data_size, NULL, &img_info, NULL))) return E_FAIL; + if (img_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) + { + FIXME("Cube map is not supported.\n"); + return E_FAIL; + }
if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory))) goto end; @@ -600,6 +628,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
width = img_info.Width; height = img_info.Height; + if (is_block_compressed(img_info.Format)) + { + width = (width + 3) & ~3; + height = (height + 3) & ~3; + } stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; frame_size = stride * height;
@@ -609,35 +642,45 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s goto end; }
- if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format))) + if (is_block_compressed(img_info.Format)) { - hr = E_FAIL; - FIXME("Unsupported DXGI format %#x.\n", img_info.Format); - goto end; - } - - if (IsEqualGUID(&src_format, dst_format)) - { - if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer))) + if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICDdsFrameDecode, (void **)&dds_frame))) + goto end; + if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride * 4, frame_size, buffer))) goto end; } else { - if (FAILED(hr = IWICImagingFactory_CreateFormatConverter(factory, &converter))) - goto end; - if (FAILED(hr = IWICFormatConverter_CanConvert(converter, &src_format, dst_format, &can_convert))) - goto end; - if (!can_convert) + if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format))) { - WARN("Format converting %s to %s is not supported by WIC.\n", - debugstr_guid(&src_format), debugstr_guid(dst_format)); + hr = E_FAIL; + FIXME("Unsupported DXGI format %#x.\n", img_info.Format); goto end; } - if (FAILED(hr = IWICFormatConverter_Initialize(converter, (IWICBitmapSource *)frame, dst_format, - WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom))) - goto end; - if (FAILED(hr = IWICFormatConverter_CopyPixels(converter, NULL, stride, frame_size, buffer))) - goto end; + + if (IsEqualGUID(&src_format, dst_format)) + { + if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer))) + goto end; + } + else + { + if (FAILED(hr = IWICImagingFactory_CreateFormatConverter(factory, &converter))) + goto end; + if (FAILED(hr = IWICFormatConverter_CanConvert(converter, &src_format, dst_format, &can_convert))) + goto end; + if (!can_convert) + { + WARN("Format converting %s to %s is not supported by WIC.\n", + debugstr_guid(&src_format), debugstr_guid(dst_format)); + goto end; + } + if (FAILED(hr = IWICFormatConverter_Initialize(converter, (IWICBitmapSource *)frame, dst_format, + WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom))) + goto end; + if (FAILED(hr = IWICFormatConverter_CopyPixels(converter, NULL, stride, frame_size, buffer))) + goto end; + } }
memset(&texture_2d_desc, 0, sizeof(texture_2d_desc)); @@ -664,6 +707,8 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s end: if (converter) IWICFormatConverter_Release(converter); + if (dds_frame) + IWICDdsFrameDecode_Release(dds_frame); if (buffer) heap_free(buffer); if (frame)