From: Connor McAdams cmcadams@codeweavers.com
This currently only supports non-DXT10 DDS files.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/Makefile.in | 5 +- dlls/d3dx10_43/dxhelpers.h | 2 + dlls/d3dx10_43/texture.c | 133 +++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/d3dx_helpers.h | 35 +++++++++ 4 files changed, 174 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx10_43/Makefile.in b/dlls/d3dx10_43/Makefile.in index 3d755499749..428f35e29bd 100644 --- a/dlls/d3dx10_43/Makefile.in +++ b/dlls/d3dx10_43/Makefile.in @@ -1,6 +1,8 @@ +EXTRADEFS = -DD3DX_D3D_VERSION=10 MODULE = d3dx10_43.dll IMPORTLIB = d3dx10 -IMPORTS = d3d10_1 d3dcompiler dxguid uuid gdi32 +IMPORTS = d3d10_1 d3dcompiler dxguid uuid gdi32 ole32 user32 +PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
EXTRADLLFLAGS = -Wb,--prefer-native @@ -8,6 +10,7 @@ EXTRADLLFLAGS = -Wb,--prefer-native SOURCES = \ async.c \ compiler.c \ + d3dx_helpers.c \ d3dx10_43_main.c \ font.c \ mesh.c \ diff --git a/dlls/d3dx10_43/dxhelpers.h b/dlls/d3dx10_43/dxhelpers.h index 50d509973cd..49f56d63a23 100644 --- a/dlls/d3dx10_43/dxhelpers.h +++ b/dlls/d3dx10_43/dxhelpers.h @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "../d3dx9_36/d3dx_helpers.h" + extern HRESULT load_file(const WCHAR *path, void **data, DWORD *size); extern HRESULT load_resourceA(HMODULE module, const char *resource, void **data, DWORD *size); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index b925a07dd08..7d172264155 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -29,6 +29,76 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT sdk_version, IWICImagingFactory **imaging_factory);
+/* + * These are mappings from legacy DDS header formats to DXGI formats. Some + * don't map to a DXGI_FORMAT at all, and some only map to the default format. + */ +static DXGI_FORMAT dxgi_format_from_legacy_dds_d3dx_pixel_format_id(enum d3dx_pixel_format_id format) +{ + switch (format) + { + /* + * Some of these formats do have DXGI_FORMAT equivalents, but get + * mapped to DXGI_FORMAT_R8G8B8A8_UNORM instead. + */ + case D3DX_PIXEL_FORMAT_P8_UINT: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_P8_UINT_A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_R8G8B8X8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B8G8R8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B5G6R5_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B5G5R5X1_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B5G5R5A1_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B2G3R3_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B2G3R3A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B4G4R4A4_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_B4G4R4X4_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_L8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_L4A4_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DX_PIXEL_FORMAT_L8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + + /* B10G10R10A2 doesn't exist in DXGI, both map to R10G10B10A2. */ + case D3DX_PIXEL_FORMAT_B10G10R10A2_UNORM: + case D3DX_PIXEL_FORMAT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; + + case D3DX_PIXEL_FORMAT_U16V16W16Q16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; + case D3DX_PIXEL_FORMAT_L16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DX_PIXEL_FORMAT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DX_PIXEL_FORMAT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; + case D3DX_PIXEL_FORMAT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; + case D3DX_PIXEL_FORMAT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case D3DX_PIXEL_FORMAT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case D3DX_PIXEL_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case D3DX_PIXEL_FORMAT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case D3DX_PIXEL_FORMAT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case D3DX_PIXEL_FORMAT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case D3DX_PIXEL_FORMAT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case D3DX_PIXEL_FORMAT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; + + case D3DX_PIXEL_FORMAT_DXT1_UNORM: return DXGI_FORMAT_BC1_UNORM; + case D3DX_PIXEL_FORMAT_DXT2_UNORM: return DXGI_FORMAT_BC2_UNORM; + case D3DX_PIXEL_FORMAT_DXT3_UNORM: return DXGI_FORMAT_BC2_UNORM; + case D3DX_PIXEL_FORMAT_DXT4_UNORM: return DXGI_FORMAT_BC3_UNORM; + case D3DX_PIXEL_FORMAT_DXT5_UNORM: return DXGI_FORMAT_BC3_UNORM; + + /* These formats are known and explicitly unsupported on d3dx10+. */ + case D3DX_PIXEL_FORMAT_U8V8W8Q8_SNORM: + case D3DX_PIXEL_FORMAT_U8V8_SNORM: + case D3DX_PIXEL_FORMAT_U16V16_SNORM: + case D3DX_PIXEL_FORMAT_U8V8_SNORM_L8X8_UNORM: + case D3DX_PIXEL_FORMAT_U10V10W10_SNORM_A2_UNORM: + case D3DX_PIXEL_FORMAT_UYVY: + case D3DX_PIXEL_FORMAT_YUY2: + return DXGI_FORMAT_UNKNOWN; + + default: + FIXME("Unknown d3dx_pixel_format_id %#x.\n", format); + return DXGI_FORMAT_UNKNOWN; + } +} + static const struct { const GUID *wic_container_guid; @@ -423,6 +493,55 @@ HRESULT WINAPI D3DX10GetImageInfoFromResourceW(HMODULE module, const WCHAR *reso return hr; }
+static HRESULT d3dx10_image_info_from_d3dx_image(D3DX10_IMAGE_INFO *info, struct d3dx_image *image) +{ + DXGI_FORMAT format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + HRESULT hr = S_OK; + + memset(info, 0, sizeof(*info)); + if (format == DXGI_FORMAT_UNKNOWN) + { + WARN("Tried to load DDS file with unsupported format %#x.\n", image->format); + return E_FAIL; + } + + info->ImageFileFormat = (D3DX10_IMAGE_FILE_FORMAT)image->image_file_format; + if (info->ImageFileFormat == D3DX10_IFF_FORCE_DWORD) + { + ERR("Unsupported d3dx image file.\n"); + return E_FAIL; + } + + info->Width = image->size.width; + info->Height = image->size.height; + info->Depth = image->size.depth; + info->ArraySize = image->layer_count; + info->MipLevels = image->mip_levels; + info->Format = format; + switch (image->resource_type) + { + case D3DX_RESOURCE_TYPE_TEXTURE_2D: + info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + break; + + case D3DX_RESOURCE_TYPE_CUBE_TEXTURE: + info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D; + info->MiscFlags |= D3D10_RESOURCE_MISC_TEXTURECUBE; + break; + + case D3DX_RESOURCE_TYPE_TEXTURE_3D: + info->ResourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D; + break; + + default: + ERR("Unhandled resource type %d.\n", image->resource_type); + hr = E_FAIL; + break; + } + + return hr; +} + HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) { IWICBitmapFrameDecode *frame = NULL; @@ -432,9 +551,23 @@ HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_inf WICDdsParameters dds_params; IWICStream *stream = NULL; unsigned int frame_count; + struct d3dx_image image; GUID container_format; HRESULT hr;
+ if (!data || !size) + return E_FAIL; + + if (SUCCEEDED(d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_INFO_ONLY)) + && image.image_file_format == D3DX_IMAGE_FILE_FORMAT_DDS) + { + if (SUCCEEDED(d3dx10_image_info_from_d3dx_image(img_info, &image))) + { + TRACE("Successfully retrieved image info from shared code.\n"); + return S_OK; + } + } + WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory); IWICImagingFactory_CreateStream(factory, &stream); hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size); diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index fb139ed8cb9..7bfd7e88be3 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -29,6 +29,41 @@ #include "d3dx9.h" #endif /* D3DX_D3D_VERSION == 9 */
+#if D3DX_D3D_VERSION == 10 +#define COBJMACROS +#include "d3dx10.h" + +#define D3DERR_INVALIDCALL 0x8876086c +#define D3DXERR_INVALIDDATA D3DX10_ERR_INVALID_DATA +#define D3D_OK S_OK + +#define D3DX_FILTER_NONE D3DX10_FILTER_NONE +#define D3DX_FILTER_POINT D3DX10_FILTER_POINT +#define D3DX_FILTER_LINEAR D3DX10_FILTER_LINEAR +#define D3DX_FILTER_TRIANGLE D3DX10_FILTER_TRIANGLE +#define D3DX_FILTER_BOX D3DX10_FILTER_BOX +#define D3DX_FILTER_MIRROR_U D3DX10_FILTER_MIRROR_U +#define D3DX_FILTER_MIRROR_V D3DX10_FILTER_MIRROR_V +#define D3DX_FILTER_MIRROR_W D3DX10_FILTER_MIRROR_W +#define D3DX_FILTER_MIRROR D3DX10_FILTER_MIRROR +#define D3DX_FILTER_DITHER D3DX10_FILTER_DITHER +#define D3DX_FILTER_DITHER_DIFFUSION D3DX10_FILTER_DITHER_DIFFUSION +#define D3DX_FILTER_SRGB_IN D3DX10_FILTER_SRGB_IN +#define D3DX_FILTER_SRGB_OUT D3DX10_FILTER_SRGB_OUT +#define D3DX_FILTER_SRGB D3DX10_FILTER_SRGB + +#define ID3DXBuffer ID3D10Blob +#define D3DXCreateBuffer(size, blob) D3D10CreateBlob(size, blob) +#define ID3DXBuffer_GetBufferPointer(blob) ID3D10Blob_GetBufferPointer(blob) +#define ID3DXBuffer_Release(blob) ID3D10Blob_Release(blob) + +#ifndef MAKEFOURCC +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ + ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +#endif +#endif /* D3DX_D3D_VERSION == 10 */ + #define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256)
/* dds_header.flags */