Commit 52ba1b49 authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

d3dx10: Support block compressed formats in D3DX10CreateTextureFromMemory().

parent ce0e61db
...@@ -1147,6 +1147,8 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag ...@@ -1147,6 +1147,8 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag
{ {
line_match = !memcmp(image->expected_data + stride * i, line_match = !memcmp(image->expected_data + stride * i,
(BYTE *)map.pData + map.RowPitch * i, stride); (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); ok_(__FILE__, line)(line_match, "Data mismatch for line %u.\n", i);
if (!line_match) if (!line_match)
break; break;
...@@ -1997,7 +1999,7 @@ static void test_create_texture(void) ...@@ -1997,7 +1999,7 @@ static void test_create_texture(void)
winetest_push_context("Test %u", i); winetest_push_context("Test %u", i);
hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, NULL, NULL, &resource, NULL); 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); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
if (hr == S_OK) if (hr == S_OK)
{ {
......
...@@ -71,6 +71,17 @@ wic_pixel_formats[] = ...@@ -71,6 +71,17 @@ wic_pixel_formats[] =
{ &GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT } { &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[] = static const DXGI_FORMAT to_be_converted_format[] =
{ {
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
...@@ -124,6 +135,17 @@ static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimensio ...@@ -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) static unsigned int get_bpp_from_format(DXGI_FORMAT format)
{ {
switch (format) switch (format)
...@@ -556,6 +578,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ...@@ -556,6 +578,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
{ {
unsigned int frame_count, width, height, stride, frame_size; unsigned int frame_count, width, height, stride, frame_size;
IWICFormatConverter *converter = NULL; IWICFormatConverter *converter = NULL;
IWICDdsFrameDecode *dds_frame = NULL;
D3D10_TEXTURE2D_DESC texture_2d_desc; D3D10_TEXTURE2D_DESC texture_2d_desc;
D3D10_SUBRESOURCE_DATA resource_data; D3D10_SUBRESOURCE_DATA resource_data;
IWICBitmapFrameDecode *frame = NULL; IWICBitmapFrameDecode *frame = NULL;
...@@ -582,6 +605,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ...@@ -582,6 +605,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
if (FAILED(D3DX10GetImageInfoFromMemory(src_data, src_data_size, NULL, &img_info, NULL))) if (FAILED(D3DX10GetImageInfoFromMemory(src_data, src_data_size, NULL, &img_info, NULL)))
return E_FAIL; 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))) if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory)))
goto end; goto end;
...@@ -600,6 +628,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ...@@ -600,6 +628,11 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
width = img_info.Width; width = img_info.Width;
height = img_info.Height; 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; stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8;
frame_size = stride * height; frame_size = stride * height;
...@@ -609,35 +642,45 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ...@@ -609,35 +642,45 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
goto end; goto end;
} }
if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format))) if (is_block_compressed(img_info.Format))
{ {
hr = E_FAIL; if (FAILED(hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICDdsFrameDecode, (void **)&dds_frame)))
FIXME("Unsupported DXGI format %#x.\n", img_info.Format); goto end;
goto end; if (FAILED(hr = IWICDdsFrameDecode_CopyBlocks(dds_frame, NULL, stride * 4, frame_size, buffer)))
}
if (IsEqualGUID(&src_format, dst_format))
{
if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer)))
goto end; goto end;
} }
else else
{ {
if (FAILED(hr = IWICImagingFactory_CreateFormatConverter(factory, &converter))) if (!(dst_format = dxgi_format_to_wic_guid(img_info.Format)))
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", hr = E_FAIL;
debugstr_guid(&src_format), debugstr_guid(dst_format)); FIXME("Unsupported DXGI format %#x.\n", img_info.Format);
goto end; goto end;
} }
if (FAILED(hr = IWICFormatConverter_Initialize(converter, (IWICBitmapSource *)frame, dst_format,
WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom))) if (IsEqualGUID(&src_format, dst_format))
goto end; {
if (FAILED(hr = IWICFormatConverter_CopyPixels(converter, NULL, stride, frame_size, buffer))) if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer)))
goto end; 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)); memset(&texture_2d_desc, 0, sizeof(texture_2d_desc));
...@@ -664,6 +707,8 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s ...@@ -664,6 +707,8 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
end: end:
if (converter) if (converter)
IWICFormatConverter_Release(converter); IWICFormatConverter_Release(converter);
if (dds_frame)
IWICDdsFrameDecode_Release(dds_frame);
if (buffer) if (buffer)
heap_free(buffer); heap_free(buffer);
if (frame) if (frame)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment