texconv: Added support for DXT5nm and RXGB DXT5 format variants (#362)
This commit is contained in:
Родитель
2395b804ff
Коммит
a2a4ffd33c
|
@ -221,6 +221,9 @@ namespace DirectX
|
||||||
DDS_FLAGS_FORCE_DX9_LEGACY = 0x40000,
|
DDS_FLAGS_FORCE_DX9_LEGACY = 0x40000,
|
||||||
// Force use of legacy header for DDS writer (will fail if unable to write as such)
|
// Force use of legacy header for DDS writer (will fail if unable to write as such)
|
||||||
|
|
||||||
|
DDS_FLAGS_FORCE_DXT5_RXGB = 0x80000,
|
||||||
|
// Force use of 'RXGB' instead of 'DXT5' for DDS write of BC3_UNORM data
|
||||||
|
|
||||||
DDS_FLAGS_ALLOW_LARGE_FILES = 0x1000000,
|
DDS_FLAGS_ALLOW_LARGE_FILES = 0x1000000,
|
||||||
// Enables the loader to read large dimension .dds files (i.e. greater than known hardware requirements)
|
// Enables the loader to read large dimension .dds files (i.e. greater than known hardware requirements)
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,6 +66,19 @@ namespace
|
||||||
{ DXGI_FORMAT_BC2_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT2 }, // D3DFMT_DXT2
|
{ DXGI_FORMAT_BC2_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT2 }, // D3DFMT_DXT2
|
||||||
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT4 }, // D3DFMT_DXT4
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_PMALPHA, DDSPF_DXT4 }, // D3DFMT_DXT4
|
||||||
|
|
||||||
|
// These DXT5 variants have various swizzled channels. They are returned 'as is' to the client as BC3.
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', '2', 'D', '5'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'G', 'B', 'R'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'x', 'B', 'G'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'B', 'x', 'G'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'R', 'B', 'G'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'G', 'x', 'B'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'G', 'x', 'R'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G', 'X', 'R', 'B'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G', 'R', 'X', 'B'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'X', 'G', 'B'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC3_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'R', 'G', 'X'), 0, 0, 0, 0, 0 } },
|
||||||
|
|
||||||
{ DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, DDSPF_BC4_UNORM },
|
{ DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, DDSPF_BC4_UNORM },
|
||||||
{ DXGI_FORMAT_BC4_SNORM, CONV_FLAGS_NONE, DDSPF_BC4_SNORM },
|
{ DXGI_FORMAT_BC4_SNORM, CONV_FLAGS_NONE, DDSPF_BC4_SNORM },
|
||||||
{ DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, DDSPF_BC5_UNORM },
|
{ DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, DDSPF_BC5_UNORM },
|
||||||
|
@ -73,6 +86,7 @@ namespace
|
||||||
|
|
||||||
{ DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 } },
|
{ DXGI_FORMAT_BC4_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 } },
|
||||||
{ DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 } },
|
{ DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 } },
|
||||||
|
{ DXGI_FORMAT_BC5_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', '2', 'X', 'Y'), 0, 0, 0, 0, 0 } },
|
||||||
|
|
||||||
{ DXGI_FORMAT_BC6H_UF16, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'C', '6', 'H'), 0, 0, 0, 0, 0 } },
|
{ DXGI_FORMAT_BC6H_UF16, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'C', '6', 'H'), 0, 0, 0, 0, 0 } },
|
||||||
{ DXGI_FORMAT_BC7_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'C', '7', 'L'), 0, 0, 0, 0, 0 } },
|
{ DXGI_FORMAT_BC7_UNORM, CONV_FLAGS_NONE, { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'C', '7', 'L'), 0, 0, 0, 0, 0 } },
|
||||||
|
@ -614,7 +628,6 @@ HRESULT DirectX::EncodeDDSHeader(
|
||||||
case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy(&ddpf, &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_G8R8_G8B8_UNORM: memcpy(&ddpf, &DDSPF_G8R8_G8B8, sizeof(DDS_PIXELFORMAT)); break;
|
||||||
case DXGI_FORMAT_BC1_UNORM: memcpy(&ddpf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_BC1_UNORM: memcpy(&ddpf, &DDSPF_DXT1, sizeof(DDS_PIXELFORMAT)); break;
|
||||||
case DXGI_FORMAT_BC2_UNORM: memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_BC2_UNORM: memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT2) : (&DDSPF_DXT3), sizeof(DDS_PIXELFORMAT)); break;
|
||||||
case DXGI_FORMAT_BC3_UNORM: memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT)); break;
|
|
||||||
case DXGI_FORMAT_BC4_SNORM: memcpy(&ddpf, &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_BC4_SNORM: memcpy(&ddpf, &DDSPF_BC4_SNORM, sizeof(DDS_PIXELFORMAT)); break;
|
||||||
case DXGI_FORMAT_BC5_SNORM: memcpy(&ddpf, &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_BC5_SNORM: memcpy(&ddpf, &DDSPF_BC5_SNORM, sizeof(DDS_PIXELFORMAT)); break;
|
||||||
case DXGI_FORMAT_B5G6R5_UNORM: memcpy(&ddpf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break;
|
case DXGI_FORMAT_B5G6R5_UNORM: memcpy(&ddpf, &DDSPF_R5G6B5, sizeof(DDS_PIXELFORMAT)); break;
|
||||||
|
@ -627,6 +640,14 @@ HRESULT DirectX::EncodeDDSHeader(
|
||||||
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy(&ddpf, &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
|
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy(&ddpf, &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
|
||||||
case DXGI_FORMAT_YUY2: memcpy(&ddpf, &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
|
case DXGI_FORMAT_YUY2: memcpy(&ddpf, &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT)); break; // DXGI 1.2
|
||||||
|
|
||||||
|
case DXGI_FORMAT_BC3_UNORM:
|
||||||
|
memcpy(&ddpf, metadata.IsPMAlpha() ? (&DDSPF_DXT4) : (&DDSPF_DXT5), sizeof(DDS_PIXELFORMAT));
|
||||||
|
if (flags & DDS_FLAGS_FORCE_DXT5_RXGB)
|
||||||
|
{
|
||||||
|
ddpf.fourCC = MAKEFOURCC('R', 'X', 'G', 'B');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// Legacy D3DX formats using D3DFMT enum value as FourCC
|
// Legacy D3DX formats using D3DFMT enum value as FourCC
|
||||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||||
ddpf.size = sizeof(DDS_PIXELFORMAT); ddpf.flags = DDS_FOURCC; ddpf.fourCC = 116; // D3DFMT_A32B32G32R32F
|
ddpf.size = sizeof(DDS_PIXELFORMAT); ddpf.flags = DDS_FOURCC; ddpf.fourCC = 116; // D3DFMT_A32B32G32R32F
|
||||||
|
|
|
@ -147,6 +147,12 @@ namespace
|
||||||
ROTATE_P3D65_TO_709,
|
ROTATE_P3D65_TO_709,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FORMAT_DXT5_NM = 1,
|
||||||
|
FORMAT_DXT5_RXGB,
|
||||||
|
};
|
||||||
|
|
||||||
static_assert(OPT_MAX <= 64, "dwOptions is a unsigned int bitfield");
|
static_assert(OPT_MAX <= 64, "dwOptions is a unsigned int bitfield");
|
||||||
|
|
||||||
struct SConversion
|
struct SConversion
|
||||||
|
@ -338,6 +344,15 @@ namespace
|
||||||
{ nullptr, DXGI_FORMAT_UNKNOWN }
|
{ nullptr, DXGI_FORMAT_UNKNOWN }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SValue<uint32_t> g_pSpecialFormats[] =
|
||||||
|
{
|
||||||
|
{ L"BC3n", FORMAT_DXT5_NM },
|
||||||
|
{ L"DXT5nm", FORMAT_DXT5_NM },
|
||||||
|
{ L"RXGB", FORMAT_DXT5_RXGB },
|
||||||
|
|
||||||
|
{ nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
const SValue<uint32_t> g_pReadOnlyFormats[] =
|
const SValue<uint32_t> g_pReadOnlyFormats[] =
|
||||||
{
|
{
|
||||||
DEFFMT(R32G32B32A32_TYPELESS),
|
DEFFMT(R32G32B32A32_TYPELESS),
|
||||||
|
@ -997,6 +1012,8 @@ namespace
|
||||||
PrintList(13, g_pFormats);
|
PrintList(13, g_pFormats);
|
||||||
wprintf(L" ");
|
wprintf(L" ");
|
||||||
PrintList(13, g_pFormatAliases);
|
PrintList(13, g_pFormatAliases);
|
||||||
|
wprintf(L" ");
|
||||||
|
PrintList(13, g_pSpecialFormats);
|
||||||
|
|
||||||
wprintf(L"\n <filter>: ");
|
wprintf(L"\n <filter>: ");
|
||||||
PrintList(13, g_pFilters);
|
PrintList(13, g_pFilters);
|
||||||
|
@ -1428,6 +1445,8 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||||
float paperWhiteNits = 200.f;
|
float paperWhiteNits = 200.f;
|
||||||
float preserveAlphaCoverageRef = 0.0f;
|
float preserveAlphaCoverageRef = 0.0f;
|
||||||
bool keepRecursiveDirs = false;
|
bool keepRecursiveDirs = false;
|
||||||
|
bool dxt5nm = false;
|
||||||
|
bool dxt5rxgb = false;
|
||||||
uint32_t swizzleElements[4] = { 0, 1, 2, 3 };
|
uint32_t swizzleElements[4] = { 0, 1, 2, 3 };
|
||||||
uint32_t zeroElements[4] = {};
|
uint32_t zeroElements[4] = {};
|
||||||
uint32_t oneElements[4] = {};
|
uint32_t oneElements[4] = {};
|
||||||
|
@ -1581,10 +1600,24 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||||
format = static_cast<DXGI_FORMAT>(LookupByName(pValue, g_pFormatAliases));
|
format = static_cast<DXGI_FORMAT>(LookupByName(pValue, g_pFormatAliases));
|
||||||
if (!format)
|
if (!format)
|
||||||
{
|
{
|
||||||
wprintf(L"Invalid value specified with -f (%ls)\n", pValue);
|
switch (LookupByName(pValue, g_pSpecialFormats))
|
||||||
wprintf(L"\n");
|
{
|
||||||
PrintUsage();
|
case FORMAT_DXT5_NM:
|
||||||
return 1;
|
format = DXGI_FORMAT_BC3_UNORM;
|
||||||
|
dxt5nm = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT_DXT5_RXGB:
|
||||||
|
format = DXGI_FORMAT_BC3_UNORM;
|
||||||
|
dxt5rxgb = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wprintf(L"Invalid value specified with -f (%ls)\n", pValue);
|
||||||
|
wprintf(L"\n");
|
||||||
|
PrintUsage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3454,36 +3487,12 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Compress ----------------------------------------------------------------
|
// --- Compress ----------------------------------------------------------------
|
||||||
if (IsCompressed(tformat) && (FileType == CODEC_DDS))
|
if (FileType == CODEC_DDS)
|
||||||
{
|
{
|
||||||
if (cimage && (cimage->GetMetadata().format == tformat))
|
if (dxt5nm || dxt5rxgb)
|
||||||
{
|
{
|
||||||
// We never changed the image and it was already compressed in our desired format, use original data
|
// Prepare for DXT5nm/RXGB
|
||||||
image.reset(cimage.release());
|
assert(tformat == DXGI_FORMAT_BC3_UNORM);
|
||||||
|
|
||||||
auto& tinfo = image->GetMetadata();
|
|
||||||
|
|
||||||
if ((tinfo.width % 4) != 0 || (tinfo.height % 4) != 0)
|
|
||||||
{
|
|
||||||
non4bc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.format = tinfo.format;
|
|
||||||
assert(info.width == tinfo.width);
|
|
||||||
assert(info.height == tinfo.height);
|
|
||||||
assert(info.depth == tinfo.depth);
|
|
||||||
assert(info.arraySize == tinfo.arraySize);
|
|
||||||
assert(info.mipLevels == tinfo.mipLevels);
|
|
||||||
assert(info.miscFlags == tinfo.miscFlags);
|
|
||||||
assert(info.dimension == tinfo.dimension);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cimage.reset();
|
|
||||||
|
|
||||||
auto img = image->GetImage(0, 0, 0);
|
|
||||||
assert(img);
|
|
||||||
const size_t nimg = image->GetImageCount();
|
|
||||||
|
|
||||||
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
||||||
if (!timage)
|
if (!timage)
|
||||||
|
@ -3492,93 +3501,188 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bc6hbc7 = false;
|
if (dxt5nm)
|
||||||
switch (tformat)
|
|
||||||
{
|
{
|
||||||
case DXGI_FORMAT_BC6H_TYPELESS:
|
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
|
||||||
case DXGI_FORMAT_BC6H_UF16:
|
[=](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t w, size_t y)
|
||||||
case DXGI_FORMAT_BC6H_SF16:
|
|
||||||
case DXGI_FORMAT_BC7_TYPELESS:
|
|
||||||
case DXGI_FORMAT_BC7_UNORM:
|
|
||||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
||||||
bc6hbc7 = true;
|
|
||||||
|
|
||||||
{
|
|
||||||
static bool s_tryonce = false;
|
|
||||||
|
|
||||||
if (!s_tryonce)
|
|
||||||
{
|
{
|
||||||
s_tryonce = true;
|
UNREFERENCED_PARAMETER(y);
|
||||||
|
|
||||||
if (!(dwOptions & (uint64_t(1) << OPT_NOGPU)))
|
for (size_t j = 0; j < w; ++j)
|
||||||
{
|
{
|
||||||
if (!CreateDevice(adapter, pDevice.GetAddressOf()))
|
outPixels[j] = XMVectorPermute<4, 1, 5, 0>(inPixels[j], g_XMIdentityR0);
|
||||||
wprintf(L"\nWARNING: DirectCompute is not available, using BC6H / BC7 CPU codec\n");
|
|
||||||
}
|
}
|
||||||
else
|
}, *timage);
|
||||||
{
|
if (FAILED(hr))
|
||||||
wprintf(L"\nWARNING: using BC6H / BC7 CPU codec\n");
|
{
|
||||||
}
|
wprintf(L" FAILED [DXT5nm] (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
|
||||||
}
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEX_COMPRESS_FLAGS cflags = dwCompress;
|
|
||||||
#ifdef _OPENMP
|
|
||||||
if (!(dwOptions & (uint64_t(1) << OPT_FORCE_SINGLEPROC)))
|
|
||||||
{
|
|
||||||
cflags |= TEX_COMPRESS_PARALLEL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((img->width % 4) != 0 || (img->height % 4) != 0)
|
|
||||||
{
|
|
||||||
non4bc = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bc6hbc7 && pDevice)
|
|
||||||
{
|
|
||||||
hr = Compress(pDevice.Get(), img, nimg, info, tformat, dwCompress | dwSRGB, alphaWeight, *timage);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = Compress(img, nimg, info, tformat, cflags | dwSRGB, alphaThreshold, *timage);
|
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
|
||||||
}
|
[=](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t w, size_t y)
|
||||||
if (FAILED(hr))
|
{
|
||||||
{
|
UNREFERENCED_PARAMETER(y);
|
||||||
wprintf(L" FAILED [compress] (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
|
|
||||||
retVal = 1;
|
for (size_t j = 0; j < w; ++j)
|
||||||
continue;
|
{
|
||||||
|
outPixels[j] = XMVectorSwizzle<3, 1, 2, 0>(inPixels[j]);
|
||||||
|
}
|
||||||
|
}, *timage);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
wprintf(L" FAILED [DXT5 RXGB] (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
auto& tinfo = timage->GetMetadata();
|
auto& tinfo = timage->GetMetadata();
|
||||||
|
#endif
|
||||||
|
|
||||||
info.format = tinfo.format;
|
|
||||||
assert(info.width == tinfo.width);
|
assert(info.width == tinfo.width);
|
||||||
assert(info.height == tinfo.height);
|
assert(info.height == tinfo.height);
|
||||||
assert(info.depth == tinfo.depth);
|
assert(info.depth == tinfo.depth);
|
||||||
assert(info.arraySize == tinfo.arraySize);
|
assert(info.arraySize == tinfo.arraySize);
|
||||||
assert(info.mipLevels == tinfo.mipLevels);
|
assert(info.mipLevels == tinfo.mipLevels);
|
||||||
assert(info.miscFlags == tinfo.miscFlags);
|
assert(info.miscFlags == tinfo.miscFlags);
|
||||||
|
assert(info.format == tinfo.format);
|
||||||
assert(info.dimension == tinfo.dimension);
|
assert(info.dimension == tinfo.dimension);
|
||||||
|
|
||||||
image.swap(timage);
|
image.swap(timage);
|
||||||
|
cimage.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCompressed(tformat))
|
||||||
|
{
|
||||||
|
if (cimage && (cimage->GetMetadata().format == tformat))
|
||||||
|
{
|
||||||
|
// We never changed the image and it was already compressed in our desired format, use original data
|
||||||
|
image.reset(cimage.release());
|
||||||
|
|
||||||
|
auto& tinfo = image->GetMetadata();
|
||||||
|
|
||||||
|
if ((tinfo.width % 4) != 0 || (tinfo.height % 4) != 0)
|
||||||
|
{
|
||||||
|
non4bc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.format = tinfo.format;
|
||||||
|
assert(info.width == tinfo.width);
|
||||||
|
assert(info.height == tinfo.height);
|
||||||
|
assert(info.depth == tinfo.depth);
|
||||||
|
assert(info.arraySize == tinfo.arraySize);
|
||||||
|
assert(info.mipLevels == tinfo.mipLevels);
|
||||||
|
assert(info.miscFlags == tinfo.miscFlags);
|
||||||
|
assert(info.dimension == tinfo.dimension);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cimage.reset();
|
||||||
|
|
||||||
|
auto img = image->GetImage(0, 0, 0);
|
||||||
|
assert(img);
|
||||||
|
const size_t nimg = image->GetImageCount();
|
||||||
|
|
||||||
|
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
|
||||||
|
if (!timage)
|
||||||
|
{
|
||||||
|
wprintf(L"\nERROR: Memory allocation failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bc6hbc7 = false;
|
||||||
|
switch (tformat)
|
||||||
|
{
|
||||||
|
case DXGI_FORMAT_BC6H_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC6H_UF16:
|
||||||
|
case DXGI_FORMAT_BC6H_SF16:
|
||||||
|
case DXGI_FORMAT_BC7_TYPELESS:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM:
|
||||||
|
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||||
|
bc6hbc7 = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
static bool s_tryonce = false;
|
||||||
|
|
||||||
|
if (!s_tryonce)
|
||||||
|
{
|
||||||
|
s_tryonce = true;
|
||||||
|
|
||||||
|
if (!(dwOptions & (uint64_t(1) << OPT_NOGPU)))
|
||||||
|
{
|
||||||
|
if (!CreateDevice(adapter, pDevice.GetAddressOf()))
|
||||||
|
wprintf(L"\nWARNING: DirectCompute is not available, using BC6H / BC7 CPU codec\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wprintf(L"\nWARNING: using BC6H / BC7 CPU codec\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEX_COMPRESS_FLAGS cflags = dwCompress;
|
||||||
|
#ifdef _OPENMP
|
||||||
|
if (!(dwOptions & (uint64_t(1) << OPT_FORCE_SINGLEPROC)))
|
||||||
|
{
|
||||||
|
cflags |= TEX_COMPRESS_PARALLEL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((img->width % 4) != 0 || (img->height % 4) != 0)
|
||||||
|
{
|
||||||
|
non4bc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bc6hbc7 && pDevice)
|
||||||
|
{
|
||||||
|
hr = Compress(pDevice.Get(), img, nimg, info, tformat, dwCompress | dwSRGB, alphaWeight, *timage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = Compress(img, nimg, info, tformat, cflags | dwSRGB, alphaThreshold, *timage);
|
||||||
|
}
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
wprintf(L" FAILED [compress] (%08X%ls)\n", static_cast<unsigned int>(hr), GetErrorDesc(hr));
|
||||||
|
retVal = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& tinfo = timage->GetMetadata();
|
||||||
|
|
||||||
|
info.format = tinfo.format;
|
||||||
|
assert(info.width == tinfo.width);
|
||||||
|
assert(info.height == tinfo.height);
|
||||||
|
assert(info.depth == tinfo.depth);
|
||||||
|
assert(info.arraySize == tinfo.arraySize);
|
||||||
|
assert(info.mipLevels == tinfo.mipLevels);
|
||||||
|
assert(info.miscFlags == tinfo.miscFlags);
|
||||||
|
assert(info.dimension == tinfo.dimension);
|
||||||
|
|
||||||
|
image.swap(timage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
cimage.reset();
|
||||||
cimage.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Set alpha mode ----------------------------------------------------------
|
// --- Set alpha mode ----------------------------------------------------------
|
||||||
if (HasAlpha(info.format)
|
if (HasAlpha(info.format)
|
||||||
&& info.format != DXGI_FORMAT_A8_UNORM)
|
&& info.format != DXGI_FORMAT_A8_UNORM)
|
||||||
{
|
{
|
||||||
if (image->IsAlphaAllOpaque())
|
if (dxt5nm || dxt5rxgb)
|
||||||
|
{
|
||||||
|
info.SetAlphaMode(TEX_ALPHA_MODE_CUSTOM);
|
||||||
|
}
|
||||||
|
else if (image->IsAlphaAllOpaque())
|
||||||
{
|
{
|
||||||
info.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
info.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||||
}
|
}
|
||||||
|
@ -3693,6 +3797,11 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||||
}
|
}
|
||||||
else if (dwOptions & (uint64_t(1) << OPT_USE_DX9))
|
else if (dwOptions & (uint64_t(1) << OPT_USE_DX9))
|
||||||
{
|
{
|
||||||
|
if (dxt5rxgb)
|
||||||
|
{
|
||||||
|
ddsFlags |= DDS_FLAGS_FORCE_DXT5_RXGB;
|
||||||
|
}
|
||||||
|
|
||||||
ddsFlags |= DDS_FLAGS_FORCE_DX9_LEGACY;
|
ddsFlags |= DDS_FLAGS_FORCE_DX9_LEGACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче