From 3265019d7cb24bb655130491e3ef87ede923e901 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 13 Jul 2022 18:42:26 +0200 Subject: [PATCH] d3dx10: Add support for texture cubes in D3DX10CreateTexture functions. --- 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) + for (i = 0; i < img_info.ArraySize; ++i) { - 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 (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))) + 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) { - hr = E_FAIL; - FIXME("Unsupported DXGI format %#x.\n", img_info.Format); - goto end; + if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride, frame_size, buffer))) + goto end; } - if (FAILED(hr = convert_image(factory, frame, dst_format, 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;