From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3dx10_43/async.c | 81 ++++++++++++++++- dlls/d3dx10_43/dxhelpers.h | 8 ++ dlls/d3dx10_43/texture.c | 176 +++++++++++++++++++++++++++---------- 3 files changed, 216 insertions(+), 49 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c index cd41e405210..bb1cf30a217 100644 --- a/dlls/d3dx10_43/async.c +++ b/dlls/d3dx10_43/async.c @@ -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, diff --git a/dlls/d3dx10_43/dxhelpers.h b/dlls/d3dx10_43/dxhelpers.h index 82fe639c2ea..5d0cdb54c59 100644 --- a/dlls/d3dx10_43/dxhelpers.h +++ b/dlls/d3dx10_43/dxhelpers.h @@ -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; diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index bba08f11beb..7a43d8409da 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -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;