Merge Xbox xtexconv tool into mainline via CMake (#441)

* Merge Xbox xtexconv tool into mainline via CMake

* Update CMake for Xbox builds

* Keep using _USE_GXDK

* Code review feedback
This commit is contained in:
Chuck Walbourn
2024-01-22 07:58:00 -08:00
committed by GitHub
parent fae11ce578
commit 9aa857e160
5 changed files with 198 additions and 37 deletions

View File

@@ -61,7 +61,6 @@
#endif
#include "DirectXTex.h"
#include "DirectXPackedVector.h"
#ifdef USE_OPENEXR
@@ -77,6 +76,11 @@
#include "DirectXTexPNG.h"
#endif
#ifdef USE_XBOX_EXTS
// See <https://github.com/microsoft/DirectXTex/wiki/DirectXTexXbox> for details
#include "DirectXTexXbox.h"
#endif
using namespace DirectX;
using namespace DirectX::PackedVector;
using Microsoft::WRL::ComPtr;
@@ -144,6 +148,10 @@ namespace
OPT_PAPER_WHITE_NITS,
OPT_BCNONMULT4FIX,
OPT_SWIZZLE,
#ifdef USE_XBOX_EXTS
OPT_USE_XBOX,
OPT_XGMODE,
#endif
OPT_MAX
};
@@ -241,6 +249,10 @@ namespace
{ L"nits", OPT_PAPER_WHITE_NITS },
{ L"fixbc4x4", OPT_BCNONMULT4FIX },
{ L"swizzle", OPT_SWIZZLE },
#ifdef USE_XBOX_EXTS
{ L"xbox", OPT_USE_XBOX },
{ L"xgmode", OPT_XGMODE },
#endif
{ nullptr, 0 }
};
@@ -333,6 +345,14 @@ namespace
// D3D11on12 format
{ L"A4B4G4R4_UNORM", DXGI_FORMAT(191) },
#ifdef USE_XBOX_EXTS
// Xbox One extended formats
{ L"R10G10B10_7E3_A2_FLOAT", DXGI_FORMAT(116) },
{ L"R10G10B10_6E4_A2_FLOAT", DXGI_FORMAT(117) },
{ L"R10G10B10_SNORM_A2_UNORM", DXGI_FORMAT(189) },
{ L"R4G4_UNORM", DXGI_FORMAT(190) },
#endif
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
@@ -412,6 +432,13 @@ namespace
{ L"V208", DXGI_FORMAT(131) },
{ L"V408", DXGI_FORMAT(132) },
#ifdef USE_XBOX_EXTS
// Xbox One extended formats
{ L"D16_UNORM_S8_UINT", DXGI_FORMAT(118) },
{ L"R16_UNORM_X8_TYPELESS", DXGI_FORMAT(119) },
{ L"X16_TYPELESS_G8_UINT", DXGI_FORMAT(120) },
#endif
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
@@ -773,7 +800,7 @@ namespace
wprintf(L"*UNKNOWN*");
}
void PrintInfo(const TexMetadata& info)
void PrintInfo(const TexMetadata& info, bool isXbox)
{
wprintf(L" (%zux%zu", info.width, info.height);
@@ -829,6 +856,11 @@ namespace
break;
}
if (isXbox)
{
wprintf(L" Xbox");
}
wprintf(L")");
}
@@ -886,7 +918,13 @@ namespace
}
else
{
#if defined(USE_XBOX_EXTS) && defined(_USE_SCARLETT)
wprintf(L"Microsoft (R) DirectX Texture Converter for Microsoft GDKX for Xbox Series X|S [Version %ls]\n", version);
#elif defined(USE_XBOX_EXTS)
wprintf(L"Microsoft (R) DirectX Texture Converter for Microsoft GDKX for Xbox One [Version %ls]\n", version);
#else
wprintf(L"Microsoft (R) DirectX Texture Converter [DirectXTex] Version %ls\n", version);
#endif
wprintf(L"Copyright (C) Microsoft Corp.\n");
#ifdef _DEBUG
wprintf(L"*** Debug build ***\n");
@@ -981,6 +1019,10 @@ namespace
L" (DDS output only)\n"
L" -dx10 Force use of 'DX10' extended header\n"
L" -dx9 Force use of legacy DX9 header\n"
#ifdef USE_XBOX_EXTS
L" -xbox Tile/swizzle and use 'XBOX' variant of DDS\n"
L" -xgmode <mode> Tile/swizzle using provided memory layout mode\n"
#endif
L"\n"
L" (TGA input only)\n"
L" -tgazeroalpha Allow all zero alpha channel files to be loaded 'as is'\n"
@@ -1559,6 +1601,9 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
case OPT_PAPER_WHITE_NITS:
case OPT_PRESERVE_ALPHA_COVERAGE:
case OPT_SWIZZLE:
#ifdef USE_XBOX_EXTS
case OPT_XGMODE:
#endif
// These support either "-arg:value" or "-arg value"
if (!*pValue)
{
@@ -2040,6 +2085,40 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
return 1;
}
break;
#ifdef USE_XBOX_EXTS
case OPT_XGMODE:
{
#ifdef _USE_SCARLETT
static const SValue<uint32_t> s_pXGModes[] =
{
{ L"xboxseriess", XG_HARDWARE_VERSION_XBOX_SCARLETT_LOCKHART },
{ L"xboxseriesx", XG_HARDWARE_VERSION_XBOX_SCARLETT_ANACONDA },
{ nullptr, 0 },
};
#else
static const SValue<uint32_t> s_pXGModes[] =
{
{ L"xboxone", XG_HARDWARE_VERSION_XBOX_ONE },
{ L"xboxonex", XG_HARDWARE_VERSION_XBOX_ONE_X },
{ L"scorpio", XG_HARDWARE_VERSION_SCORPIO },
{ nullptr, 0 },
};
#endif
const uint32_t mode = LookupByName(pValue, s_pXGModes);
if (!mode)
{
printf("Invalid value specified with -xgmode (%ls)\n", pValue);
wprintf(L"\n <mode>: ");
PrintList(14, s_pXGModes);
return 1;
};
XGSetHardwareVersion(static_cast<XG_HARDWARE_VERSION>(mode));
break;
}
#endif // USE_XBOX_EXTS
}
}
else if (wcspbrk(pArg, L"?*") != nullptr)
@@ -2124,19 +2203,46 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
std::filesystem::path curpath(pConv->szSrc);
auto const ext = curpath.extension();
#ifndef USE_XBOX_EXTS
constexpr
#endif
bool isXbox = false;
if (_wcsicmp(ext.c_str(), L".dds") == 0 || _wcsicmp(ext.c_str(), L".ddx") == 0)
{
DDS_FLAGS ddsFlags = DDS_FLAGS_ALLOW_LARGE_FILES;
if (dwOptions & (uint64_t(1) << OPT_DDS_DWORD_ALIGN))
ddsFlags |= DDS_FLAGS_LEGACY_DWORD;
if (dwOptions & (uint64_t(1) << OPT_EXPAND_LUMINANCE))
ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE;
if (dwOptions & (uint64_t(1) << OPT_DDS_BAD_DXTN_TAILS))
ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS;
if (dwOptions & (uint64_t(1) << OPT_DDS_PERMISSIVE))
ddsFlags |= DDS_FLAGS_PERMISSIVE;
#ifdef USE_XBOX_EXTS
hr = Xbox::GetMetadataFromDDSFile(curpath.c_str(), info, isXbox);
if (FAILED(hr))
{
wprintf(L" FAILED (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
retVal = 1;
continue;
}
hr = LoadFromDDSFile(curpath.c_str(), ddsFlags, &info, *image);
if (isXbox)
{
Xbox::XboxImage xbox;
hr = Xbox::LoadFromDDSFile(curpath.c_str(), &info, xbox);
if (SUCCEEDED(hr))
{
hr = Xbox::Detile(xbox, *image);
}
}
else
#endif // USE_XBOX_EXTS
{
DDS_FLAGS ddsFlags = DDS_FLAGS_ALLOW_LARGE_FILES;
if (dwOptions & (uint64_t(1) << OPT_DDS_DWORD_ALIGN))
ddsFlags |= DDS_FLAGS_LEGACY_DWORD;
if (dwOptions & (uint64_t(1) << OPT_EXPAND_LUMINANCE))
ddsFlags |= DDS_FLAGS_EXPAND_LUMINANCE;
if (dwOptions & (uint64_t(1) << OPT_DDS_BAD_DXTN_TAILS))
ddsFlags |= DDS_FLAGS_BAD_DXTN_TAILS;
if (dwOptions & (uint64_t(1) << OPT_DDS_PERMISSIVE))
ddsFlags |= DDS_FLAGS_PERMISSIVE;
hr = LoadFromDDSFile(curpath.c_str(), ddsFlags, &info, *image);
}
if (FAILED(hr))
{
wprintf(L" FAILED (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
@@ -2291,7 +2397,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
}
PrintInfo(info);
PrintInfo(info, isXbox);
size_t tMips = (!mipLevels && info.mipLevels > 1) ? info.mipLevels : mipLevels;
@@ -3741,7 +3847,12 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
assert(img);
const size_t nimg = image->GetImageCount();
PrintInfo(info);
#ifdef USE_XBOX_EXTS
const bool isXboxOut = ((FileType == CODEC_DDS) && (dwOptions & (uint64_t(1) << OPT_USE_XBOX))) != 0;
#else
constexpr bool isXboxOut = false;
#endif
PrintInfo(info, isXboxOut);
wprintf(L"\n");
// Figure out dest filename
@@ -3806,6 +3917,19 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
switch (FileType)
{
case CODEC_DDS:
#ifdef USE_XBOX_EXTS
if (isXboxOut)
{
Xbox::XboxImage xbox;
hr = Xbox::Tile(img, nimg, info, xbox);
if (SUCCEEDED(hr))
{
hr = Xbox::SaveToDDSFile(xbox, destName.c_str());
}
}
else
#endif // USE_XBOX_EXTS
{
DDS_FLAGS ddsFlags = DDS_FLAGS_NONE;
if (dwOptions & (uint64_t(1) << OPT_USE_DX10))
@@ -3823,8 +3947,8 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
hr = SaveToDDSFile(img, nimg, info, ddsFlags, destName.c_str());
break;
}
break;
case CODEC_TGA:
hr = SaveToTGAFile(img[0], TGA_FLAGS_NONE, destName.c_str(), (dwOptions & (uint64_t(1) << OPT_TGA20)) ? &info : nullptr);