Module: wine Branch: master Commit: ce0e61dbe839bd80ddc2b9d472cce25b05a9618a URL: https://source.winehq.org/git/wine.git/?a=commit;h=ce0e61dbe839bd80ddc2b9d47...
Author: Ziqing Hui zhui@codeweavers.com Date: Thu Jul 1 14:08:49 2021 +0800
d3dx10: Handle format conversion in D3DX10CreateTextureFromMemory().
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d3dx10_43/tests/d3dx10.c | 3 +- dlls/d3dx10_43/texture.c | 83 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 251613d246f..d5d1f02441c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1147,7 +1147,6 @@ 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 ok_(__FILE__, line)(line_match, "Data mismatch for line %u.\n", i); if (!line_match) break; @@ -1998,7 +1997,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(test_image[i].expected_info.Format != DXGI_FORMAT_R8G8B8A8_UNORM) + todo_wine_if(is_block_compressed(test_image[i].expected_info.Format)) 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 8655048fa5f..8765f312f4c 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -45,6 +45,32 @@ file_formats[] = { &GUID_ContainerFormatWmp, D3DX10_IFF_WMP }, };
+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 DXGI_FORMAT to_be_converted_format[] = { DXGI_FORMAT_UNKNOWN, @@ -69,6 +95,19 @@ static D3DX10_IMAGE_FILE_FORMAT wic_container_guid_to_file_format(GUID *containe return D3DX10_IFF_FORCE_DWORD; }
+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 D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension) { switch (wic_dimension) @@ -516,6 +555,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult) { unsigned int frame_count, width, height, stride, frame_size; + IWICFormatConverter *converter = NULL; D3D10_TEXTURE2D_DESC texture_2d_desc; D3D10_SUBRESOURCE_DATA resource_data; IWICBitmapFrameDecode *frame = NULL; @@ -524,7 +564,10 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ID3D10Texture2D *texture_2d; D3DX10_IMAGE_INFO img_info; IWICStream *stream = NULL; + const GUID *dst_format; BYTE *buffer = NULL; + BOOL can_convert; + GUID src_format; HRESULT hr;
TRACE("device %p, src_data %p, src_data_size %lu, load_info %p, pump %p, texture %p, hresult %p.\n", @@ -539,11 +582,6 @@ 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.Format != DXGI_FORMAT_R8G8B8A8_UNORM) - { - FIXME("Unsupported format %#x.\n", img_info.Format); - return E_FAIL; - }
if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory))) goto end; @@ -557,6 +595,8 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s goto end; if (FAILED(hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame))) goto end; + if (FAILED(hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &src_format))) + goto end;
width = img_info.Width; height = img_info.Height; @@ -568,8 +608,37 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s hr = E_FAIL; goto end; } - if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer))) + + 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 (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)); texture_2d_desc.Width = width; @@ -593,6 +662,8 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s hr = S_OK;
end: + if (converter) + IWICFormatConverter_Release(converter); if (buffer) heap_free(buffer); if (frame)