From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/texture.c | 76 ++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 88efdf585b4..fa7918a0778 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -766,11 +766,53 @@ 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; +} + HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, D3D10_SUBRESOURCE_DATA **resource_data) { unsigned int frame_count, width, height, stride, frame_size; - IWICFormatConverter *converter = NULL; IWICDdsFrameDecode *dds_frame = NULL; IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; @@ -779,8 +821,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO D3DX10_IMAGE_INFO img_info; IWICStream *stream = NULL; const GUID *dst_format; - BOOL can_convert; - GUID src_format; HRESULT hr;
if (load_info->Width != D3DX10_DEFAULT) @@ -835,8 +875,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO 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; @@ -870,30 +908,8 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO 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; - } + if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer))) + goto end; }
load_info->Width = width; @@ -913,8 +929,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO hr = S_OK;
end: - if (converter) - IWICFormatConverter_Release(converter); if (dds_frame) IWICDdsFrameDecode_Release(dds_frame); free(res_data);
From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/texture.c | 96 +++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 40 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index fa7918a0778..a530bd6b7f0 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -71,17 +71,6 @@ 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, @@ -135,17 +124,6 @@ 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) @@ -876,32 +854,70 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO if (FAILED(hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame))) goto end;
- width = img_info.Width; - height = img_info.Height; - if (is_block_compressed(img_info.Format)) + if (img_info.ImageFileFormat == D3DX10_IFF_DDS) { - width = (width + 3) & ~3; - height = (height + 3) & ~3; - } - stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; - frame_size = stride * height; + WICDdsFormatInfo format_info;
- if (!(res_data = malloc(sizeof(**resource_data) + frame_size))) - { - hr = E_FAIL; - goto end; - } - buffer = res_data + sizeof(**resource_data); - - if (is_block_compressed(img_info.Format)) - { 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))) + if (FAILED(hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info))) + goto end; + if (FAILED(hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width, &height))) + goto end; + + if (img_info.Format == format_info.DxgiFormat) + { + stride = width * format_info.BytesPerBlock; + frame_size = stride * height; + width *= format_info.BlockWidth; + height *= format_info.BlockHeight; + } + else + { + width *= format_info.BlockWidth; + height *= format_info.BlockHeight; + stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; + frame_size = stride * height; + } + + if (!(res_data = malloc(sizeof(**resource_data) + frame_size))) + { + hr = E_FAIL; goto end; + } + buffer = res_data + sizeof(**resource_data); + + 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; + } } else { + width = img_info.Width; + height = img_info.Height; + stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; + frame_size = stride * 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;
From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/tests/d3dx10.c | 7 -- dlls/d3dx10_43/texture.c | 155 +++++++++++++++++++++++----------- 2 files changed, 104 insertions(+), 58 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index ee969608d2b..fd6226fa5a8 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2059,7 +2059,6 @@ static void test_D3DX10CreateAsyncTextureProcessor(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[i].data, test_image[i].size); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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) @@ -2434,7 +2433,6 @@ static void test_D3DX10CreateThreadPump(void) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID3DX10ThreadPump_WaitForAllItems(pump); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(work_item_hr == S_OK || (work_item_hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#lx.\n", work_item_hr); @@ -2665,7 +2663,6 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, NULL, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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) @@ -2716,7 +2713,6 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileW(device, path, NULL, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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) @@ -2729,7 +2725,6 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), NULL, NULL, &resource, &hr2); ok(hr == hr2, "Got unexpected hr2 %#lx.\n", hr2); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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) @@ -2775,7 +2770,6 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromResourceW(device, resource_module, test_resource_name, NULL, NULL, &resource, &hr2); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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); @@ -2789,7 +2783,6 @@ static void test_create_texture(void) hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromResourceA(device, resource_module, get_str_a(test_resource_name), NULL, NULL, &resource, &hr2); - todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) 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); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index a530bd6b7f0..cb00ef45eb0 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -744,6 +744,32 @@ 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) { @@ -790,10 +816,11 @@ static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, D3D10_SUBRESOURCE_DATA **resource_data) { - unsigned int frame_count, width, height, stride, frame_size; + unsigned int frame_count, stride, frame_size, i; IWICDdsFrameDecode *dds_frame = NULL; IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; + IWICDdsDecoder *dds_decoder = NULL; IWICBitmapDecoder *decoder = NULL; BYTE *res_data = NULL, *buffer; D3DX10_IMAGE_INFO img_info; @@ -830,17 +857,14 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (FAILED(D3DX10GetImageInfoFromMemory(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 (img_info.ArraySize != 1) + 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; }
+ if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory))) goto end; if (FAILED(hr = IWICImagingFactory_CreateStream(factory, &stream))) @@ -851,65 +875,92 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end; if (FAILED(hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count)) || !frame_count) 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 = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICDdsFrameDecode, (void **)&dds_frame))) - goto end; - if (FAILED(hr = IWICDdsFrameDecode_GetFormatInfo(dds_frame, &format_info))) - goto end; - if (FAILED(hr = IWICDdsFrameDecode_GetSizeInBlocks(dds_frame, &width, &height))) + if (FAILED(hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder))) goto end;
- if (img_info.Format == format_info.DxgiFormat) - { - stride = width * format_info.BytesPerBlock; - frame_size = stride * height; - width *= format_info.BlockWidth; - height *= format_info.BlockHeight; - } - else + for (i = 0; i < img_info.ArraySize; ++i) { - width *= format_info.BlockWidth; - height *= format_info.BlockHeight; - stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; - frame_size = stride * height; + if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, 0, 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) + { + 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(sizeof(**resource_data) + frame_size))) + if (!(res_data = malloc(size))) { hr = E_FAIL; goto end; } - buffer = res_data + sizeof(**resource_data); + *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
- if (img_info.Format == format_info.DxgiFormat) + size = 0; + for (i = 0; i < img_info.ArraySize; ++i) { - if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride, frame_size, buffer))) + if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, 0, 0, &frame))) 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); + if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICDdsFrameDecode, (void **)&dds_frame))) goto end; - } - if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer))) + 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 + 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].pSysMem = buffer; + (*resource_data)[i].SysMemPitch = stride; + (*resource_data)[i].SysMemSlicePitch = frame_size; } } else { - width = img_info.Width; - height = img_info.Height; - stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; - frame_size = stride * height; + 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))) { @@ -926,25 +977,27 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO } 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 = width; - load_info->Height = height; + load_info->Width = img_info.Width; + load_info->Height = img_info.Height; load_info->MipLevels = 1; 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;
- *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data; res_data = NULL; - (*resource_data)->pSysMem = buffer; - (*resource_data)->SysMemPitch = stride; - (*resource_data)->SysMemSlicePitch = frame_size; - hr = S_OK;
end: + if (dds_decoder) + IWICDdsDecoder_Release(dds_decoder); if (dds_frame) IWICDdsFrameDecode_Release(dds_frame); free(res_data); @@ -970,7 +1023,7 @@ HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_in texture_2d_desc.Width = load_info->Width; texture_2d_desc.Height = load_info->Height; texture_2d_desc.MipLevels = load_info->MipLevels; - texture_2d_desc.ArraySize = 1; + texture_2d_desc.ArraySize = load_info->MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE ? 6 : 1; texture_2d_desc.Format = load_info->Format; texture_2d_desc.SampleDesc.Count = 1; texture_2d_desc.Usage = load_info->Usage;
From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/texture.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index cb00ef45eb0..e1c7742b409 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -816,7 +816,7 @@ static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, D3D10_SUBRESOURCE_DATA **resource_data) { - unsigned int frame_count, stride, frame_size, i; + unsigned int stride, frame_size, i; IWICDdsFrameDecode *dds_frame = NULL; IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; @@ -873,8 +873,6 @@ 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_GetFrameCount(decoder, &frame_count)) || !frame_count) - goto end;
if (img_info.ImageFileFormat == D3DX10_IFF_DDS) {
From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 102 ++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 48 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index fd6226fa5a8..fb56ec1c365 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1138,7 +1138,7 @@ 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 != 1) + 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 e1c7742b409..0439808e468 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -816,7 +816,7 @@ static HRESULT convert_image(IWICImagingFactory *factory, IWICBitmapFrameDecode 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; + unsigned int stride, frame_size, i, j; IWICDdsFrameDecode *dds_frame = NULL; IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; @@ -884,25 +884,29 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
for (i = 0; i < img_info.ArraySize; ++i) { - if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, 0, 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) + for (j = 0; j < img_info.MipLevels; ++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); - } + 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;
- size += sizeof(**resource_data) + frame_size; + 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); + }
- IWICDdsFrameDecode_Release(dds_frame); - dds_frame = NULL; - IWICBitmapFrameDecode_Release(frame); - frame = NULL; + size += sizeof(**resource_data) + frame_size; + + IWICDdsFrameDecode_Release(dds_frame); + dds_frame = NULL; + IWICBitmapFrameDecode_Release(frame); + frame = NULL; + } }
if (!(res_data = malloc(size))) @@ -915,41 +919,45 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO size = 0; for (i = 0; i < img_info.ArraySize; ++i) { - if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, 0, 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 + size; - size += frame_size; - - if (img_info.Format == format_info.DxgiFormat) + for (j = 0; j < img_info.MipLevels; ++j) { - if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride, frame_size, buffer))) + if (FAILED(hr = IWICDdsDecoder_GetFrame(dds_decoder, i, j, 0, &frame))) 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); + if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame, + &IID_IWICDdsFrameDecode, (void **)&dds_frame))) goto end; - } - if (FAILED(hr = convert_image(factory, frame, dst_format, stride, frame_size, buffer))) + if (FAILED(hr = dds_get_frame_info(dds_frame, &img_info, &format_info, &stride, &frame_size))) goto end; - }
- IWICDdsFrameDecode_Release(dds_frame); - dds_frame = NULL; - IWICBitmapFrameDecode_Release(frame); - frame = NULL; + buffer = res_data + sizeof(**resource_data) * img_info.ArraySize * img_info.MipLevels + size; + size += frame_size;
- (*resource_data)[i].pSysMem = buffer; - (*resource_data)[i].SysMemPitch = stride; - (*resource_data)[i].SysMemSlicePitch = 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 @@ -984,7 +992,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
load_info->Width = img_info.Width; load_info->Height = img_info.Height; - load_info->MipLevels = 1; + 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;
From: Piotr Caban piotr@codeweavers.com
--- dlls/d3dx10_43/tests/d3dx10.c | 46 ++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index fb56ec1c365..f750d0d3667 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -511,6 +511,11 @@ static const BYTE test_dds_cube[] = }; static const BYTE test_dds_cube_data[] = { + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, + 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7, 0xf5, 0xa7, 0x08, 0x69, 0x74, 0xc0, 0xbf, 0xd7 };
@@ -1211,10 +1216,11 @@ static void check_resource_info(ID3D10Resource *resource, const struct test_imag
static void check_resource_data(ID3D10Resource *resource, const struct test_image *image, unsigned int line) { - unsigned int width, height, stride, i; + unsigned int width, height, stride, i, array_slice; D3D10_MAPPED_TEXTURE2D map; D3D10_TEXTURE2D_DESC desc; ID3D10Texture2D *readback; + const BYTE *expected_data; BOOL line_match; HRESULT hr;
@@ -1233,26 +1239,32 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag height = (height + 3) / 4; }
- hr = ID3D10Texture2D_Map(readback, 0, D3D10_MAP_READ, 0, &map); - ok_(__FILE__, line)(hr == S_OK, "Map failed, hr %#lx.\n", hr); - if (hr != S_OK) + expected_data = image->expected_data; + for (array_slice = 0; array_slice < desc.ArraySize; ++array_slice) { - ID3D10Texture2D_Release(readback); - return; - } + hr = ID3D10Texture2D_Map(readback, array_slice * desc.MipLevels, D3D10_MAP_READ, 0, &map); + ok_(__FILE__, line)(hr == S_OK, "Map failed, hr %#lx.\n", hr); + if (hr != S_OK) + { + ID3D10Texture2D_Release(readback); + return; + }
- for (i = 0; i < height; ++i) - { - 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; + for (i = 0; i < height; ++i) + { + line_match = !memcmp(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, array slice %u.\n", i, array_slice); + if (!line_match) + break; + } + expected_data += stride * height; + + ID3D10Texture2D_Unmap(readback, 0); }
- ID3D10Texture2D_Unmap(readback, 0); ID3D10Texture2D_Release(readback); }
This merge request was approved by Matteo Bruni.
Sorry for the long wait.
I'm not super thrilled about depending more and more on our private WIC extensions (i.e. support for uncompressed DDS). I'm not sure the alternatives are any better but, FWIW, https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3dx11createtextur... mentions how the newer d3dx replacement libraries DirectXTK and DirectXTex have separate function variants for loading DDS and WIC files.
Random thought: in theory TIFFs support multiple images in the same file. It's very unlikely that both d3dx10/11 support that and that they are actually used in the wild but it might be interesting to at least check the former.
Matteo Bruni (@Mystral) commented about dlls/d3dx10_43/texture.c:
img_info.Height = (img_info.Height + format_info.BlockHeight - 1) & ~(format_info.BlockHeight - 1);
}
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;
size += sizeof(**resource_data) + frame_size;
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);
}
I wonder if this should happen for all the mip level 0 elements of an array / cube texture (i.e. condition should just be !j instead).