Xbox auxiliary EncodeDDSHeader helper exposed as public function (#497)
Some checks failed
MSBuild / build (Debug, ARM64, 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-2019) (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-2019) (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-2019) (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-2019) (push) Has been cancelled
CMake (Windows) / build (amd64_x86, x86-Release-Clang, windows-2022) (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 (Debug, x86, 2019) (push) Has been cancelled
MSBuild / build (Debug, x86, 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-2019) (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-2019) (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-2019) (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-2019) (push) Has been cancelled
CTest (Windows) / build (amd64_x86, x86-Release-Clang, windows-2022) (push) Has been cancelled

This commit is contained in:
Chuck Walbourn 2024-08-19 16:27:36 -07:00 committed by GitHub
parent 059ce81581
commit 1c47191318
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 311 additions and 268 deletions

View File

@ -69,12 +69,12 @@ namespace Xbox
XboxImage(const XboxImage&) = delete; XboxImage(const XboxImage&) = delete;
XboxImage& operator=(const XboxImage&) = delete; XboxImage& operator=(const XboxImage&) = delete;
HRESULT Initialize(_In_ const XG_TEXTURE1D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); HRESULT __cdecl Initialize(_In_ const XG_TEXTURE1D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0);
HRESULT Initialize(_In_ const XG_TEXTURE2D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); HRESULT __cdecl Initialize(_In_ const XG_TEXTURE2D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0);
HRESULT Initialize(_In_ const XG_TEXTURE3D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0); HRESULT __cdecl Initialize(_In_ const XG_TEXTURE3D_DESC& desc, _In_ const XG_RESOURCE_LAYOUT& layout, _In_ uint32_t miscFlags2 = 0);
HRESULT Initialize(_In_ const DirectX::TexMetadata& mdata, _In_ XboxTileMode tm, _In_ uint32_t size, _In_ uint32_t alignment); HRESULT __cdecl Initialize(_In_ const DirectX::TexMetadata& mdata, _In_ XboxTileMode tm, _In_ uint32_t size, _In_ uint32_t alignment);
void Release(); void __cdecl Release();
const DirectX::TexMetadata& GetMetadata() const { return metadata; } const DirectX::TexMetadata& GetMetadata() const { return metadata; }
XboxTileMode GetTileMode() const { return tilemode; } XboxTileMode GetTileMode() const { return tilemode; }
@ -94,65 +94,65 @@ namespace Xbox
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Image I/O // Image I/O
HRESULT GetMetadataFromDDSMemory( HRESULT __cdecl GetMetadataFromDDSMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox); _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox);
HRESULT GetMetadataFromDDSFile( HRESULT __cdecl GetMetadataFromDDSFile(
_In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox); _In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox);
HRESULT GetMetadataFromDDSMemoryEx( HRESULT __cdecl GetMetadataFromDDSMemoryEx(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox,
_Out_opt_ DirectX::DDSMetaData* ddPixelFormat); _Out_opt_ DirectX::DDSMetaData* ddPixelFormat);
HRESULT GetMetadataFromDDSFileEx( HRESULT __cdecl GetMetadataFromDDSFileEx(
_In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox, _In_z_ const wchar_t* szFile, _Out_ DirectX::TexMetadata& metadata, _Out_ bool& isXbox,
_Out_opt_ DirectX::DDSMetaData* ddPixelFormat); _Out_opt_ DirectX::DDSMetaData* ddPixelFormat);
HRESULT LoadFromDDSMemory( HRESULT __cdecl LoadFromDDSMemory(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image); _Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image);
HRESULT LoadFromDDSFile( HRESULT __cdecl LoadFromDDSFile(
_In_z_ const wchar_t* szFile, _In_z_ const wchar_t* szFile,
_Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image); _Out_opt_ DirectX::TexMetadata* metadata, _Out_ XboxImage& image);
HRESULT LoadFromDDSMemoryEx( HRESULT __cdecl LoadFromDDSMemoryEx(
_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
_Out_opt_ DirectX::TexMetadata* metadata, _Out_opt_ DirectX::TexMetadata* metadata,
_Out_opt_ DirectX::DDSMetaData* ddPixelFormat, _Out_opt_ DirectX::DDSMetaData* ddPixelFormat,
_Out_ XboxImage& image); _Out_ XboxImage& image);
HRESULT LoadFromDDSFileEx( HRESULT __cdecl LoadFromDDSFileEx(
_In_z_ const wchar_t* szFile, _In_z_ const wchar_t* szFile,
_Out_opt_ DirectX::TexMetadata* metadata, _Out_opt_ DirectX::TexMetadata* metadata,
_Out_opt_ DirectX::DDSMetaData* ddPixelFormat, _Out_opt_ DirectX::DDSMetaData* ddPixelFormat,
_Out_ XboxImage& image); _Out_ XboxImage& image);
HRESULT SaveToDDSMemory(_In_ const XboxImage& xbox, _Out_ DirectX::Blob& blob); HRESULT __cdecl SaveToDDSMemory(_In_ const XboxImage& xbox, _Out_ DirectX::Blob& blob);
HRESULT SaveToDDSFile(_In_ const XboxImage& xbox, _In_z_ const wchar_t* szFile); HRESULT __cdecl SaveToDDSFile(_In_ const XboxImage& xbox, _In_z_ const wchar_t* szFile);
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Xbox Texture Tiling / Detiling (requires XG DLL to be present at runtime) // Xbox Texture Tiling / Detiling (requires XG DLL to be present at runtime)
HRESULT Tile(_In_ const DirectX::Image& srcImage, _Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid); HRESULT __cdecl Tile(_In_ const DirectX::Image& srcImage, _Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid);
HRESULT Tile( HRESULT __cdecl Tile(
_In_ const DirectX::Image* srcImages, _In_ size_t nimages, _In_ const DirectX::TexMetadata& metadata, _In_ const DirectX::Image* srcImages, _In_ size_t nimages, _In_ const DirectX::TexMetadata& metadata,
_Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid); _Out_ XboxImage& xbox, _In_ XboxTileMode mode = c_XboxTileModeInvalid);
HRESULT Detile(_In_ const XboxImage& xbox, _Out_ DirectX::ScratchImage& image); HRESULT __cdecl Detile(_In_ const XboxImage& xbox, _Out_ DirectX::ScratchImage& image);
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Direct3D 11.X functions // Direct3D 11.X functions
#if defined(_XBOX_ONE) && defined(_TITLE) && defined(__d3d11_x_h__) #if defined(_XBOX_ONE) && defined(_TITLE) && defined(__d3d11_x_h__)
HRESULT CreateTexture( HRESULT __cdecl CreateTexture(
_In_ ID3D11DeviceX* d3dDevice, _In_ ID3D11DeviceX* d3dDevice,
_In_ const XboxImage& xbox, _Outptr_opt_ ID3D11Resource** ppResource, _Outptr_ void** grfxMemory); _In_ const XboxImage& xbox, _Outptr_opt_ ID3D11Resource** ppResource, _Outptr_ void** grfxMemory);
HRESULT CreateShaderResourceView( HRESULT __cdecl CreateShaderResourceView(
_In_ ID3D11DeviceX* d3dDevice, _In_ ID3D11DeviceX* d3dDevice,
_In_ const XboxImage& xbox, _Outptr_opt_ ID3D11ShaderResourceView** ppSRV, _Outptr_ void** grfxMemory); _In_ const XboxImage& xbox, _Outptr_opt_ ID3D11ShaderResourceView** ppSRV, _Outptr_ void** grfxMemory);
void FreeTextureMemory(_In_ ID3D11DeviceX* d3dDevice, _In_opt_ void* grfxMemory); void __cdecl FreeTextureMemory(_In_ ID3D11DeviceX* d3dDevice, _In_opt_ void* grfxMemory);
#endif #endif
@ -161,12 +161,18 @@ namespace Xbox
#if ((defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)) && (defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__)) #if ((defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)) && (defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__))
HRESULT CreateTexture( HRESULT __cdecl CreateTexture(
_In_ ID3D12Device* d3dDevice, _In_ ID3D12Device* d3dDevice,
_In_ const XboxImage& xbox, _Outptr_opt_ ID3D12Resource** ppResource, _Outptr_ void** grfxMemory); _In_ const XboxImage& xbox, _Outptr_opt_ ID3D12Resource** ppResource, _Outptr_ void** grfxMemory);
void FreeTextureMemory(_In_ ID3D12Device* d3dDevice, _In_opt_ void* grfxMemory); void __cdecl FreeTextureMemory(_In_ ID3D12Device* d3dDevice, _In_opt_ void* grfxMemory);
#endif #endif
//---------------------------------------------------------------------------------
// DDS helper functions
HRESULT __cdecl EncodeDDSHeader(
const XboxImage& xbox,
_Out_writes_bytes_(maxsize) void* pDestination, _In_ size_t maxsize) noexcept;
} // namespace } // namespace

View File

@ -23,34 +23,6 @@ using namespace Xbox;
namespace namespace
{ {
const DDS_PIXELFORMAT DDSPF_XBOX =
{ sizeof(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)
constexpr uint32_t XBOX_TILEMODE_SCARLETT = 0x1000000;
static_assert(sizeof(DDS_HEADER_XBOX) == 36, "DDS XBOX Header size mismatch");
static_assert(sizeof(DDS_HEADER_XBOX) >= sizeof(DDS_HEADER_DXT10), "DDS XBOX Header should be larger than DX10 header");
constexpr size_t XBOX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_XBOX);
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Decodes DDS header using XBOX extended header (variant of DX10 header) // Decodes DDS header using XBOX extended header (variant of DX10 header)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -86,7 +58,7 @@ namespace
*ddPixelFormat = {}; *ddPixelFormat = {};
} }
if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (size < DDS_MIN_HEADER_SIZE)
{ {
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA); return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
} }
@ -120,13 +92,13 @@ namespace
} }
// Buffer must be big enough for both headers and magic value // Buffer must be big enough for both headers and magic value
if (size < XBOX_HEADER_SIZE) if (size < DDS_XBOX_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
auto xboxext = reinterpret_cast<const DDS_HEADER_XBOX*>( auto xboxext = reinterpret_cast<const DDS_HEADER_XBOX*>(
reinterpret_cast<const uint8_t*>(pSource) + sizeof(uint32_t) + sizeof(DDS_HEADER)); reinterpret_cast<const uint8_t*>(pSource) + DDS_MIN_HEADER_SIZE);
metadata.arraySize = xboxext->arraySize; metadata.arraySize = xboxext->arraySize;
if (metadata.arraySize == 0) if (metadata.arraySize == 0)
@ -244,20 +216,26 @@ namespace
return S_OK; return S_OK;
} }
}
//=====================================================================================
// Entry-points
//=====================================================================================
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Encodes DDS file header (magic value, header, XBOX extended header) // Encodes DDS file header (magic value, header, XBOX extended header)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
HRESULT EncodeDDSHeader( _Use_decl_annotations_
HRESULT Xbox::EncodeDDSHeader(
const XboxImage& xbox, const XboxImage& xbox,
_Out_writes_(maxsize) void* pDestination, void* pDestination,
size_t maxsize) size_t maxsize) noexcept
{ {
if (!pDestination) if (!pDestination)
return E_POINTER; return E_INVALIDARG;
if (maxsize < XBOX_HEADER_SIZE) if (maxsize < DDS_XBOX_HEADER_SIZE)
return E_NOT_SUFFICIENT_BUFFER; return E_NOT_SUFFICIENT_BUFFER;
*reinterpret_cast<uint32_t*>(pDestination) = DDS_MAGIC; *reinterpret_cast<uint32_t*>(pDestination) = DDS_MAGIC;
@ -397,13 +375,8 @@ namespace
return S_OK; return S_OK;
} }
}
//=====================================================================================
// Entry-points
//=====================================================================================
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Obtain metadata from DDS file in memory/on disk // Obtain metadata from DDS file in memory/on disk
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -491,16 +464,16 @@ HRESULT Xbox::GetMetadataFromDDSFileEx(
} }
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (fileInfo.EndOfFile.LowPart < DDS_MIN_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
// Read the header in (including extended header if present) // Read the header in (including extended header if present)
uint8_t header[XBOX_HEADER_SIZE] = {}; uint8_t header[DDS_XBOX_HEADER_SIZE] = {};
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, XBOX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, DDS_XBOX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -566,13 +539,13 @@ HRESULT Xbox::LoadFromDDSMemoryEx(
return E_FAIL; return E_FAIL;
} }
if (size <= XBOX_HEADER_SIZE) if (size <= DDS_XBOX_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
// Copy tiled data // Copy tiled data
const size_t remaining = size - XBOX_HEADER_SIZE; const size_t remaining = size - DDS_XBOX_HEADER_SIZE;
if (remaining < dataSize) if (remaining < dataSize)
{ {
@ -585,7 +558,7 @@ HRESULT Xbox::LoadFromDDSMemoryEx(
assert(xbox.GetPointer() != nullptr); assert(xbox.GetPointer() != nullptr);
memcpy(xbox.GetPointer(), reinterpret_cast<const uint8_t*>(pSource) + XBOX_HEADER_SIZE, dataSize); memcpy(xbox.GetPointer(), reinterpret_cast<const uint8_t*>(pSource) + DDS_XBOX_HEADER_SIZE, dataSize);
if (metadata) if (metadata)
memcpy(metadata, &mdata, sizeof(TexMetadata)); memcpy(metadata, &mdata, sizeof(TexMetadata));
@ -644,16 +617,16 @@ HRESULT Xbox::LoadFromDDSFileEx(
} }
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (fileInfo.EndOfFile.LowPart < DDS_MIN_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
// Read the header in (including extended header if present) // Read the header in (including extended header if present)
uint8_t header[XBOX_HEADER_SIZE] = {}; uint8_t header[DDS_XBOX_HEADER_SIZE] = {};
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, XBOX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, DDS_XBOX_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
@ -677,7 +650,7 @@ HRESULT Xbox::LoadFromDDSFileEx(
} }
// Read tiled data // Read tiled data
const DWORD remaining = fileInfo.EndOfFile.LowPart - XBOX_HEADER_SIZE; const DWORD remaining = fileInfo.EndOfFile.LowPart - DDS_XBOX_HEADER_SIZE;
if (remaining == 0) if (remaining == 0)
return E_FAIL; return E_FAIL;
@ -716,7 +689,7 @@ HRESULT Xbox::SaveToDDSMemory(const XboxImage& xbox, Blob& blob)
blob.Release(); blob.Release();
HRESULT hr = blob.Initialize(XBOX_HEADER_SIZE + xbox.GetSize()); HRESULT hr = blob.Initialize(DDS_XBOX_HEADER_SIZE + xbox.GetSize());
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -724,7 +697,7 @@ HRESULT Xbox::SaveToDDSMemory(const XboxImage& xbox, Blob& blob)
auto pDestination = reinterpret_cast<uint8_t*>(blob.GetBufferPointer()); auto pDestination = reinterpret_cast<uint8_t*>(blob.GetBufferPointer());
assert(pDestination); assert(pDestination);
hr = EncodeDDSHeader(xbox, pDestination, XBOX_HEADER_SIZE); hr = EncodeDDSHeader(xbox, pDestination, DDS_XBOX_HEADER_SIZE);
if (FAILED(hr)) if (FAILED(hr))
{ {
blob.Release(); blob.Release();
@ -732,8 +705,8 @@ HRESULT Xbox::SaveToDDSMemory(const XboxImage& xbox, Blob& blob)
} }
// Copy tiled data // Copy tiled data
const size_t remaining = blob.GetBufferSize() - XBOX_HEADER_SIZE; const size_t remaining = blob.GetBufferSize() - DDS_XBOX_HEADER_SIZE;
pDestination += XBOX_HEADER_SIZE; pDestination += DDS_XBOX_HEADER_SIZE;
if (!remaining) if (!remaining)
{ {
@ -763,8 +736,8 @@ HRESULT Xbox::SaveToDDSFile(const XboxImage& xbox, const wchar_t* szFile)
return E_INVALIDARG; return E_INVALIDARG;
// Create DDS Header // Create DDS Header
uint8_t header[XBOX_HEADER_SIZE] = {}; uint8_t header[DDS_XBOX_HEADER_SIZE] = {};
HRESULT hr = EncodeDDSHeader(xbox, header, XBOX_HEADER_SIZE); HRESULT hr = EncodeDDSHeader(xbox, header, DDS_XBOX_HEADER_SIZE);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -782,12 +755,12 @@ HRESULT Xbox::SaveToDDSFile(const XboxImage& xbox, const wchar_t* szFile)
} }
DWORD bytesWritten; DWORD bytesWritten;
if (!WriteFile(hFile.get(), header, static_cast<DWORD>(XBOX_HEADER_SIZE), &bytesWritten, nullptr)) if (!WriteFile(hFile.get(), header, static_cast<DWORD>(DDS_XBOX_HEADER_SIZE), &bytesWritten, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
if (bytesWritten != XBOX_HEADER_SIZE) if (bytesWritten != DDS_XBOX_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }

View File

@ -591,7 +591,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
endforeach() endforeach()
endif() endif()
set(WarningsEXE "/wd4061" "/wd4062" "/wd4365" "/wd4514" "/wd4625" "/wd4626" "/wd4627" "/wd4668" "/wd4710" "/wd4711" "/wd4751" "/wd4820" "/wd5026" "/wd5027" "/wd5039" "/wd5045" "/wd5219") set(WarningsEXE "/wd4061" "/wd4062" "/wd4365" "/wd4514" "/wd4571" "/wd4625" "/wd4626" "/wd4627" "/wd4668" "/wd4710" "/wd4711" "/wd4751" "/wd4774" "/wd4820" "/wd5026" "/wd5027" "/wd5039" "/wd5045" "/wd5219")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.34) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.34)
list(APPEND WarningsEXE "/wd5262" "/wd5264") list(APPEND WarningsEXE "/wd5262" "/wd5264")
endif() endif()

View File

@ -48,8 +48,9 @@ namespace DirectX
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA #define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8 #define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8
#define DDS_PAL8A 0x00000021 // DDPF_PALETTEINDEXED8 | DDPF_ALPHAPIXELS #define DDS_PAL8A 0x00000021 // DDPF_PALETTEINDEXED8 | DDPF_ALPHAPIXELS
#define DDS_BUMPLUMINANCE 0x00040000 // DDPF_BUMPLUMINANCE
#define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV #define DDS_BUMPDUDV 0x00080000 // DDPF_BUMPDUDV
// DDS_BUMPLUMINANCE 0x00040000 #define DDS_BUMPDUDVA 0x00080001 // DDPF_BUMPDUDV | DDPF_ALPHAPIXELS
#ifndef MAKEFOURCC #ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
@ -187,10 +188,13 @@ namespace DirectX
DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A2B10G10R10 = DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A2B10G10R10 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }; { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 };
// We do not support the following legacy Direct3D 9 formats: // The following legacy Direct3D 9 formats use 'mixed' signed & unsigned channels so requires special handling
// DDSPF_A2W10V10U10 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 }; DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A2W10V10U10 =
// DDSPF_L6V5U5 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 16, 0x001f, 0x03e0, 0xfc00, 0 }; { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDVA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 };
// DDSPF_X8L8V8U8 = { sizeof(DDS_PIXELFORMAT), DDS_BUMPLUMINANCE, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0 }; 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) // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_DX10 = 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) == 124, "DDS Header size mismatch");
static_assert(sizeof(DDS_HEADER_DXT10) == 20, "DDS DX10 Extended 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 } // namespace

View File

@ -22,8 +22,6 @@ static_assert(static_cast<int>(TEX_DIMENSION_TEXTURE3D) == static_cast<int>(DDS_
namespace namespace
{ {
constexpr size_t MAX_HEADER_SIZE = sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10);
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Legacy format mapping table (used for DDS files without 'DX10' extended header) // Legacy format mapping table (used for DDS files without 'DX10' extended header)
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@ -326,7 +324,7 @@ namespace
*ddPixelFormat = {}; *ddPixelFormat = {};
} }
if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (size < DDS_MIN_HEADER_SIZE)
{ {
return HRESULT_E_INVALID_DATA; return HRESULT_E_INVALID_DATA;
} }
@ -386,12 +384,12 @@ namespace
} }
// Buffer must be big enough for both headers and magic value // Buffer must be big enough for both headers and magic value
if (size < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10))) if (size < DDS_DX10_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
auto d3d10ext = reinterpret_cast<const DDS_HEADER_DXT10*>(static_cast<const uint8_t*>(pSource) + sizeof(uint32_t) + sizeof(DDS_HEADER)); auto d3d10ext = reinterpret_cast<const DDS_HEADER_DXT10*>(static_cast<const uint8_t*>(pSource) + DDS_MIN_HEADER_SIZE);
convFlags |= CONV_FLAGS_DX10; convFlags |= CONV_FLAGS_DX10;
metadata.arraySize = d3d10ext->arraySize; metadata.arraySize = d3d10ext->arraySize;
@ -826,7 +824,7 @@ HRESULT DirectX::EncodeDDSHeader(
} }
} }
required = sizeof(uint32_t) + sizeof(DDS_HEADER); required = DDS_MIN_HEADER_SIZE;
if (ddpf.size == 0) if (ddpf.size == 0)
{ {
@ -1776,24 +1774,24 @@ HRESULT DirectX::GetMetadataFromDDSFileEx(
#endif #endif
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (len < DDS_MIN_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
// Read the header in (including extended header if present) // Read the header in (including extended header if present)
uint8_t header[MAX_HEADER_SIZE] = {}; uint8_t header[DDS_DX10_HEADER_SIZE] = {};
#ifdef _WIN32 #ifdef _WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, DDS_DX10_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto const headerLen = static_cast<size_t>(bytesRead); auto const headerLen = static_cast<size_t>(bytesRead);
#else #else
auto const headerLen = std::min<size_t>(len, MAX_HEADER_SIZE); auto const headerLen = std::min<size_t>(len, DDS_DX10_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen); inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile) if (!inFile)
@ -1839,7 +1837,7 @@ HRESULT DirectX::LoadFromDDSMemoryEx(
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
size_t offset = sizeof(uint32_t) + sizeof(DDS_HEADER); size_t offset = DDS_MIN_HEADER_SIZE;
if (convFlags & CONV_FLAGS_DX10) if (convFlags & CONV_FLAGS_DX10)
offset += sizeof(DDS_HEADER_DXT10); offset += sizeof(DDS_HEADER_DXT10);
@ -1960,24 +1958,24 @@ HRESULT DirectX::LoadFromDDSFileEx(
#endif #endif
// Need at least enough data to fill the standard header and magic number to be a valid DDS // Need at least enough data to fill the standard header and magic number to be a valid DDS
if (len < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (len < DDS_MIN_HEADER_SIZE)
{ {
return E_FAIL; return E_FAIL;
} }
// Read the header in (including extended header if present) // Read the header in (including extended header if present)
uint8_t header[MAX_HEADER_SIZE] = {}; uint8_t header[DDS_DX10_HEADER_SIZE] = {};
#ifdef _WIN32 #ifdef _WIN32
DWORD bytesRead = 0; DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), header, MAX_HEADER_SIZE, &bytesRead, nullptr)) if (!ReadFile(hFile.get(), header, DDS_DX10_HEADER_SIZE, &bytesRead, nullptr))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
auto const headerLen = static_cast<size_t>(bytesRead); auto const headerLen = static_cast<size_t>(bytesRead);
#else #else
auto const headerLen = std::min<size_t>(len, MAX_HEADER_SIZE); auto const headerLen = std::min<size_t>(len, DDS_DX10_HEADER_SIZE);
inFile.read(reinterpret_cast<char*>(header), headerLen); inFile.read(reinterpret_cast<char*>(header), headerLen);
if (!inFile) if (!inFile)
@ -1990,24 +1988,24 @@ HRESULT DirectX::LoadFromDDSFileEx(
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
size_t offset = MAX_HEADER_SIZE; size_t offset = DDS_DX10_HEADER_SIZE;
if (!(convFlags & CONV_FLAGS_DX10)) if (!(convFlags & CONV_FLAGS_DX10))
{ {
#ifdef _WIN32 #ifdef _WIN32
// Must reset file position since we read more than the standard header above // Must reset file position since we read more than the standard header above
const LARGE_INTEGER filePos = { { sizeof(uint32_t) + sizeof(DDS_HEADER), 0 } }; const LARGE_INTEGER filePos = { { DDS_MIN_HEADER_SIZE, 0 } };
if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN)) if (!SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
{ {
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
#else #else
inFile.seekg(sizeof(uint32_t) + sizeof(DDS_HEADER), std::ios::beg); inFile.seekg(DDS_MIN_HEADER_SIZE, std::ios::beg);
if (!inFile) if (!inFile)
return E_FAIL; return E_FAIL;
#endif #endif
offset = sizeof(uint32_t) + sizeof(DDS_HEADER); offset = DDS_MIN_HEADER_SIZE;
} }
std::unique_ptr<uint32_t[]> pal8; std::unique_ptr<uint32_t[]> pal8;
@ -2393,9 +2391,9 @@ HRESULT DirectX::SaveToDDSFile(
return E_INVALIDARG; return E_INVALIDARG;
// Create DDS Header // Create DDS Header
uint8_t header[MAX_HEADER_SIZE]; uint8_t header[DDS_DX10_HEADER_SIZE];
size_t required; size_t required;
HRESULT hr = EncodeDDSHeader(metadata, flags, header, MAX_HEADER_SIZE, required); HRESULT hr = EncodeDDSHeader(metadata, flags, header, DDS_DX10_HEADER_SIZE, required);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;

View File

@ -14,7 +14,7 @@
#pragma warning(disable : 4005) #pragma warning(disable : 4005)
#endif #endif
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOMINMAX #define NOMINMAX 1
#define NODRAWTEXT #define NODRAWTEXT
#define NOMCX #define NOMCX
#define NOSERVICE #define NOSERVICE
@ -25,6 +25,7 @@
#include <Windows.h> #include <Windows.h>
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>

View File

@ -85,18 +85,40 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|IntelLLVM")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
list(APPEND COMPILER_SWITCHES /Zc:__cplusplus /Zc:inline /fp:fast /Qdiag-disable:161) list(APPEND COMPILER_SWITCHES /Zc:__cplusplus /Zc:inline /fp:fast /Qdiag-disable:161)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
list(APPEND COMPILER_SWITCHES /sdl /permissive- /JMC- /Zc:__cplusplus /Zc:inline /fp:fast) list(APPEND COMPILER_SWITCHES /sdl /Zc:inline /fp:fast)
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
message(STATUS "Building using Whole Program Optimization") message(STATUS "Building using Whole Program Optimization")
list(APPEND COMPILER_SWITCHES $<$<NOT:$<CONFIG:Debug>>:/Gy /Gw>) list(APPEND COMPILER_SWITCHES $<$<NOT:$<CONFIG:Debug>>:/Gy /Gw>)
endif() endif()
if(OpenMP_CXX_FOUND) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.10)
list(APPEND COMPILER_SWITCHES /permissive-)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.11)
AND (OpenMP_CXX_FOUND
OR (XBOX_CONSOLE_TARGET STREQUAL "durango")))
# OpenMP in MSVC is not compatible with /permissive- unless you disable two-phase lookup # OpenMP in MSVC is not compatible with /permissive- unless you disable two-phase lookup
list(APPEND COMPILER_SWITCHES /Zc:twoPhase-) list(APPEND COMPILER_SWITCHES /Zc:twoPhase-)
endif() endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.14)
list(APPEND COMPILER_SWITCHES /Zc:__cplusplus)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.15)
list(APPEND COMPILER_SWITCHES /JMC-)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20)
AND (XBOX_CONSOLE_TARGET STREQUAL "durango"))
list(APPEND COMPILER_SWITCHES /d2FH4-)
if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
list(APPEND LINKER_SWITCHES -d2:-FH4-)
endif()
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.24) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.24)
list(APPEND COMPILER_SWITCHES /ZH:SHA_256) list(APPEND COMPILER_SWITCHES /ZH:SHA_256)
endif() endif()
@ -114,6 +136,10 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
list(APPEND COMPILER_SWITCHES /Zc:lambda) list(APPEND COMPILER_SWITCHES /Zc:lambda)
endif() endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29)
list(APPEND COMPILER_SWITCHES /external:W4)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.31) if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.31)
AND (XBOX_CONSOLE_TARGET STREQUAL "durango")) AND (XBOX_CONSOLE_TARGET STREQUAL "durango"))
list(APPEND COMPILER_SWITCHES /Zc:static_assert-) list(APPEND COMPILER_SWITCHES /Zc:static_assert-)