Commit 0d457b2c authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

d3dx10: Add D3DX10CreateAsyncTextureProcessor implementation.

parent 04b6412c
......@@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "d3d10_1.h"
#include "d3dx10.h"
#include "d3dcompiler.h"
......@@ -315,6 +316,66 @@ static ID3DX10DataProcessorVtbl texture_info_processor_vtbl =
texture_info_processor_Destroy
};
struct texture_processor
{
ID3DX10DataProcessor ID3DX10DataProcessor_iface;
ID3D10Device *device;
D3DX10_IMAGE_LOAD_INFO load_info;
D3D10_SUBRESOURCE_DATA *resource_data;
};
static inline struct texture_processor *texture_processor_from_ID3DX10DataProcessor(ID3DX10DataProcessor *iface)
{
return CONTAINING_RECORD(iface, struct texture_processor, ID3DX10DataProcessor_iface);
}
static HRESULT WINAPI texture_processor_Process(ID3DX10DataProcessor *iface, void *data, SIZE_T size)
{
struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface);
TRACE("iface %p, data %p, size %Iu.\n", iface, data, size);
if (processor->resource_data)
{
WARN("Called multiple times.\n");
free(processor->resource_data);
processor->resource_data = NULL;
}
return load_texture_data(data, size, &processor->load_info, &processor->resource_data);
}
static HRESULT WINAPI texture_processor_CreateDeviceObject(ID3DX10DataProcessor *iface, void **object)
{
struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface);
TRACE("iface %p, object %p.\n", iface, object);
if (!processor->resource_data)
return E_FAIL;
return create_d3d_texture(processor->device, &processor->load_info,
processor->resource_data, (ID3D10Resource **)object);
}
static HRESULT WINAPI texture_processor_Destroy(ID3DX10DataProcessor *iface)
{
struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface);
TRACE("iface %p.\n", iface);
ID3D10Device_Release(processor->device);
free(processor->resource_data);
free(processor);
return S_OK;
}
static ID3DX10DataProcessorVtbl texture_processor_vtbl =
{
texture_processor_Process,
texture_processor_CreateDeviceObject,
texture_processor_Destroy
};
HRESULT WINAPI D3DX10CompileFromMemory(const char *data, SIZE_T data_size, const char *filename,
const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entry_point,
const char *target, UINT sflags, UINT eflags, ID3DX10ThreadPump *pump, ID3D10Blob **shader,
......@@ -517,8 +578,24 @@ HRESULT WINAPI D3DX10CreateAsyncTextureInfoProcessor(D3DX10_IMAGE_INFO *info, ID
HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *device,
D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10DataProcessor **processor)
{
FIXME("device %p, load_info %p, processor %p stub!\n", device, load_info, processor);
return E_NOTIMPL;
struct texture_processor *object;
TRACE("device %p, load_info %p, processor %p.\n", device, load_info, processor);
if (!device || !processor)
return E_INVALIDARG;
object = calloc(1, sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
object->ID3DX10DataProcessor_iface.lpVtbl = &texture_processor_vtbl;
object->device = device;
ID3D10Device_AddRef(device);
init_load_info(load_info, &object->load_info);
*processor = &object->ID3DX10DataProcessor_iface;
return S_OK;
}
HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_size, const char *filename,
......
......@@ -23,3 +23,11 @@ extern HRESULT load_resourceW(HMODULE module, const WCHAR *resource,
void **data, DWORD *size) DECLSPEC_HIDDEN;
extern HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) DECLSPEC_HIDDEN;
extern void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info,
D3DX10_IMAGE_LOAD_INFO *out) DECLSPEC_HIDDEN;
/* Returns array of D3D10_SUBRESOURCE_DATA structures followed by textures data. */
extern HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info,
D3D10_SUBRESOURCE_DATA **resource_data) DECLSPEC_HIDDEN;
extern HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info,
D3D10_SUBRESOURCE_DATA *resource_data, ID3D10Resource **texture) DECLSPEC_HIDDEN;
......@@ -571,6 +571,22 @@ HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_dat
return hr;
}
static HRESULT create_texture(ID3D10Device *device, const void *data, SIZE_T size,
D3DX10_IMAGE_LOAD_INFO *load_info, ID3D10Resource **texture)
{
D3D10_SUBRESOURCE_DATA *resource_data;
D3DX10_IMAGE_LOAD_INFO load_info_copy;
HRESULT hr;
init_load_info(load_info, &load_info_copy);
if (FAILED((hr = load_texture_data(data, size, &load_info_copy, &resource_data))))
return hr;
hr = create_d3d_texture(device, &load_info_copy, resource_data, texture);
free(resource_data);
return hr;
}
HRESULT WINAPI D3DX10CreateTextureFromFileA(ID3D10Device *device, const char *src_file,
D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult)
{
......@@ -669,56 +685,83 @@ HRESULT WINAPI D3DX10CreateTextureFromResourceW(ID3D10Device *device, HMODULE mo
return D3DX10CreateTextureFromMemory(device, buffer, size, load_info, pump, texture, hresult);
}
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)
void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info, D3DX10_IMAGE_LOAD_INFO *out)
{
if (load_info)
{
*out = *load_info;
return;
}
out->Width = D3DX10_DEFAULT;
out->Height = D3DX10_DEFAULT;
out->Depth = D3DX10_DEFAULT;
out->FirstMipLevel = D3DX10_DEFAULT;
out->MipLevels = D3DX10_DEFAULT;
out->Usage = D3DX10_DEFAULT;
out->BindFlags = D3DX10_DEFAULT;
out->CpuAccessFlags = D3DX10_DEFAULT;
out->MiscFlags = D3DX10_DEFAULT;
out->Format = D3DX10_DEFAULT;
out->Filter = D3DX10_DEFAULT;
out->MipFilter = D3DX10_DEFAULT;
out->pSrcInfo = NULL;
}
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;
D3D10_TEXTURE2D_DESC texture_2d_desc;
D3D10_SUBRESOURCE_DATA resource_data;
IWICBitmapFrameDecode *frame = NULL;
IWICImagingFactory *factory = NULL;
IWICBitmapDecoder *decoder = NULL;
ID3D10Texture2D *texture_2d;
BYTE *res_data = NULL, *buffer;
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 %Iu, load_info %p, pump %p, texture %p, hresult %p.\n",
device, src_data, src_data_size, load_info, pump, texture, hresult);
if (!device)
return E_INVALIDARG;
if (!src_data)
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)))
{
if (hresult)
*hresult = E_FAIL;
if (load_info->Width != D3DX10_DEFAULT)
FIXME("load_info->Width is ignored.\n");
if (load_info->Height != D3DX10_DEFAULT)
FIXME("load_info->Height is ignored.\n");
if (load_info->Depth != D3DX10_DEFAULT)
FIXME("load_info->Depth is ignored.\n");
if (load_info->FirstMipLevel != D3DX10_DEFAULT)
FIXME("load_info->FirstMipLevel is ignored.\n");
if (load_info->MipLevels != D3DX10_DEFAULT)
FIXME("load_info->MipLevels is ignored.\n");
if (load_info->Usage != D3DX10_DEFAULT)
FIXME("load_info->Usage is ignored.\n");
if (load_info->BindFlags != D3DX10_DEFAULT)
FIXME("load_info->BindFlags is ignored.\n");
if (load_info->CpuAccessFlags != D3DX10_DEFAULT)
FIXME("load_info->CpuAccessFlags is ignored.\n");
if (load_info->MiscFlags != D3DX10_DEFAULT)
FIXME("load_info->MiscFlags is ignored.\n");
if (load_info->Format != D3DX10_DEFAULT)
FIXME("load_info->Format is ignored.\n");
if (load_info->Filter != D3DX10_DEFAULT)
FIXME("load_info->Filter is ignored.\n");
if (load_info->MipFilter != D3DX10_DEFAULT)
FIXME("load_info->MipFilter is ignored.\n");
if (load_info->pSrcInfo)
FIXME("load_info->pSrcInfo is ignored.\n");
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");
if (hresult)
*hresult = E_FAIL;
return E_FAIL;
}
if (img_info.ArraySize != 1)
{
FIXME("img_info.ArraySize = %u not supported.\n", img_info.ArraySize);
if (hresult)
*hresult = E_NOTIMPL;
return E_NOTIMPL;
}
......@@ -726,7 +769,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
goto end;
if (FAILED(hr = IWICImagingFactory_CreateStream(factory, &stream)))
goto end;
if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)src_data, src_data_size)))
if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size)))
goto end;
if (FAILED(hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder)))
goto end;
......@@ -747,11 +790,12 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8;
frame_size = stride * height;
if (!(buffer = malloc(frame_size)))
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))
{
......@@ -794,25 +838,20 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s
}
}
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;
load_info->Width = width;
load_info->Height = 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;
if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, &resource_data, &texture_2d)))
goto end;
*resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
res_data = NULL;
(*resource_data)->pSysMem = buffer;
(*resource_data)->SysMemPitch = stride;
(*resource_data)->SysMemSlicePitch = frame_size;
*texture = (ID3D10Resource *)texture_2d;
hr = S_OK;
end:
......@@ -820,7 +859,7 @@ end:
IWICFormatConverter_Release(converter);
if (dds_frame)
IWICDdsFrameDecode_Release(dds_frame);
free(buffer);
free(res_data);
if (frame)
IWICBitmapFrameDecode_Release(frame);
if (decoder)
......@@ -829,7 +868,50 @@ end:
IWICStream_Release(stream);
if (factory)
IWICImagingFactory_Release(factory);
return hr;
}
HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info,
D3D10_SUBRESOURCE_DATA *resource_data, ID3D10Resource **texture)
{
D3D10_TEXTURE2D_DESC texture_2d_desc;
ID3D10Texture2D *texture_2d;
HRESULT hr;
memset(&texture_2d_desc, 0, sizeof(texture_2d_desc));
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.Format = load_info->Format;
texture_2d_desc.SampleDesc.Count = 1;
texture_2d_desc.Usage = load_info->Usage;
texture_2d_desc.BindFlags = load_info->BindFlags;
texture_2d_desc.MiscFlags = load_info->MiscFlags;
if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, resource_data, &texture_2d)))
return hr;
*texture = (ID3D10Resource *)texture_2d;
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)
{
HRESULT hr;
TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n",
device, src_data, src_data_size, load_info, pump, texture, hresult);
if (!device)
return E_INVALIDARG;
if (!src_data)
return E_FAIL;
if (pump)
FIXME("Thread pump is not supported yet.\n");
hr = create_texture(device, src_data, src_data_size, load_info, texture);
if (hresult)
*hresult = hr;
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