Resync'd DDSTextureLoader, ScreenGrab, WICTextureLoader

This commit is contained in:
Chuck Walbourn 2021-06-02 17:14:32 -07:00
Родитель 14b387cc05
Коммит f3b8c48e30
5 изменённых файлов: 96 добавлений и 44 удалений

Просмотреть файл

@ -17,9 +17,10 @@
#include "dxut.h"
#include "DDSTextureLoader.h"
#include <assert.h>
#include <algorithm>
#include <cassert>
#include <memory>
#include <new>
#ifdef __clang__
#pragma clang diagnostic ignored "-Wcovered-switch-default"
@ -122,7 +123,7 @@ namespace
using ScopedHandle = std::unique_ptr<void, handle_closer>;
inline HANDLE safe_handle( HANDLE h ) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
template<UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_ const char (&name)[TNameLength]) noexcept
@ -148,6 +149,8 @@ namespace
return E_POINTER;
}
*bitSize = 0;
if (ddsDataSize > UINT32_MAX)
{
return E_FAIL;
@ -180,7 +183,7 @@ namespace
(MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC))
{
// Must be long enough for both headers and magic value
if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10)))
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10)))
{
return E_FAIL;
}
@ -213,6 +216,8 @@ namespace
return E_POINTER;
}
*bitSize = 0;
// open the file
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(fileName,
@ -262,19 +267,21 @@ namespace
}
// read the data in
DWORD BytesRead = 0;
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(),
ddsData.get(),
fileInfo.EndOfFile.LowPart,
&BytesRead,
&bytesRead,
nullptr
))
{
ddsData.reset();
return HRESULT_FROM_WIN32(GetLastError());
}
if (BytesRead < fileInfo.EndOfFile.LowPart)
if (bytesRead < fileInfo.EndOfFile.LowPart)
{
ddsData.reset();
return E_FAIL;
}
@ -282,6 +289,7 @@ namespace
auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get());
if (dwMagicNumber != DDS_MAGIC)
{
ddsData.reset();
return E_FAIL;
}
@ -291,6 +299,7 @@ namespace
if (hdr->size != sizeof(DDS_HEADER) ||
hdr->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
ddsData.reset();
return E_FAIL;
}
@ -300,8 +309,9 @@ namespace
(MAKEFOURCC('D', 'X', '1', '0') == hdr->ddspf.fourCC))
{
// Must be long enough for both headers and magic value
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10)))
if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10)))
{
ddsData.reset();
return E_FAIL;
}
@ -692,31 +702,37 @@ namespace
return DXGI_FORMAT_B4G4R4A4_UNORM;
}
// NVTT versions 1.x wrote this as RGB instead of LUMINANCE
if (ISBITMASK(0x00ff, 0, 0, 0xff00))
{
return DXGI_FORMAT_R8G8_UNORM;
}
if (ISBITMASK(0xffff, 0, 0, 0))
{
return DXGI_FORMAT_R16_UNORM;
}
// No DXGI format maps to ISBITMASK(0x0f00,0x00f0,0x000f,0) aka D3DFMT_X4R4G4B4
// No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc.
// No 3:3:2:8 or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_A8P8, etc.
break;
case 8:
// NVTT versions 1.x wrote this as RGB instead of LUMINANCE
if (ISBITMASK(0xff, 0, 0, 0))
{
return DXGI_FORMAT_R8_UNORM;
}
// No 3:3:2 or paletted DXGI formats aka D3DFMT_R3G3B2, D3DFMT_P8
break;
}
}
else if (ddpf.flags & DDS_LUMINANCE)
{
if (8 == ddpf.RGBBitCount)
{
if (ISBITMASK(0xff, 0, 0, 0))
{
return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension
}
// No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4
if (ISBITMASK(0x00ff, 0, 0, 0xff00))
{
return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16
}
}
if (16 == ddpf.RGBBitCount)
switch (ddpf.RGBBitCount)
{
case 16:
if (ISBITMASK(0xffff, 0, 0, 0))
{
return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension
@ -725,6 +741,21 @@ namespace
{
return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension
}
break;
case 8:
if (ISBITMASK(0xff, 0, 0, 0))
{
return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension
}
// No DXGI format maps to ISBITMASK(0x0f,0,0,0xf0) aka D3DFMT_A4L4
if (ISBITMASK(0x00ff, 0, 0, 0xff00))
{
return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16
}
break;
}
}
else if (ddpf.flags & DDS_ALPHA)
@ -736,16 +767,9 @@ namespace
}
else if (ddpf.flags & DDS_BUMPDUDV)
{
if (16 == ddpf.RGBBitCount)
{
if (ISBITMASK(0x00ff, 0xff00, 0, 0))
{
return DXGI_FORMAT_R8G8_SNORM; // D3DX10/11 writes this out as DX10 extension
}
}
if (32 == ddpf.RGBBitCount)
switch (ddpf.RGBBitCount)
{
case 32:
if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
{
return DXGI_FORMAT_R8G8B8A8_SNORM; // D3DX10/11 writes this out as DX10 extension
@ -756,6 +780,14 @@ namespace
}
// No DXGI format maps to ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000) aka D3DFMT_A2W10V10U10
break;
case 16:
if (ISBITMASK(0x00ff, 0xff00, 0, 0))
{
return DXGI_FORMAT_R8G8_SNORM; // D3DX10/11 writes this out as DX10 extension
}
break;
}
// No DXGI format maps to DDPF_BUMPLUMINANCE aka D3DFMT_L6V5U5, D3DFMT_X8L8V8U8

Просмотреть файл

@ -18,6 +18,7 @@
#include <d3d11_1.h>
#include <cstddef>
#include <cstdint>

Просмотреть файл

@ -25,9 +25,12 @@
#include "ScreenGrab.h"
#include <assert.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <memory>
#include <new>
#include <wincodec.h>
@ -791,9 +794,11 @@ HRESULT DirectX::SaveDDSTextureToFile(
// Create file
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(CreateFile2(fileName, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
ScopedHandle hFile(safe_handle(CreateFile2(fileName,
GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
#else
ScopedHandle hFile(safe_handle(CreateFileW(fileName, GENERIC_WRITE | DELETE, 0, nullptr, CREATE_ALWAYS, 0, nullptr)));
ScopedHandle hFile(safe_handle(CreateFileW(fileName,
GENERIC_WRITE | DELETE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)));
#endif
if (!hFile)
return HRESULT_FROM_WIN32(GetLastError());

Просмотреть файл

@ -29,14 +29,17 @@
#include "WICTextureLoader.h"
#include <dxgiformat.h>
#include <assert.h>
#include <wincodec.h>
#include <wrl\client.h>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iterator>
#include <memory>
#include <new>
#ifdef __clang__
#pragma clang diagnostic ignored "-Wcovered-switch-default"
@ -97,14 +100,13 @@ namespace
//-------------------------------------------------------------------------------------
// WIC Pixel Format nearest conversion table
//-------------------------------------------------------------------------------------
struct WICConvert
{
const GUID& source;
const GUID& target;
const GUID& source;
const GUID& target;
};
constexpr WICConvert g_WICConvert[] =
constexpr WICConvert g_WICConvert [] =
{
// Note target GUID in this conversion table must be one of those directly supported formats (above).
@ -166,7 +168,7 @@ namespace
bool g_WIC2 = false;
BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID* ifactory) noexcept
BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID *ifactory) noexcept
{
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
HRESULT hr = CoCreateInstance(
@ -224,7 +226,7 @@ namespace
//---------------------------------------------------------------------------------
DXGI_FORMAT _WICToDXGI(const GUID& guid) noexcept
{
for (size_t i = 0; i < _countof(g_WICFormats); ++i)
for (size_t i = 0; i < std::size(g_WICFormats); ++i)
{
if (memcmp(&g_WICFormats[i].wic, &guid, sizeof(GUID)) == 0)
return g_WICFormats[i].format;
@ -459,7 +461,7 @@ namespace
}
else
{
for (size_t i = 0; i < _countof(g_WICConvert); ++i)
for (size_t i = 0; i < std::size(g_WICConvert); ++i)
{
if (memcmp(&g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID)) == 0)
{

Просмотреть файл

@ -25,6 +25,7 @@
#include <d3d11_1.h>
#include <cstddef>
#include <cstdint>
namespace DirectX
@ -41,6 +42,17 @@ namespace DirectX
WIC_LOADER_MAKE_SQUARE = 0x40,
WIC_LOADER_FORCE_RGBA32 = 0x80,
};
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
#endif
DEFINE_ENUM_FLAG_OPERATORS(WIC_LOADER_FLAGS);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
// Standard version