[PATCH v3 5/6] d3dx10: Add D3DX10CreateAsyncTextureProcessor implementation.
Piotr Caban
wine at gitlab.winehq.org
Wed Jun 15 07:24:48 CDT 2022
From: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Piotr Caban <piotr at 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 d3a4d9450b6..b07472e5c46 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 = %d 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;
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/228
More information about the wine-devel
mailing list