Fix DX12 Capture transition state handling for MSAA (#532)
Some checks failed
MSBuild / build (Debug, x86, 2022) (push) Has been cancelled
CTest (BVTs) / build (amd64, x64-Release, windows-2022) (push) Has been cancelled
CTest (BVTs) / build (amd64, x64-Release, windows-2019) (push) Has been cancelled
MSBuild / build (Debug, x86, 2019) (push) Has been cancelled
CodeQL / Analyze (C/C++) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Debug, windows-2019) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Debug, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Debug-Clang, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Release, windows-2019) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Release, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64, x64-Release-Clang, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_arm64, arm64-Debug, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_arm64, arm64-Release, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_arm64, arm64ec-Debug, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_arm64, arm64ec-Release, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Debug, windows-2019) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Debug, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Debug-Clang, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Release, windows-2019) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Release, windows-2022) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Release-Clang, windows-2022) (push) Has been cancelled
MSBuild / build (Debug, ARM64, 2019) (push) Has been cancelled
MSBuild / build (Debug, ARM64, 2022) (push) Has been cancelled
MSBuild / build (Debug, x64, 2019) (push) Has been cancelled
MSBuild / build (Debug, x64, 2022) (push) Has been cancelled
MSBuild / build (Release, ARM64, 2019) (push) Has been cancelled
MSBuild / build (Release, ARM64, 2022) (push) Has been cancelled
MSBuild / build (Release, x64, 2019) (push) Has been cancelled
MSBuild / build (Release, x64, 2022) (push) Has been cancelled
MSBuild / build (Release, x86, 2019) (push) Has been cancelled
MSBuild / build (Release, x86, 2022) (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Debug, windows-2019) (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Debug, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Debug-Clang, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Release, windows-2019) (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Release, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64, x64-Release-Clang, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_arm64, arm64-Debug, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_arm64, arm64-Release, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_arm64, arm64ec-Debug, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_arm64, arm64ec-Release, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Debug, windows-2019) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Debug, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Debug-Clang, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Release, windows-2019) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Release, windows-2022) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Release-Clang, windows-2022) (push) Has been cancelled
CMake (Windows using VCPKG) / build (amd64, x64-Debug-Clang-VCPKG, windows-2022) (push) Has been cancelled
CMake (Windows using VCPKG) / build (amd64, x64-Debug-VCPKG, windows-2019) (push) Has been cancelled
CMake (Windows using VCPKG) / build (amd64, x64-Debug-VCPKG, windows-2022) (push) Has been cancelled
CMake (Windows using VCPKG) / build (amd64_arm64, arm64-Debug-VCPKG, windows-2022) (push) Has been cancelled
CMake (Windows using VCPKG) / build (amd64_x86, x86-Debug-VCPKG, windows-2022) (push) Has been cancelled
CMake (WSL) / build (x64-Debug-Linux, 10) (push) Has been cancelled
CMake (WSL) / build (x64-Debug-Linux, 11) (push) Has been cancelled
CMake (WSL) / build (x64-Debug-Linux, 12) (push) Has been cancelled
CMake (WSL) / build (x64-Release-Linux, 10) (push) Has been cancelled
CMake (WSL) / build (x64-Release-Linux, 11) (push) Has been cancelled
CMake (WSL) / build (x64-Release-Linux, 12) (push) Has been cancelled

This commit is contained in:
Chuck Walbourn
2024-10-14 15:49:44 -07:00
committed by GitHub
parent 1262c4b293
commit 09affb78aa
7 changed files with 356 additions and 298 deletions

View File

@@ -18,6 +18,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <new>
@@ -52,83 +53,91 @@ using namespace DirectX;
// DDS file structure definitions
//
// See DDS.h in the 'Texconv' sample and the 'DirectXTex' library
//--------------------------------------------------------------------------------------
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
enum DDS_MISC_FLAGS2
{
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
};
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
struct DDS_HEADER_DXT10
{
DXGI_FORMAT dxgiFormat;
uint32_t resourceDimension;
uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG
uint32_t arraySize;
uint32_t miscFlags2;
};
#pragma pack(pop)
//--------------------------------------------------------------------------------------
namespace
{
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
enum DDS_MISC_FLAGS2
{
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
};
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
struct DDS_HEADER_DXT10
{
DXGI_FORMAT dxgiFormat;
uint32_t resourceDimension;
uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG
uint32_t arraySize;
uint32_t miscFlags2;
};
#pragma pack(pop)
static_assert(sizeof(DDS_PIXELFORMAT) == 32, "DDS pixel format size mismatch");
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");
//--------------------------------------------------------------------------------------
struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>;
@@ -168,7 +177,7 @@ namespace
return E_FAIL;
}
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
if (ddsDataSize < DDS_MIN_HEADER_SIZE)
{
return E_FAIL;
}
@@ -195,7 +204,7 @@ namespace
(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;
}
@@ -205,8 +214,7 @@ namespace
// 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;
@@ -264,7 +272,7 @@ namespace
}
// 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;
}
@@ -319,7 +327,7 @@ namespace
(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;
@@ -330,7 +338,7 @@ namespace
// 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;

View File

@@ -18,6 +18,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <new>
@@ -80,83 +81,91 @@ using namespace DirectX;
// DDS file structure definitions
//
// See DDS.h in the 'Texconv' sample and the 'DirectXTex' library
//--------------------------------------------------------------------------------------
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
enum DDS_MISC_FLAGS2
{
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
};
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
struct DDS_HEADER_DXT10
{
DXGI_FORMAT dxgiFormat;
uint32_t resourceDimension;
uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG
uint32_t arraySize;
uint32_t miscFlags2;
};
#pragma pack(pop)
//--------------------------------------------------------------------------------------
namespace
{
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
enum DDS_MISC_FLAGS2
{
DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
};
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
struct DDS_HEADER_DXT10
{
DXGI_FORMAT dxgiFormat;
uint32_t resourceDimension;
uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG
uint32_t arraySize;
uint32_t miscFlags2;
};
#pragma pack(pop)
static_assert(sizeof(DDS_PIXELFORMAT) == 32, "DDS pixel format size mismatch");
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");
//--------------------------------------------------------------------------------------
#ifdef _WIN32
struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } };
@@ -214,7 +223,7 @@ namespace
return E_FAIL;
}
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
if (ddsDataSize < DDS_MIN_HEADER_SIZE)
{
return E_FAIL;
}
@@ -241,7 +250,7 @@ namespace
(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;
}
@@ -251,8 +260,7 @@ namespace
// 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;
@@ -302,7 +310,7 @@ namespace
}
// 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;
}
@@ -345,7 +353,7 @@ namespace
return E_FAIL;
// Need at least enough data to fill the header and magic number to be a valid DDS
if (fileLen < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
if (fileLen < DDS_MIN_HEADER_SIZE)
return E_FAIL;
ddsData.reset(new (std::nothrow) uint8_t[size_t(fileLen)]);
@@ -395,7 +403,7 @@ namespace
(MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC))
{
// Must be long enough for both headers and magic value
if (len < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10)))
if (len < DDS_DX10_HEADER_SIZE)
{
ddsData.reset();
return E_FAIL;
@@ -406,7 +414,7 @@ namespace
// 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 = len - offset;

View File

@@ -20,6 +20,7 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <memory>
#include <new>
@@ -56,68 +57,73 @@ using Microsoft::WRL::ComPtr;
// DDS file structure definitions
//
// See DDS.h in the 'Texconv' sample and the 'DirectXTex' library
//--------------------------------------------------------------------------------------
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_BUMPLUMINANCE 0x00040000 // DDPF_BUMPLUMINANCE
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
#pragma pack(pop)
//--------------------------------------------------------------------------------------
namespace
{
#pragma pack(push,1)
constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
#define DDS_BUMPLUMINANCE 0x00040000 // DDPF_BUMPLUMINANCE
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
struct DDS_HEADER
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
};
#pragma pack(pop)
static_assert(sizeof(DDS_PIXELFORMAT) == 32, "DDS pixel format size mismatch");
static_assert(sizeof(DDS_HEADER) == 124, "DDS Header size mismatch");
constexpr size_t DDS_DX9_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER);
//--------------------------------------------------------------------------------------
struct handle_closer { void operator()(HANDLE h) noexcept { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>;
@@ -144,7 +150,7 @@ namespace
return E_FAIL;
}
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
if (ddsDataSize < DDS_DX9_HEADER_SIZE)
{
return E_FAIL;
}
@@ -175,9 +181,8 @@ namespace
// setup the pointers in the process request
*header = hdr;
auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER);
*bitData = ddsData + offset;
*bitSize = ddsDataSize - offset;
*bitData = ddsData + DDS_DX9_HEADER_SIZE;
*bitSize = ddsDataSize - DDS_DX9_HEADER_SIZE;
return S_OK;
}
@@ -234,7 +239,7 @@ namespace
}
// 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_DX9_HEADER_SIZE)
{
return E_FAIL;
}
@@ -294,9 +299,8 @@ namespace
// setup the pointers in the process request
*header = hdr;
auto offset = sizeof(uint32_t) + sizeof(DDS_HEADER);
*bitData = ddsData.get() + offset;
*bitSize = fileInfo.EndOfFile.LowPart - offset;
*bitData = ddsData.get() + DDS_DX9_HEADER_SIZE;
*bitSize = fileInfo.EndOfFile.LowPart - DDS_DX9_HEADER_SIZE;
return S_OK;
}