Commit 68ac49bc authored by Ziqing Hui's avatar Ziqing Hui Committed by Alexandre Julliard

d3dx10: Introduce initial D3DX10CreateTextureFromMemory() implementation.

parent dd55d9ce
......@@ -187,17 +187,6 @@ HRESULT WINAPI D3DX10CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D10_DRIVE
D3D10_1_SDK_VERSION, desc, swapchain, (ID3D10Device1 **)device);
}
HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *src_data,
SIZE_T src_data_size, D3DX10_IMAGE_LOAD_INFO *loadinfo, ID3DX10ThreadPump *pump,
ID3D10Resource **texture, HRESULT *hresult)
{
FIXME("device %p, src_data %p, src_data_size %lu, loadinfo %p, pump %p, texture %p, "
"hresult %p, stub!\n",
device, src_data, src_data_size, loadinfo, pump, texture, hresult);
return E_NOTIMPL;
}
HRESULT WINAPI D3DX10FilterTexture(ID3D10Resource *texture, UINT src_level, UINT filter)
{
FIXME("texture %p, src_level %u, filter %#x stub!\n", texture, src_level, filter);
......
......@@ -1040,6 +1040,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)
ok_(__FILE__, line)(desc_2d.MipLevels == expected_mip_levels,
"Got unexpected MipLevels %u, expected %u.\n",
desc_2d.MipLevels, expected_mip_levels);
......@@ -1146,6 +1147,7 @@ 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;
......@@ -1973,25 +1975,21 @@ static void test_create_texture(void)
resource = (ID3D10Resource *)0xdeadbeef;
hr = D3DX10CreateTextureFromMemory(device, NULL, 0, NULL, NULL, &resource, NULL);
todo_wine
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef;
hr = D3DX10CreateTextureFromMemory(device, NULL, sizeof(test_bmp_1bpp), NULL, NULL, &resource, NULL);
todo_wine
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef;
hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, 0, NULL, NULL, &resource, NULL);
todo_wine
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef;
hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, sizeof(test_bmp_1bpp) - 1, NULL, NULL, &resource, NULL);
todo_wine
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
......@@ -2000,7 +1998,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
todo_wine_if(test_image[i].expected_info.Format != DXGI_FORMAT_R8G8B8A8_UNORM)
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
if (hr == S_OK)
{
......
......@@ -85,6 +85,140 @@ static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimensio
}
}
static unsigned int get_bpp_from_format(DXGI_FORMAT format)
{
switch (format)
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS:
case DXGI_FORMAT_R32G32B32A32_FLOAT:
case DXGI_FORMAT_R32G32B32A32_UINT:
case DXGI_FORMAT_R32G32B32A32_SINT:
return 128;
case DXGI_FORMAT_R32G32B32_TYPELESS:
case DXGI_FORMAT_R32G32B32_FLOAT:
case DXGI_FORMAT_R32G32B32_UINT:
case DXGI_FORMAT_R32G32B32_SINT:
return 96;
case DXGI_FORMAT_R16G16B16A16_TYPELESS:
case DXGI_FORMAT_R16G16B16A16_FLOAT:
case DXGI_FORMAT_R16G16B16A16_UNORM:
case DXGI_FORMAT_R16G16B16A16_UINT:
case DXGI_FORMAT_R16G16B16A16_SNORM:
case DXGI_FORMAT_R16G16B16A16_SINT:
case DXGI_FORMAT_R32G32_TYPELESS:
case DXGI_FORMAT_R32G32_FLOAT:
case DXGI_FORMAT_R32G32_UINT:
case DXGI_FORMAT_R32G32_SINT:
case DXGI_FORMAT_R32G8X24_TYPELESS:
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
case DXGI_FORMAT_Y416:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
return 64;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
case DXGI_FORMAT_R10G10B10A2_UNORM:
case DXGI_FORMAT_R10G10B10A2_UINT:
case DXGI_FORMAT_R11G11B10_FLOAT:
case DXGI_FORMAT_R8G8B8A8_TYPELESS:
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_R8G8B8A8_UINT:
case DXGI_FORMAT_R8G8B8A8_SNORM:
case DXGI_FORMAT_R8G8B8A8_SINT:
case DXGI_FORMAT_R16G16_TYPELESS:
case DXGI_FORMAT_R16G16_FLOAT:
case DXGI_FORMAT_R16G16_UNORM:
case DXGI_FORMAT_R16G16_UINT:
case DXGI_FORMAT_R16G16_SNORM:
case DXGI_FORMAT_R16G16_SINT:
case DXGI_FORMAT_R32_TYPELESS:
case DXGI_FORMAT_D32_FLOAT:
case DXGI_FORMAT_R32_FLOAT:
case DXGI_FORMAT_R32_UINT:
case DXGI_FORMAT_R32_SINT:
case DXGI_FORMAT_R24G8_TYPELESS:
case DXGI_FORMAT_D24_UNORM_S8_UINT:
case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8X8_UNORM:
case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
case DXGI_FORMAT_B8G8R8A8_TYPELESS:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_AYUV:
case DXGI_FORMAT_Y410:
case DXGI_FORMAT_YUY2:
return 32;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
return 24;
case DXGI_FORMAT_R8G8_TYPELESS:
case DXGI_FORMAT_R8G8_UNORM:
case DXGI_FORMAT_R8G8_UINT:
case DXGI_FORMAT_R8G8_SNORM:
case DXGI_FORMAT_R8G8_SINT:
case DXGI_FORMAT_R16_TYPELESS:
case DXGI_FORMAT_R16_FLOAT:
case DXGI_FORMAT_D16_UNORM:
case DXGI_FORMAT_R16_UNORM:
case DXGI_FORMAT_R16_UINT:
case DXGI_FORMAT_R16_SNORM:
case DXGI_FORMAT_R16_SINT:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_A8P8:
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 16;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_NV11:
return 12;
case DXGI_FORMAT_R8_TYPELESS:
case DXGI_FORMAT_R8_UNORM:
case DXGI_FORMAT_R8_UINT:
case DXGI_FORMAT_R8_SNORM:
case DXGI_FORMAT_R8_SINT:
case DXGI_FORMAT_A8_UNORM:
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
case DXGI_FORMAT_BC2_TYPELESS:
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT_BC3_TYPELESS:
case DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT_BC5_TYPELESS:
case DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT_BC5_SNORM:
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_BC7_TYPELESS:
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
return 8;
case DXGI_FORMAT_BC1_TYPELESS:
case DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
return 4;
case DXGI_FORMAT_R1_UNORM:
return 1;
default:
return 0;
}
}
static DXGI_FORMAT get_d3dx10_dds_format(DXGI_FORMAT format)
{
unsigned int i;
......@@ -377,3 +511,98 @@ end:
}
return S_OK;
}
HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *src_data, SIZE_T src_data_size,
D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult)
{
unsigned int frame_count, width, height, stride, frame_size;
D3D10_TEXTURE2D_DESC texture_2d_desc;
D3D10_SUBRESOURCE_DATA resource_data;
IWICBitmapFrameDecode *frame = NULL;
IWICImagingFactory *factory = NULL;
IWICBitmapDecoder *decoder = NULL;
ID3D10Texture2D *texture_2d;
D3DX10_IMAGE_INFO img_info;
IWICStream *stream = NULL;
BYTE *buffer = NULL;
HRESULT hr;
TRACE("device %p, src_data %p, src_data_size %lu, load_info %p, pump %p, texture %p, hresult %p.\n",
device, src_data, src_data_size, load_info, pump, texture, hresult);
if (!src_data || !src_data_size || !texture)
return E_FAIL;
if (load_info)
FIXME("load_info is ignored.\n");
if (pump)
FIXME("Thread pump is not supported yet.\n");
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;
if (FAILED(hr = IWICImagingFactory_CreateStream(factory, &stream)))
goto end;
if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)src_data, src_data_size)))
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 (FAILED(hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame)))
goto end;
width = img_info.Width;
height = img_info.Height;
stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8;
frame_size = stride * height;
if (!(buffer = heap_alloc(frame_size)))
{
hr = E_FAIL;
goto end;
}
if (FAILED(hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, stride, frame_size, buffer)))
goto end;
memset(&texture_2d_desc, 0, sizeof(texture_2d_desc));
texture_2d_desc.Width = width;
texture_2d_desc.Height = height;
texture_2d_desc.MipLevels = 1;
texture_2d_desc.ArraySize = img_info.ArraySize;
texture_2d_desc.Format = img_info.Format;
texture_2d_desc.SampleDesc.Count = 1;
texture_2d_desc.Usage = D3D10_USAGE_DEFAULT;
texture_2d_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
texture_2d_desc.MiscFlags = img_info.MiscFlags;
resource_data.pSysMem = buffer;
resource_data.SysMemPitch = stride;
resource_data.SysMemSlicePitch = frame_size;
if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, &resource_data, &texture_2d)))
goto end;
*texture = (ID3D10Resource *)texture_2d;
hr = S_OK;
end:
if (buffer)
heap_free(buffer);
if (frame)
IWICBitmapFrameDecode_Release(frame);
if (decoder)
IWICBitmapDecoder_Release(decoder);
if (stream)
IWICStream_Release(stream);
if (factory)
IWICImagingFactory_Release(factory);
return hr;
}
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