There was talk about having a shared library to allow reuse of common code between each DirectX version.
Here is a proof of concept, for a single shared function between Dx10 and 11.
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- configure | 28 ++++++++++++++++++++++++++++ configure.ac | 2 ++ libs/wined3dx/Makefile.in | 4 ++++ libs/wined3dx/texture.c | 24 ++++++++++++++++++++++++ libs/wined3dx/wined3dx.h | 24 ++++++++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 libs/wined3dx/Makefile.in create mode 100644 libs/wined3dx/texture.c create mode 100644 libs/wined3dx/wined3dx.h
diff --git a/configure b/configure index 9c15f952298..2e8d5bdc118 100755 --- a/configure +++ b/configure @@ -720,6 +720,8 @@ XSLT_PE_LIBS XSLT_PE_CFLAGS XML2_PE_LIBS XML2_PE_CFLAGS +WINED3DX_PE_LIBS +WINED3DX_PE_CFLAGS VKD3D_PE_LIBS VKD3D_PE_CFLAGS TIFF_PE_LIBS @@ -1596,6 +1598,7 @@ enable_tiff enable_uuid enable_vkd3d enable_wbemuuid +enable_wined3dx enable_wmcodecdspuuid enable_xml2 enable_xslt @@ -1756,6 +1759,8 @@ TIFF_PE_CFLAGS TIFF_PE_LIBS VKD3D_PE_CFLAGS VKD3D_PE_LIBS +WINED3DX_PE_CFLAGS +WINED3DX_PE_LIBS XML2_PE_CFLAGS XML2_PE_LIBS XSLT_PE_CFLAGS @@ -2558,6 +2563,11 @@ Some influential environment variables: version VKD3D_PE_LIBS Linker flags for the PE vkd3d, overriding the bundled version + WINED3DX_PE_CFLAGS + C compiler flags for the PE wined3dx, overriding the bundled + version + WINED3DX_PE_LIBS + Linker flags for the PE wined3dx, overriding the bundled version XML2_PE_CFLAGS C compiler flags for the PE xml2, overriding the bundled version XML2_PE_LIBS @@ -13202,6 +13212,21 @@ fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: vkd3d cflags: $VKD3D_PE_CFLAGS" >&5 printf "%s\n" "$as_me:${as_lineno-$LINENO}: vkd3d libs: $VKD3D_PE_LIBS" >&5
+if ${WINED3DX_PE_LIBS:+false} : +then : + WINED3DX_PE_LIBS="wined3dx dxguid windowscodecs" + if ${WINED3DX_PE_CFLAGS:+false} : +then : + WINED3DX_PE_CFLAGS="-I$(top_srcdir)/libs/wined3dx" +else $as_nop + enable_wined3dx=no +fi +else $as_nop + enable_wined3dx=no +fi +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wined3dx cflags: $WINED3DX_PE_CFLAGS" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: wined3dx libs: $WINED3DX_PE_LIBS" >&5 + if ${XML2_PE_LIBS:+false} : then : XML2_PE_LIBS=xml2 @@ -22074,6 +22099,7 @@ wine_fn_config_makefile libs/tiff enable_tiff wine_fn_config_makefile libs/uuid enable_uuid wine_fn_config_makefile libs/vkd3d enable_vkd3d wine_fn_config_makefile libs/wbemuuid enable_wbemuuid +wine_fn_config_makefile libs/wined3dx enable_wined3dx wine_fn_config_makefile libs/wmcodecdspuuid enable_wmcodecdspuuid wine_fn_config_makefile libs/xml2 enable_xml2 wine_fn_config_makefile libs/xslt enable_xslt @@ -23232,6 +23258,8 @@ TIFF_PE_CFLAGS = $TIFF_PE_CFLAGS TIFF_PE_LIBS = $TIFF_PE_LIBS VKD3D_PE_CFLAGS = $VKD3D_PE_CFLAGS VKD3D_PE_LIBS = $VKD3D_PE_LIBS +WINED3DX_PE_CFLAGS = $WINED3DX_PE_CFLAGS +WINED3DX_PE_LIBS = $WINED3DX_PE_LIBS XML2_PE_CFLAGS = $XML2_PE_CFLAGS XML2_PE_LIBS = $XML2_PE_LIBS XSLT_PE_CFLAGS = $XSLT_PE_CFLAGS diff --git a/configure.ac b/configure.ac index dab2bb07302..abc53604dde 100644 --- a/configure.ac +++ b/configure.ac @@ -1147,6 +1147,7 @@ WINE_EXTLIB_FLAGS(MUSL, musl, musl) WINE_EXTLIB_FLAGS(PNG, png, "png $(ZLIB_PE_LIBS)", "-I$(top_srcdir)/libs/png") WINE_EXTLIB_FLAGS(TIFF, tiff, "tiff $(ZLIB_PE_LIBS)", "-I$(top_srcdir)/libs/tiff/libtiff") WINE_EXTLIB_FLAGS(VKD3D, vkd3d, vkd3d, "-I$(top_srcdir)/libs/vkd3d/include") +WINE_EXTLIB_FLAGS(WINED3DX, wined3dx, "wined3dx dxguid windowscodecs", "-I$(top_srcdir)/libs/wined3dx") WINE_EXTLIB_FLAGS(XML2, xml2, xml2, "-I$(top_srcdir)/libs/xml2/include -DLIBXML_STATIC") WINE_EXTLIB_FLAGS(XSLT, xslt, xslt, "-I$(top_srcdir)/libs/xslt/libxslt -I$(top_srcdir)/libs/xslt -DLIBXSLT_STATIC") WINE_EXTLIB_FLAGS(ZLIB, zlib, z, "-I$(top_srcdir)/libs/zlib -DFAR= -DZ_SOLO") @@ -3336,6 +3337,7 @@ WINE_CONFIG_MAKEFILE(libs/tiff) WINE_CONFIG_MAKEFILE(libs/uuid) WINE_CONFIG_MAKEFILE(libs/vkd3d) WINE_CONFIG_MAKEFILE(libs/wbemuuid) +WINE_CONFIG_MAKEFILE(libs/wined3dx) WINE_CONFIG_MAKEFILE(libs/wmcodecdspuuid) WINE_CONFIG_MAKEFILE(libs/xml2) WINE_CONFIG_MAKEFILE(libs/xslt) diff --git a/libs/wined3dx/Makefile.in b/libs/wined3dx/Makefile.in new file mode 100644 index 00000000000..9ef77a13eea --- /dev/null +++ b/libs/wined3dx/Makefile.in @@ -0,0 +1,4 @@ +STATICLIB = libwined3dx.a + +C_SRCS = \ + texture.c diff --git a/libs/wined3dx/texture.c b/libs/wined3dx/texture.c new file mode 100644 index 00000000000..1bf084184ab --- /dev/null +++ b/libs/wined3dx/texture.c @@ -0,0 +1,24 @@ +/* + * Copyright 2023 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wined3dx.h" + +void function(void) +{ + /* Place Holder */ +} diff --git a/libs/wined3dx/wined3dx.h b/libs/wined3dx/wined3dx.h new file mode 100644 index 00000000000..6d5ff10ac67 --- /dev/null +++ b/libs/wined3dx/wined3dx.h @@ -0,0 +1,24 @@ +/* + * Copyright 2023 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef __WINED3DX_H__ +#define __WINED3DX_H__ + +/* Place Holder */ + + +#endif
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/d3dx10_43/Makefile.in | 3 +- dlls/d3dx10_43/async.c | 4 +- dlls/d3dx10_43/texture.c | 179 ++---------------------------------- libs/wined3dx/texture.c | 184 ++++++++++++++++++++++++++++++++++++- libs/wined3dx/wined3dx.h | 1 + 5 files changed, 194 insertions(+), 177 deletions(-)
diff --git a/dlls/d3dx10_43/Makefile.in b/dlls/d3dx10_43/Makefile.in index 0fab62f4834..c093894efdc 100644 --- a/dlls/d3dx10_43/Makefile.in +++ b/dlls/d3dx10_43/Makefile.in @@ -1,7 +1,8 @@ MODULE = d3dx10_43.dll IMPORTLIB = d3dx10 -IMPORTS = d3d10_1 d3dcompiler dxguid uuid gdi32 +IMPORTS = d3d10_1 d3dcompiler dxguid uuid gdi32 $(WINED3DX_PE_LIBS) DELAYIMPORTS = windowscodecs +EXTRAINCL = $(WINED3DX_PE_CFLAGS)
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c index 62627886804..0cf6648bf6d 100644 --- a/dlls/d3dx10_43/async.c +++ b/dlls/d3dx10_43/async.c @@ -23,6 +23,8 @@ #include "dxhelpers.h" #include "winternl.h"
+#include "wined3dx.h" + #include "wine/debug.h" #include "wine/list.h"
@@ -292,7 +294,7 @@ static HRESULT WINAPI texture_info_processor_Process(ID3DX10DataProcessor *iface struct texture_info_processor *processor = impl_from_ID3DX10DataProcessor(iface);
TRACE("iface %p, data %p, size %Iu.\n", iface, data, size); - return get_image_info(data, size, processor->info); + return wined3dx_get_image_info(data, size, processor->info); }
static HRESULT WINAPI texture_info_processor_CreateDeviceObject(ID3DX10DataProcessor *iface, void **object) diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index b925a07dd08..f39cd5ba7f0 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -25,26 +25,12 @@ #include "wincodec.h" #include "dxhelpers.h"
+#include "wined3dx.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT sdk_version, IWICImagingFactory **imaging_factory);
-static const struct -{ - const GUID *wic_container_guid; - D3DX10_IMAGE_FILE_FORMAT d3dx_file_format; -} -file_formats[] = -{ - { &GUID_ContainerFormatBmp, D3DX10_IFF_BMP }, - { &GUID_ContainerFormatJpeg, D3DX10_IFF_JPG }, - { &GUID_ContainerFormatPng, D3DX10_IFF_PNG }, - { &GUID_ContainerFormatDds, D3DX10_IFF_DDS }, - { &GUID_ContainerFormatTiff, D3DX10_IFF_TIFF }, - { &GUID_ContainerFormatGif, D3DX10_IFF_GIF }, - { &GUID_ContainerFormatWmp, D3DX10_IFF_WMP }, -}; - static const struct { const GUID *wic_guid; @@ -71,18 +57,6 @@ wic_pixel_formats[] = { &GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT } };
-static D3DX10_IMAGE_FILE_FORMAT wic_container_guid_to_file_format(GUID *container_format) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(file_formats); ++i) - { - if (IsEqualGUID(file_formats[i].wic_container_guid, container_format)) - return file_formats[i].d3dx_file_format; - } - return D3DX10_IFF_FORCE_DWORD; -} - static const GUID *dxgi_format_to_wic_guid(DXGI_FORMAT format) { unsigned int i; @@ -96,22 +70,6 @@ static const GUID *dxgi_format_to_wic_guid(DXGI_FORMAT format) return NULL; }
-static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension) -{ - switch (wic_dimension) - { - case WICDdsTexture1D: - return D3D10_RESOURCE_DIMENSION_TEXTURE1D; - case WICDdsTexture2D: - case WICDdsTextureCube: - return D3D10_RESOURCE_DIMENSION_TEXTURE2D; - case WICDdsTexture3D: - return D3D10_RESOURCE_DIMENSION_TEXTURE3D; - default: - return D3D10_RESOURCE_DIMENSION_UNKNOWN; - } -} - static unsigned int get_bpp_from_format(DXGI_FORMAT format) { switch (format) @@ -246,36 +204,6 @@ static unsigned int get_bpp_from_format(DXGI_FORMAT format) } }
-static DXGI_FORMAT get_d3dx10_dds_format(DXGI_FORMAT format) -{ - static const struct - { - DXGI_FORMAT src; - DXGI_FORMAT dst; - } - format_map[] = - { - {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, - {DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM}, - }; - - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(format_map); ++i) - { - if (format == format_map[i].src) - return format_map[i].dst; - } - return format; -} - HRESULT WINAPI D3DX10GetImageInfoFromFileA(const char *src_file, ID3DX10ThreadPump *pump, D3DX10_IMAGE_INFO *info, HRESULT *result) { @@ -339,7 +267,7 @@ HRESULT WINAPI D3DX10GetImageInfoFromFileW(const WCHAR *src_file, ID3DX10ThreadP
if (SUCCEEDED((hr = load_file(src_file, &buffer, &size)))) { - hr = get_image_info(buffer, size, info); + hr = wined3dx_get_image_info(buffer, size, info); free(buffer); } if (result) @@ -379,7 +307,7 @@ HRESULT WINAPI D3DX10GetImageInfoFromResourceA(HMODULE module, const char *resou
if (FAILED((hr = load_resourceA(module, resource, &buffer, &size)))) return hr; - hr = get_image_info(buffer, size, info); + hr = wined3dx_get_image_info(buffer, size, info); if (result) *result = hr; return hr; @@ -417,107 +345,12 @@ HRESULT WINAPI D3DX10GetImageInfoFromResourceW(HMODULE module, const WCHAR *reso
if (FAILED((hr = load_resourceW(module, resource, &buffer, &size)))) return hr; - hr = get_image_info(buffer, size, info); + hr = wined3dx_get_image_info(buffer, size, info); if (result) *result = hr; return hr; }
-HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) -{ - IWICBitmapFrameDecode *frame = NULL; - IWICImagingFactory *factory = NULL; - IWICDdsDecoder *dds_decoder = NULL; - IWICBitmapDecoder *decoder = NULL; - WICDdsParameters dds_params; - IWICStream *stream = NULL; - unsigned int frame_count; - GUID container_format; - HRESULT hr; - - WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); - IWICImagingFactory_CreateStream(factory, &stream); - hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size); - if (FAILED(hr)) - { - WARN("Failed to initialize stream.\n"); - goto end; - } - hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder); - if (FAILED(hr)) - goto end; - - hr = IWICBitmapDecoder_GetContainerFormat(decoder, &container_format); - if (FAILED(hr)) - goto end; - img_info->ImageFileFormat = wic_container_guid_to_file_format(&container_format); - if (img_info->ImageFileFormat == D3DX10_IFF_FORCE_DWORD) - { - hr = E_FAIL; - WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format)); - goto end; - } - - hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); - if (FAILED(hr) || !frame_count) - goto end; - hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - if (FAILED(hr)) - goto end; - hr = IWICBitmapFrameDecode_GetSize(frame, &img_info->Width, &img_info->Height); - if (FAILED(hr)) - goto end; - - if (img_info->ImageFileFormat == D3DX10_IFF_DDS) - { - hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); - if (FAILED(hr)) - goto end; - hr = IWICDdsDecoder_GetParameters(dds_decoder, &dds_params); - if (FAILED(hr)) - goto end; - img_info->ArraySize = dds_params.ArraySize; - img_info->Depth = dds_params.Depth; - img_info->MipLevels = dds_params.MipLevels; - img_info->ResourceDimension = wic_dimension_to_d3dx10_dimension(dds_params.Dimension); - img_info->Format = get_d3dx10_dds_format(dds_params.DxgiFormat); - img_info->MiscFlags = 0; - if (dds_params.Dimension == WICDdsTextureCube) - { - img_info->MiscFlags = D3D10_RESOURCE_MISC_TEXTURECUBE; - img_info->ArraySize *= 6; - } - } - else - { - img_info->ArraySize = 1; - img_info->Depth = 1; - img_info->MipLevels = 1; - img_info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; - img_info->Format = DXGI_FORMAT_R8G8B8A8_UNORM; - img_info->MiscFlags = 0; - } - -end: - if (dds_decoder) - IWICDdsDecoder_Release(dds_decoder); - if (frame) - IWICBitmapFrameDecode_Release(frame); - if (decoder) - IWICBitmapDecoder_Release(decoder); - if (stream) - IWICStream_Release(stream); - if (factory) - IWICImagingFactory_Release(factory); - - if (hr != S_OK) - { - WARN("Invalid or unsupported image file.\n"); - return E_FAIL; - } - return S_OK; -} - HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX10ThreadPump *pump, D3DX10_IMAGE_INFO *img_info, HRESULT *result) { @@ -549,7 +382,7 @@ HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_dat return hr; }
- hr = get_image_info(src_data, src_data_size, img_info); + hr = wined3dx_get_image_info(src_data, src_data_size, img_info); if (result) *result = hr; return hr; diff --git a/libs/wined3dx/texture.c b/libs/wined3dx/texture.c index 1bf084184ab..1712a164d8c 100644 --- a/libs/wined3dx/texture.c +++ b/libs/wined3dx/texture.c @@ -15,10 +15,190 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + +#include "d3d10_1.h" +#include "d3dx10.h" +#undef MAKE_DDHRESULT +#include "d3dx11.h" +#include "wincodec.h"
#include "wined3dx.h"
-void function(void) +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + +#include "wined3dx.h" + +HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT sdk_version, IWICImagingFactory **imaging_factory); + +static const struct +{ + const GUID *wic_container_guid; + D3DX10_IMAGE_FILE_FORMAT d3dx_file_format; +} +file_formats[] = +{ + { &GUID_ContainerFormatBmp, D3DX10_IFF_BMP }, + { &GUID_ContainerFormatJpeg, D3DX10_IFF_JPG }, + { &GUID_ContainerFormatPng, D3DX10_IFF_PNG }, + { &GUID_ContainerFormatDds, D3DX10_IFF_DDS }, + { &GUID_ContainerFormatTiff, D3DX10_IFF_TIFF }, + { &GUID_ContainerFormatGif, D3DX10_IFF_GIF }, + { &GUID_ContainerFormatWmp, D3DX10_IFF_WMP }, +}; + +static D3DX10_IMAGE_FILE_FORMAT wic_container_guid_to_file_format(GUID *container_format) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(file_formats); ++i) + { + if (IsEqualGUID(file_formats[i].wic_container_guid, container_format)) + return file_formats[i].d3dx_file_format; + } + return D3DX10_IFF_FORCE_DWORD; +} + +static DXGI_FORMAT get_d3dx10_dds_format(DXGI_FORMAT format) { - /* Place Holder */ + static const struct + { + DXGI_FORMAT src; + DXGI_FORMAT dst; + } + format_map[] = + { + {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM}, + {DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM}, + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(format_map); ++i) + { + if (format == format_map[i].src) + return format_map[i].dst; + } + return format; +} + +static D3D10_RESOURCE_DIMENSION wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension) +{ + switch (wic_dimension) + { + case WICDdsTexture1D: + return D3D10_RESOURCE_DIMENSION_TEXTURE1D; + case WICDdsTexture2D: + case WICDdsTextureCube: + return D3D10_RESOURCE_DIMENSION_TEXTURE2D; + case WICDdsTexture3D: + return D3D10_RESOURCE_DIMENSION_TEXTURE3D; + default: + return D3D10_RESOURCE_DIMENSION_UNKNOWN; + } +} + +HRESULT wined3dx_get_image_info(const void *data, SIZE_T size, void *imginfo) +{ + D3DX10_IMAGE_INFO *img_info = imginfo; + IWICBitmapFrameDecode *frame = NULL; + IWICImagingFactory *factory = NULL; + IWICDdsDecoder *dds_decoder = NULL; + IWICBitmapDecoder *decoder = NULL; + WICDdsParameters dds_params; + IWICStream *stream = NULL; + unsigned int frame_count; + GUID container_format; + HRESULT hr; + + WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); + IWICImagingFactory_CreateStream(factory, &stream); + hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size); + if (FAILED(hr)) + { + WARN("Failed to initialize stream.\n"); + goto end; + } + hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder); + if (FAILED(hr)) + goto end; + + hr = IWICBitmapDecoder_GetContainerFormat(decoder, &container_format); + if (FAILED(hr)) + goto end; + img_info->ImageFileFormat = wic_container_guid_to_file_format(&container_format); + if (img_info->ImageFileFormat == D3DX10_IFF_FORCE_DWORD) + { + hr = E_FAIL; + WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format)); + goto end; + } + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + if (FAILED(hr) || !frame_count) + goto end; + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + if (FAILED(hr)) + goto end; + hr = IWICBitmapFrameDecode_GetSize(frame, &img_info->Width, &img_info->Height); + if (FAILED(hr)) + goto end; + + if (img_info->ImageFileFormat == D3DX10_IFF_DDS) + { + hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICDdsDecoder, (void **)&dds_decoder); + if (FAILED(hr)) + goto end; + hr = IWICDdsDecoder_GetParameters(dds_decoder, &dds_params); + if (FAILED(hr)) + goto end; + img_info->ArraySize = dds_params.ArraySize; + img_info->Depth = dds_params.Depth; + img_info->MipLevels = dds_params.MipLevels; + img_info->ResourceDimension = wic_dimension_to_d3dx10_dimension(dds_params.Dimension); + img_info->Format = get_d3dx10_dds_format(dds_params.DxgiFormat); + img_info->MiscFlags = 0; + if (dds_params.Dimension == WICDdsTextureCube) + { + img_info->MiscFlags = D3D10_RESOURCE_MISC_TEXTURECUBE; + img_info->ArraySize *= 6; + } + } + else + { + img_info->ArraySize = 1; + img_info->Depth = 1; + img_info->MipLevels = 1; + img_info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + img_info->Format = DXGI_FORMAT_R8G8B8A8_UNORM; + img_info->MiscFlags = 0; + } + +end: + if (dds_decoder) + IWICDdsDecoder_Release(dds_decoder); + if (frame) + IWICBitmapFrameDecode_Release(frame); + if (decoder) + IWICBitmapDecoder_Release(decoder); + if (stream) + IWICStream_Release(stream); + if (factory) + IWICImagingFactory_Release(factory); + + if (hr != S_OK) + { + WARN("Invalid or unsupported image file.\n"); + return E_FAIL; + } + return S_OK; } diff --git a/libs/wined3dx/wined3dx.h b/libs/wined3dx/wined3dx.h index 6d5ff10ac67..201a4e37a2f 100644 --- a/libs/wined3dx/wined3dx.h +++ b/libs/wined3dx/wined3dx.h @@ -20,5 +20,6 @@
/* Place Holder */
+HRESULT wined3dx_get_image_info(const void *data, SIZE_T size, void *img_info);
#endif
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/d3dx11_42/Makefile.in | 3 ++- dlls/d3dx11_43/Makefile.in | 3 ++- dlls/d3dx11_43/main.c | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx11_42/Makefile.in b/dlls/d3dx11_42/Makefile.in index 7fcce18a8e1..6dfb2460042 100644 --- a/dlls/d3dx11_42/Makefile.in +++ b/dlls/d3dx11_42/Makefile.in @@ -1,8 +1,9 @@ EXTRADEFS = -DD3DX11_SDK_VERSION=42 MODULE = d3dx11_42.dll IMPORTLIB = d3dx11_42 -IMPORTS = d3dcompiler +IMPORTS = d3dcompiler $(WINED3DX_PE_LIBS) PARENTSRC = ../d3dx11_43 +EXTRAINCL = $(WINED3DX_PE_CFLAGS)
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/d3dx11_43/Makefile.in b/dlls/d3dx11_43/Makefile.in index ccd4319ace2..d3ad9beee06 100644 --- a/dlls/d3dx11_43/Makefile.in +++ b/dlls/d3dx11_43/Makefile.in @@ -1,7 +1,8 @@ EXTRADEFS = -DD3DX11_SDK_VERSION=43 MODULE = d3dx11_43.dll IMPORTLIB = d3dx11 -IMPORTS = d3dcompiler +IMPORTS = d3dcompiler $(WINED3DX_PE_LIBS) +EXTRAINCL = $(WINED3DX_PE_CFLAGS)
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/d3dx11_43/main.c b/dlls/d3dx11_43/main.c index 5dad027864f..c9b17be200b 100644 --- a/dlls/d3dx11_43/main.c +++ b/dlls/d3dx11_43/main.c @@ -29,6 +29,8 @@ #include "d3dx11core.h" #include "d3dx11tex.h"
+#include "wined3dx.h" + #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3dx); @@ -70,8 +72,13 @@ HRESULT WINAPI D3DX11GetImageInfoFromFileW(const WCHAR *filename, ID3DX11ThreadP HRESULT WINAPI D3DX11GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX11ThreadPump *pump, D3DX11_IMAGE_INFO *img_info, HRESULT *hresult) { + HRESULT hr; + FIXME("src_data %p, src_data_size %Iu, pump %p, img_info %p, hresult %p stub!\n", src_data, src_data_size, pump, img_info, hresult);
- return E_NOTIMPL; + hr = wined3dx_get_image_info(src_data, src_data_size, img_info); + if (hresult) + *hresult = hr; + return hr; }
Thanks Alistair for the MR; I can't seem to find the time for getting started with this endeavor myself.
If I recall correctly from the last time I had a conversation with Alexandre about this, the plan was to factor out common code as needed for reuse, but have it live in one of the existing DLLs for the time being (it could either stay in d3dx10 or be moved to d3dx11, not sure - I haven't thought it through) and use PARENTSRC for sharing. Once we've gone through most of the d3dx1* functions and the "helpers API" is stabilized we could then split all that stuff out to a separate DLL and get the additional benefits of reduced total DLL size and compilation time.
I'll try to prepare an initial MR following this new plan. No guarantees that I'll get to it any time soon.
Mostly just to add my own scepticism to Alexandre's, but also for the record (I don't think that was a public conversation): If it's in fact worth the effort to define some kind of sensible API (and I'm not sure wined3dx_get_image_info() from this MR qualifies...), we might as well make that API available as part of vkd3d, along the lines of something like vkd3d-utils.
It also seems tempting to just use the existing d3dx API for this, possibly with a couple of versioned variants of some exports. The number of instances of D3DX_SDK_VERSION/D3DX10_SDK_VERSION/D3DX11_SDK_VERSION seems rather limited, and mostly confined to the effects framework. The bulk of that code is already within the scope of libvkd3d-shader. The number of instances of D3D_COMPILER_VERSION is slightly larger, but d3dcompiler as a whole is also already within the scope of libvkd3d-shader.
If it's in fact worth the effort to define some kind of sensible API (and I'm not sure wined3dx_get_image_info() from this MR qualifies...)
I guess that's the fundamental question. I'm not sure that's the case. Working our way through one piece at a time, like I mentioned in my previous comment, might tell us that without making the effort of doing the whole design beforehand to then maybe throw everything away.
My most pressing objective here is to unblock further d3dx* work, in particular for features already implemented for other d3dx* versions. Duplicating tons of code still seems very wrong to me. PARENTSRC between different d3dx* versions should be okay for the time being[*]. Maybe "forever" as well, if we figure out that we want to stop there and not create a separate DLL, or move the implementation to vkd3d, after all. Either way, it seems to me that it would be best evaluated once we start to try and fit the different APIs from d3dx9, 10 and 11 into a mostly shared codebase.
[*]: There's the unfortunate issue that PARENTSRC is already in use for d3dx9 and d3dx11 DLLs (from the _xx versions towards the "real" one, respectively _36 and _43). We don't really need those though, for the most part this was to avoid forwards for e.g. bug 21817, which we can now do otherwise with -import in the spec file. Or we could make PARENTSRC work with multiple paths, although that's probably unnecessary.
My most pressing objective here is to unblock further d3dx* work, in particular for features already implemented for other d3dx* versions. Duplicating tons of code still seems very wrong to me. PARENTSRC between different d3dx* versions should be okay for the time being[*]. Maybe "forever" as well, if we figure out that we want to stop there and not create a separate DLL, or move the implementation to vkd3d, after all. Either way, it seems to me that it would be best evaluated once we start to try and fit the different APIs from d3dx9, 10 and 11 into a mostly shared codebase.
Are we thinking about any part of d3dx in particular? We may want to do different things for different functionality. The maths functions like e.g. D3DXMatrixRotationX() would be very straightforward to add to a new "vkd3d-maths" library, and would also be some of the most generally useful functionality; beyond d3dx we'd be able to use something like that in wined3d, d2d1, possibly gdiplus, vkd3d-gears, and vkmodelviewer just from the top of my head. The texture/surface functions may be a fair bit harder, but no less useful, IMO. I think there's a bit of a lack of free, maintained, straightforward, Linux libraries for loading/handling e.g. DDS textures.
Are we thinking about any part of d3dx in particular? We may want to do different things for different functionality.
My guess is, that's probably where we'll end up. Agreed, math functions should be the easiest to share and most useful for vkd3d as well. Similarly for "shader" stuff, as you mentioned earlier.
WRT texture functions, that's problematic at the moment mostly because of the Windows dependencies (mainly WIC). That's especially true for the current d3dx10 implementation and, in fact, one of my primary immediate motivations for sharing is to reuse (most of) the d3dx9 implementation, which is quite a bit more self-contained, elsewhere. Once that is done we could start to investigate porting that part to vkd3d and e.g. initially supporting non-DDS file formats only on Windows.