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 | 4 +- dlls/d3dx10_43/dxhelpers.h | 2 + dlls/d3dx10_43/texture.c | 143 +++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx10_43/Makefile.in b/dlls/d3dx10_43/Makefile.in index 3d755499749..2889ae1949a 100644 --- a/dlls/d3dx10_43/Makefile.in +++ b/dlls/d3dx10_43/Makefile.in @@ -1,6 +1,7 @@ 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 +9,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..70bf062dd33 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -29,6 +29,90 @@ 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 D3DX10_IMAGE_FILE_FORMAT d3dx10_image_file_format_from_d3dx_image_file_format(enum d3dx_image_file_format iff) +{ + switch (iff) + { + case D3DX_IMAGE_FILE_FORMAT_BMP: return D3DX10_IFF_BMP; + case D3DX_IMAGE_FILE_FORMAT_JPG: return D3DX10_IFF_JPG; + case D3DX_IMAGE_FILE_FORMAT_PNG: return D3DX10_IFF_PNG; + case D3DX_IMAGE_FILE_FORMAT_DDS: return D3DX10_IFF_DDS; + default: + FIXME("No D3DX10_IMAGE_FILE_FORMAT for d3dx_image_file_format %d.\n", iff); + return D3DX10_IFF_FORCE_DWORD; + } +} + static const struct { const GUID *wic_container_guid; @@ -423,6 +507,51 @@ 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) +{ + D3DX10_IMAGE_FILE_FORMAT iff = d3dx10_image_file_format_from_d3dx_image_file_format(image->image_file_format); + DXGI_FORMAT format = dxgi_format_from_legacy_dds_d3dx_pixel_format_id(image->format); + + 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; + } + + if (iff == D3DX10_IFF_FORCE_DWORD) + return E_FAIL; + + 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); + return E_FAIL; + } + + info->ImageFileFormat = iff; + 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; + return S_OK; +} + HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) { IWICBitmapFrameDecode *frame = NULL; @@ -432,9 +561,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);