Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DX12 Capture transition state handling for MSAA #532

Merged
merged 3 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 86 additions & 78 deletions DDSTextureLoader/DDSTextureLoader11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
#include <new>

Expand Down Expand Up @@ -53,82 +54,90 @@ using namespace DirectX;
//
// See DDS.h in the 'Texconv' sample and the 'DirectXTex' library
//--------------------------------------------------------------------------------------
#pragma pack(push,1)
namespace
{
#pragma pack(push,1)

constexpr uint32_t DDS_MAGIC = 0x20534444; // "DDS "
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_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;
};
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)
#pragma pack(pop)

//--------------------------------------------------------------------------------------
namespace
{
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>;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Loading
Loading