From 96847bdbe61c80e3b3448b2b4bd5231f95a0af2f Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Fri, 16 Aug 2024 13:02:17 -0700 Subject: [PATCH] Update for latest version of DDS.h --- Src/DDS.h | 69 ++++++++++++++++++++++++++++-------- Src/LoaderHelpers.h | 13 ++++--- Src/ScreenGrab.cpp | 7 ++-- Src/XboxDDSTextureLoader.cpp | 39 ++++---------------- 4 files changed, 70 insertions(+), 58 deletions(-) diff --git a/Src/DDS.h b/Src/DDS.h index cce220c7d..9fcaad641 100644 --- a/Src/DDS.h +++ b/Src/DDS.h @@ -39,17 +39,18 @@ namespace DirectX uint32_t ABitMask; }; -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_ALPHAPIXELS 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_ALPHA 0x00000002 // DDPF_ALPHA -#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 -#define DDS_PAL8A 0x00000021 // DDPF_PALETTEINDEXED8 | DDPF_ALPHAPIXELS -#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV -// DDS_BUMPLUMINANCE 0x00040000 +#define DDS_FOURCC 0x00000004 // DDPF_FOURCC +#define DDS_RGB 0x00000040 // DDPF_RGB +#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS +#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE +#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS +#define DDS_ALPHAPIXELS 0x00000001 // DDPF_ALPHAPIXELS +#define DDS_ALPHA 0x00000002 // DDPF_ALPHA +#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 +#define DDS_PAL8A 0x00000021 // DDPF_PALETTEINDEXED8 | DDPF_ALPHAPIXELS +#define DDS_BUMPLUMINANCE 0x00040000 // DDPF_BUMPLUMINANCE +#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV +#define DDS_BUMPDUDVA 0x00080001 // DDPF_BUMPDUDV | DDPF_ALPHAPIXELS #ifndef MAKEFOURCC #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ @@ -187,10 +188,13 @@ namespace DirectX DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A2B10G10R10 = { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }; -// We do not support the following legacy Direct3D 9 formats: -// DDSPF_A2W10V10U10 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }; -// DDSPF_L6V5U5 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 16, 0x001f, 0x03e0, 0xfc00, 0 }; -// DDSPF_X8L8V8U8 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0 }; +// The following legacy Direct3D 9 formats use 'mixed' signed & unsigned channels so requires special handling + DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A2W10V10U10 = + { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDVA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }; + DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_L6V5U5 = + { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 16, 0x001f, 0x03e0, 0xfc00, 0 }; + DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_X8L8V8U8 = + { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0 }; // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat) DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_DX10 = @@ -288,4 +292,39 @@ namespace DirectX static_assert(sizeof(DDS_HEADER) == 124, "DDS Header size mismatch"); static_assert(sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended Header size mismatch"); + constexpr size_t DDS_MIN_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER); + constexpr size_t DDS_DX10_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); + static_assert(DDS_DX10_HEADER_SIZE > DDS_MIN_HEADER_SIZE, "DDS DX10 Header should be larger than standard header"); + +} // namespace + +namespace Xbox +{ + DDSGLOBALCONST DirectX::DDS_PIXELFORMAT DDSPF_XBOX = + { sizeof(DirectX::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('X','B','O','X'), 0, 0, 0, 0, 0 }; + +#pragma pack(push,1) + + struct DDS_HEADER_XBOX + // Must match structure in XboxDDSTextureLoader module + { + DXGI_FORMAT dxgiFormat; + uint32_t resourceDimension; + uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG + uint32_t arraySize; + uint32_t miscFlags2; // see DDS_MISC_FLAGS2 + uint32_t tileMode; // see XG_TILE_MODE / XG_SWIZZLE_MODE + uint32_t baseAlignment; + uint32_t dataSize; + uint32_t xdkVer; // matching _XDK_VER / _GXDK_VER + }; + +#pragma pack(pop) + + static_assert(sizeof(DDS_HEADER_XBOX) == 36, "DDS XBOX Header size mismatch"); + static_assert(sizeof(DDS_HEADER_XBOX) > sizeof(DirectX::DDS_HEADER_DXT10), "DDS XBOX Header should be larger than DX10 header"); + + constexpr size_t DDS_XBOX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DirectX::DDS_HEADER) + sizeof(DDS_HEADER_XBOX); + + constexpr uint32_t XBOX_TILEMODE_SCARLETT = 0x1000000; } // namespace diff --git a/Src/LoaderHelpers.h b/Src/LoaderHelpers.h index 0976889f0..96a114289 100644 --- a/Src/LoaderHelpers.h +++ b/Src/LoaderHelpers.h @@ -334,7 +334,7 @@ namespace DirectX return E_FAIL; } - if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + if (ddsDataSize < DDS_MIN_HEADER_SIZE) { return E_FAIL; } @@ -361,7 +361,7 @@ namespace DirectX (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value - if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) + if (ddsDataSize < DDS_DX10_HEADER_SIZE) { return E_FAIL; } @@ -371,8 +371,7 @@ namespace DirectX // setup the pointers in the process request *header = hdr; - auto offset = sizeof(uint32_t) - + sizeof(DDS_HEADER) + auto offset = DDS_MIN_HEADER_SIZE + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0u); *bitData = ddsData + offset; *bitSize = ddsDataSize - offset; @@ -429,7 +428,7 @@ namespace DirectX } // Need at least enough data to fill the header and magic number to be a valid DDS - if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + if (fileInfo.EndOfFile.LowPart < DDS_MIN_HEADER_SIZE) { return E_FAIL; } @@ -484,7 +483,7 @@ namespace DirectX (MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC)) { // Must be long enough for both headers and magic value - if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10))) + if (fileInfo.EndOfFile.LowPart < DDS_DX10_HEADER_SIZE) { ddsData.reset(); return E_FAIL; @@ -495,7 +494,7 @@ namespace DirectX // setup the pointers in the process request *header = hdr; - auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER) + auto offset = DDS_MIN_HEADER_SIZE + (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0u); *bitData = ddsData.get() + offset; *bitSize = fileInfo.EndOfFile.LowPart - offset; diff --git a/Src/ScreenGrab.cpp b/Src/ScreenGrab.cpp index 22bcd48db..470e76788 100644 --- a/Src/ScreenGrab.cpp +++ b/Src/ScreenGrab.cpp @@ -204,13 +204,12 @@ HRESULT DirectX::SaveDDSTextureToFile( auto_delete_file delonfail(hFile.get()); // Setup header - constexpr size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - uint8_t fileHeader[MAX_HEADER_SIZE] = {}; + uint8_t fileHeader[DDS_DX10_HEADER_SIZE] = {}; *reinterpret_cast(&fileHeader[0]) = DDS_MAGIC; auto header = reinterpret_cast(&fileHeader[0] + sizeof(uint32_t)); - size_t headerSize = sizeof(uint32_t) + sizeof(DDS_HEADER); + size_t headerSize = DDS_MIN_HEADER_SIZE; header->size = sizeof(DDS_HEADER); header->flags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP; header->height = desc.Height; @@ -268,7 +267,7 @@ HRESULT DirectX::SaveDDSTextureToFile( memcpy(&header->ddspf, &DDSPF_DX10, sizeof(DDS_PIXELFORMAT)); headerSize += sizeof(DDS_HEADER_DXT10); - extHeader = reinterpret_cast(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER)); + extHeader = reinterpret_cast(fileHeader + DDS_MIN_HEADER_SIZE); extHeader->dxgiFormat = desc.Format; extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; extHeader->arraySize = 1; diff --git a/Src/XboxDDSTextureLoader.cpp b/Src/XboxDDSTextureLoader.cpp index c9aa9cc49..95ceedfc0 100644 --- a/Src/XboxDDSTextureLoader.cpp +++ b/Src/XboxDDSTextureLoader.cpp @@ -40,31 +40,6 @@ namespace XALLOC_PAGESIZE_64KB, XALLOC_ALIGNMENT_64K); - //-------------------------------------------------------------------------------------- - // DDS file structure definitions - // - // See DDS.h in the 'Texconv' sample and the 'DirectXTex' library - //-------------------------------------------------------------------------------------- - #pragma pack(push,1) - - struct DDS_HEADER_XBOX - // Must match structure defined in xtexconv tool - { - DXGI_FORMAT dxgiFormat; - uint32_t resourceDimension; - uint32_t miscFlag; // see DDS_RESOURCE_MISC_FLAG - uint32_t arraySize; - uint32_t miscFlags2; // see DDS_MISC_FLAGS2 - uint32_t tileMode; // see XG_TILE_MODE - uint32_t baseAlignment; - uint32_t dataSize; - uint32_t xdkVer; // matching _XDK_VER - }; - - static_assert(sizeof(DDS_HEADER_XBOX) == 36, "DDS XBOX Header size mismatch"); - - #pragma pack(pop) - //-------------------------------------------------------------------------------------- HRESULT LoadTextureDataFromFile(_In_z_ const wchar_t* fileName, std::unique_ptr& ddsData, @@ -105,7 +80,7 @@ namespace } // Need at least enough data to fill the header and magic number to be a valid DDS - if (FileSize.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) + if (FileSize.LowPart < DDS_MIN_HEADER_SIZE) { return E_FAIL; } @@ -159,14 +134,14 @@ namespace } // Must be long enough for both headers and magic value - if (FileSize.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_XBOX))) + if (FileSize.LowPart < DDS_XBOX_HEADER_SIZE) { return E_FAIL; } // setup the pointers in the process request *header = hdr; - auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_XBOX); + auto offset = DDS_XBOX_HEADER_SIZE; *bitData = ddsData.get() + offset; *bitSize = FileSize.LowPart - offset; @@ -643,7 +618,7 @@ HRESULT Xbox::CreateDDSTextureFromMemory( } // Validate DDS file in memory - if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) + if (ddsDataSize < DDS_MIN_HEADER_SIZE) { return E_FAIL; } @@ -654,7 +629,7 @@ HRESULT Xbox::CreateDDSTextureFromMemory( return E_FAIL; } - auto header = reinterpret_cast( ddsData + sizeof( uint32_t ) ); + auto header = reinterpret_cast(ddsData + sizeof(uint32_t)); // Verify header to validate DDS file if (header->size != sizeof(DDS_HEADER) || @@ -672,12 +647,12 @@ HRESULT Xbox::CreateDDSTextureFromMemory( } // Must be long enough for both headers and magic value - if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_XBOX))) + if (ddsDataSize < DDS_XBOX_HEADER_SIZE) { return E_FAIL; } - auto offset = sizeof( uint32_t ) + sizeof( DDS_HEADER ) + sizeof( DDS_HEADER_XBOX ); + auto offset = DDS_XBOX_HEADER_SIZE; HRESULT hr = CreateTextureFromDDS( d3dDevice, header, ddsData + offset, ddsDataSize - offset, forceSRGB,