Skip to content

Commit

Permalink
Update for latest version of DDS.h
Browse files Browse the repository at this point in the history
  • Loading branch information
walbourn committed Aug 16, 2024
1 parent 8350d44 commit 96847bd
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 58 deletions.
69 changes: 54 additions & 15 deletions Src/DDS.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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
13 changes: 6 additions & 7 deletions Src/LoaderHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
7 changes: 3 additions & 4 deletions Src/ScreenGrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint32_t*>(&fileHeader[0]) = DDS_MAGIC;

auto header = reinterpret_cast<DDS_HEADER*>(&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;
Expand Down Expand Up @@ -268,7 +267,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
memcpy(&header->ddspf, &DDSPF_DX10, sizeof(DDS_PIXELFORMAT));

headerSize += sizeof(DDS_HEADER_DXT10);
extHeader = reinterpret_cast<DDS_HEADER_DXT10*>(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER));
extHeader = reinterpret_cast<DDS_HEADER_DXT10*>(fileHeader + DDS_MIN_HEADER_SIZE);
extHeader->dxgiFormat = desc.Format;
extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
extHeader->arraySize = 1;
Expand Down
39 changes: 7 additions & 32 deletions Src/XboxDDSTextureLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t[]>& ddsData,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand All @@ -654,7 +629,7 @@ HRESULT Xbox::CreateDDSTextureFromMemory(
return E_FAIL;
}

auto header = reinterpret_cast<const DDS_HEADER*>( ddsData + sizeof( uint32_t ) );
auto header = reinterpret_cast<const DDS_HEADER*>(ddsData + sizeof(uint32_t));

// Verify header to validate DDS file
if (header->size != sizeof(DDS_HEADER) ||
Expand All @@ -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,
Expand Down

0 comments on commit 96847bd

Please sign in to comment.