Code refactor and reformat for texture loaders (#137)

This commit is contained in:
Chuck Walbourn 2019-04-17 14:14:01 -07:00 committed by GitHub
parent 86b2bb5194
commit 56d86325b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 503 additions and 302 deletions

View File

@ -134,6 +134,71 @@ namespace
#endif #endif
} }
//--------------------------------------------------------------------------------------
HRESULT LoadTextureDataFromMemory(
_In_reads_(ddsDataSize) const uint8_t* ddsData,
size_t ddsDataSize,
const DDS_HEADER** header,
const uint8_t** bitData,
size_t* bitSize)
{
if (!header || !bitData || !bitSize)
{
return E_POINTER;
}
if (ddsDataSize > UINT32_MAX)
{
return E_FAIL;
}
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
{
return E_FAIL;
}
// DDS files always start with the same magic number ("DDS ")
auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData);
if (dwMagicNumber != DDS_MAGIC)
{
return E_FAIL;
}
auto hdr = reinterpret_cast<const DDS_HEADER*>(ddsData + sizeof(uint32_t));
// Verify header to validate DDS file
if (hdr->size != sizeof(DDS_HEADER) ||
hdr->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return E_FAIL;
}
// Check for DX10 extension
bool bDXT10Header = false;
if ((hdr->ddspf.flags & DDS_FOURCC) &&
(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)))
{
return E_FAIL;
}
bDXT10Header = true;
}
// setup the pointers in the process request
*header = hdr;
ptrdiff_t offset = sizeof(uint32_t)
+ sizeof(DDS_HEADER)
+ (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0);
*bitData = ddsData + offset;
*bitSize = ddsDataSize - offset;
return S_OK;
}
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT LoadTextureDataFromFile( HRESULT LoadTextureDataFromFile(
_In_z_ const wchar_t* fileName, _In_z_ const wchar_t* fileName,
@ -183,7 +248,7 @@ namespace
} }
// Need at least enough data to fill the header and magic number to be a valid DDS // Need at least enough data to fill the header and magic number to be a valid DDS
if (fileInfo.EndOfFile.LowPart < (sizeof(DDS_HEADER) + sizeof(uint32_t))) if (fileInfo.EndOfFile.LowPart < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
{ {
return E_FAIL; return E_FAIL;
} }
@ -213,7 +278,7 @@ namespace
} }
// DDS files always start with the same magic number ("DDS ") // DDS files always start with the same magic number ("DDS ")
uint32_t dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get()); auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get());
if (dwMagicNumber != DDS_MAGIC) if (dwMagicNumber != DDS_MAGIC)
{ {
return E_FAIL; return E_FAIL;
@ -1159,7 +1224,6 @@ namespace
return hr; return hr;
} }
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT CreateTextureFromDDS( HRESULT CreateTextureFromDDS(
_In_ ID3D11Device* d3dDevice, _In_ ID3D11Device* d3dDevice,
@ -1365,12 +1429,17 @@ namespace
{ {
// Create texture with auto-generated mipmaps // Create texture with auto-generated mipmaps
ID3D11Resource* tex = nullptr; ID3D11Resource* tex = nullptr;
hr = CreateD3DResources(d3dDevice, resDim, width, height, depth, 0, arraySize, hr = CreateD3DResources(d3dDevice,
format, usage, resDim, width, height, depth, 0, arraySize,
format,
usage,
bindFlags | D3D11_BIND_RENDER_TARGET, bindFlags | D3D11_BIND_RENDER_TARGET,
cpuAccessFlags, cpuAccessFlags,
miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS, forceSRGB, miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS,
isCubeMap, nullptr, &tex, textureView); forceSRGB,
isCubeMap,
nullptr,
&tex, textureView);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
size_t numBytes = 0; size_t numBytes = 0;
@ -1460,14 +1529,20 @@ namespace
size_t twidth = 0; size_t twidth = 0;
size_t theight = 0; size_t theight = 0;
size_t tdepth = 0; size_t tdepth = 0;
hr = FillInitData(width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData, hr = FillInitData(width, height, depth, mipCount, arraySize,
format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, initData.get()); twidth, theight, tdepth, skipMip, initData.get());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = CreateD3DResources(d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, hr = CreateD3DResources(d3dDevice,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
isCubeMap, initData.get(), texture, textureView); format,
usage, bindFlags, cpuAccessFlags, miscFlags,
forceSRGB,
isCubeMap,
initData.get(),
texture, textureView);
if (FAILED(hr) && !maxsize && (mipCount > 1)) if (FAILED(hr) && !maxsize && (mipCount > 1))
{ {
@ -1505,9 +1580,14 @@ namespace
twidth, theight, tdepth, skipMip, initData.get()); twidth, theight, tdepth, skipMip, initData.get());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = CreateD3DResources(d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize, hr = CreateD3DResources(d3dDevice,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
isCubeMap, initData.get(), texture, textureView); format,
usage, bindFlags, cpuAccessFlags, miscFlags,
forceSRGB,
isCubeMap,
initData.get(),
texture, textureView);
} }
} }
} }
@ -1544,11 +1624,67 @@ namespace
return DDS_ALPHA_MODE_UNKNOWN; return DDS_ALPHA_MODE_UNKNOWN;
} }
//--------------------------------------------------------------------------------------
void SetDebugTextureInfo(
_In_z_ const wchar_t* fileName,
_In_opt_ ID3D11Resource** texture,
_In_opt_ ID3D11ShaderResourceView** textureView)
{
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture || textureView)
{
CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_UTF8,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
nullptr
);
if (result > 0)
{
const char* pstrName = strrchr(strFileA, '\\');
if (!pstrName)
{
pstrName = strFileA;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
if (textureView && *textureView)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
}
}
#else
UNREFERENCED_PARAMETER(fileName);
UNREFERENCED_PARAMETER(texture);
UNREFERENCED_PARAMETER(textureView);
#endif
}
} // anonymous namespace } // anonymous namespace
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemory(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromMemory(
ID3D11Device* d3dDevice,
const uint8_t* ddsData, const uint8_t* ddsData,
size_t ddsDataSize, size_t ddsDataSize,
ID3D11Resource** texture, ID3D11Resource** texture,
@ -1556,13 +1692,17 @@ HRESULT DirectX::CreateDDSTextureFromMemory(ID3D11Device* d3dDevice,
size_t maxsize, size_t maxsize,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromMemoryEx(d3dDevice, nullptr, ddsData, ddsDataSize, maxsize, return CreateDDSTextureFromMemoryEx(d3dDevice, nullptr,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, ddsData, ddsDataSize,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
false,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemory(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromMemory(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const uint8_t* ddsData, const uint8_t* ddsData,
size_t ddsDataSize, size_t ddsDataSize,
@ -1571,13 +1711,17 @@ HRESULT DirectX::CreateDDSTextureFromMemory(ID3D11Device* d3dDevice,
size_t maxsize, size_t maxsize,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromMemoryEx(d3dDevice, d3dContext, ddsData, ddsDataSize, maxsize, return CreateDDSTextureFromMemoryEx(d3dDevice, d3dContext,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, ddsData, ddsDataSize,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
false,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromMemoryEx(
ID3D11Device* d3dDevice,
const uint8_t* ddsData, const uint8_t* ddsData,
size_t ddsDataSize, size_t ddsDataSize,
size_t maxsize, size_t maxsize,
@ -1590,13 +1734,17 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromMemoryEx(d3dDevice, nullptr, ddsData, ddsDataSize, maxsize, return CreateDDSTextureFromMemoryEx(d3dDevice, nullptr,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, ddsData, ddsDataSize,
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
forceSRGB,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromMemoryEx(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const uint8_t* ddsData, const uint8_t* ddsData,
size_t ddsDataSize, size_t ddsDataSize,
@ -1629,47 +1777,25 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice,
} }
// Validate DDS file in memory // Validate DDS file in memory
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) const DDS_HEADER* header = nullptr;
const uint8_t* bitData = nullptr;
size_t bitSize = 0;
HRESULT hr = LoadTextureDataFromMemory(ddsData, ddsDataSize,
&header,
&bitData,
&bitSize
);
if (FAILED(hr))
{ {
return E_FAIL; return hr;
} }
uint32_t dwMagicNumber = *(const uint32_t*)(ddsData); hr = CreateTextureFromDDS(d3dDevice, d3dContext,
if (dwMagicNumber != DDS_MAGIC) header, bitData, bitSize,
{ maxsize,
return E_FAIL; usage, bindFlags, cpuAccessFlags, miscFlags,
} forceSRGB,
auto header = reinterpret_cast<const DDS_HEADER*>(ddsData + sizeof(uint32_t));
// Verify header to validate DDS file
if (header->size != sizeof(DDS_HEADER) ||
header->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return E_FAIL;
}
// Check for DX10 extension
bool bDXT10Header = false;
if ((header->ddspf.flags & DDS_FOURCC) &&
(MAKEFOURCC('D', 'X', '1', '0') == header->ddspf.fourCC))
{
// Must be long enough for both headers and magic value
if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10)))
{
return E_FAIL;
}
bDXT10Header = true;
}
ptrdiff_t offset = sizeof(uint32_t)
+ sizeof(DDS_HEADER)
+ (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0);
HRESULT hr = CreateTextureFromDDS(d3dDevice, d3dContext, header,
ddsData + offset, ddsDataSize - offset, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView); texture, textureView);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -1692,20 +1818,24 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice,
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFile(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromFile(
ID3D11Device* d3dDevice,
const wchar_t* fileName, const wchar_t* fileName,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
size_t maxsize, size_t maxsize,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromFileEx(d3dDevice, nullptr, fileName, maxsize, return CreateDDSTextureFromFileEx(d3dDevice, nullptr,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, fileName, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
false,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFile(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromFile(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const wchar_t* fileName, const wchar_t* fileName,
ID3D11Resource** texture, ID3D11Resource** texture,
@ -1713,13 +1843,17 @@ HRESULT DirectX::CreateDDSTextureFromFile(ID3D11Device* d3dDevice,
size_t maxsize, size_t maxsize,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromFileEx(d3dDevice, d3dContext, fileName, maxsize, return CreateDDSTextureFromFileEx(d3dDevice, d3dContext,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false, fileName,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
false,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromFileEx(
ID3D11Device* d3dDevice,
const wchar_t* fileName, const wchar_t* fileName,
size_t maxsize, size_t maxsize,
D3D11_USAGE usage, D3D11_USAGE usage,
@ -1731,13 +1865,17 @@ HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode) DDS_ALPHA_MODE* alphaMode)
{ {
return CreateDDSTextureFromFileEx(d3dDevice, nullptr, fileName, maxsize, return CreateDDSTextureFromFileEx(d3dDevice, nullptr,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, fileName,
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
forceSRGB,
texture, textureView, alphaMode); texture, textureView, alphaMode);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateDDSTextureFromFileEx(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const wchar_t* fileName, const wchar_t* fileName,
size_t maxsize, size_t maxsize,
@ -1784,56 +1922,16 @@ HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice,
return hr; return hr;
} }
hr = CreateTextureFromDDS(d3dDevice, d3dContext, header, hr = CreateTextureFromDDS(d3dDevice, d3dContext,
bitData, bitSize, maxsize, header, bitData, bitSize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
forceSRGB,
texture, textureView); texture, textureView);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) SetDebugTextureInfo(fileName, texture, textureView);
if (texture || textureView)
{
CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_UTF8,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
FALSE
);
if (result > 0)
{
const CHAR* pstrName = strrchr(strFileA, '\\');
if (!pstrName)
{
pstrName = strFileA;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
if (textureView && *textureView)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
}
}
#endif
if (alphaMode) if (alphaMode)
*alphaMode = GetAlphaMode(header); *alphaMode = GetAlphaMode(header);

View File

@ -147,6 +147,72 @@ namespace
return count; return count;
} }
//--------------------------------------------------------------------------------------
HRESULT LoadTextureDataFromMemory(
_In_reads_(ddsDataSize) const uint8_t* ddsData,
size_t ddsDataSize,
const DDS_HEADER** header,
const uint8_t** bitData,
size_t* bitSize)
{
if (!header || !bitData || !bitSize)
{
return E_POINTER;
}
if (ddsDataSize > UINT32_MAX)
{
return E_FAIL;
}
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER)))
{
return E_FAIL;
}
// DDS files always start with the same magic number ("DDS ")
auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData);
if (dwMagicNumber != DDS_MAGIC)
{
return E_FAIL;
}
auto hdr = reinterpret_cast<const DDS_HEADER*>(ddsData + sizeof(uint32_t));
// Verify header to validate DDS file
if (hdr->size != sizeof(DDS_HEADER) ||
hdr->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return E_FAIL;
}
// Check for DX10 extension
bool bDXT10Header = false;
if ((hdr->ddspf.flags & DDS_FOURCC) &&
(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)))
{
return E_FAIL;
}
bDXT10Header = true;
}
// setup the pointers in the process request
*header = hdr;
ptrdiff_t offset = sizeof(uint32_t)
+ sizeof(DDS_HEADER)
+ (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0);
*bitData = ddsData + offset;
*bitSize = ddsDataSize - offset;
return S_OK;
}
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT LoadTextureDataFromFile( HRESULT LoadTextureDataFromFile(
_In_z_ const wchar_t* fileName, _In_z_ const wchar_t* fileName,
@ -216,7 +282,7 @@ namespace
} }
// DDS files always start with the same magic number ("DDS ") // DDS files always start with the same magic number ("DDS ")
uint32_t dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get()); auto dwMagicNumber = *reinterpret_cast<const uint32_t*>(ddsData.get());
if (dwMagicNumber != DDS_MAGIC) if (dwMagicNumber != DDS_MAGIC)
{ {
return E_FAIL; return E_FAIL;
@ -1342,6 +1408,35 @@ namespace
return DDS_ALPHA_MODE_UNKNOWN; return DDS_ALPHA_MODE_UNKNOWN;
} }
//--------------------------------------------------------------------------------------
void SetDebugTextureInfo(
_In_z_ const wchar_t* fileName,
_In_ ID3D12Resource** texture)
{
#if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture)
{
const wchar_t* pstrName = wcsrchr(fileName, '\\');
if (!pstrName)
{
pstrName = fileName;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetName(pstrName);
}
}
#else
UNREFERENCED_PARAMETER(fileName);
UNREFERENCED_PARAMETER(texture);
#endif
}
} // anonymous namespace } // anonymous namespace
@ -1403,46 +1498,22 @@ HRESULT DirectX::LoadDDSTextureFromMemoryEx(
} }
// Validate DDS file in memory // Validate DDS file in memory
if (ddsDataSize < (sizeof(uint32_t) + sizeof(DDS_HEADER))) const DDS_HEADER* header = nullptr;
const uint8_t* bitData = nullptr;
size_t bitSize = 0;
HRESULT hr = LoadTextureDataFromMemory(ddsData, ddsDataSize,
&header,
&bitData,
&bitSize
);
if (FAILED(hr))
{ {
return E_FAIL; return hr;
} }
uint32_t dwMagicNumber = *(const uint32_t*)(ddsData); hr = CreateTextureFromDDS(d3dDevice,
if (dwMagicNumber != DDS_MAGIC) header, bitData, bitSize, maxsize,
{
return E_FAIL;
}
auto header = reinterpret_cast<const DDS_HEADER*>(ddsData + sizeof(uint32_t));
// Verify header to validate DDS file
if (header->size != sizeof(DDS_HEADER) ||
header->ddspf.size != sizeof(DDS_PIXELFORMAT))
{
return E_FAIL;
}
// Check for DX10 extension
bool bDXT10Header = false;
if ((header->ddspf.flags & DDS_FOURCC) &&
(MAKEFOURCC('D', 'X', '1', '0') == header->ddspf.fourCC))
{
// Must be long enough for both headers and magic value
if (ddsDataSize < (sizeof(DDS_HEADER) + sizeof(uint32_t) + sizeof(DDS_HEADER_DXT10)))
{
return E_FAIL;
}
bDXT10Header = true;
}
ptrdiff_t offset = sizeof(uint32_t)
+ sizeof(DDS_HEADER)
+ (bDXT10Header ? sizeof(DDS_HEADER_DXT10) : 0);
HRESULT hr = CreateTextureFromDDS(d3dDevice,
header, ddsData + offset, ddsDataSize - offset, maxsize,
resFlags, loadFlags, resFlags, loadFlags,
texture, subresources, isCubeMap); texture, subresources, isCubeMap);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -1538,38 +1609,7 @@ HRESULT DirectX::LoadDDSTextureFromFileEx(
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
#if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) SetDebugTextureInfo(fileName, texture);
if (texture)
{
CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_UTF8,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
FALSE
);
if (result > 0)
{
const wchar_t* pstrName = wcsrchr(fileName, '\\');
if (!pstrName)
{
pstrName = fileName;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetName(pstrName);
}
}
}
#endif
if (alphaMode) if (alphaMode)
*alphaMode = GetAlphaMode(header); *alphaMode = GetAlphaMode(header);

View File

@ -677,24 +677,85 @@ namespace
return hr; return hr;
} }
//--------------------------------------------------------------------------------------
void SetDebugTextureInfo(
_In_z_ const wchar_t* fileName,
_In_opt_ ID3D11Resource** texture,
_In_opt_ ID3D11ShaderResourceView** textureView)
{
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture || textureView)
{
CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_UTF8,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
nullptr
);
if (result > 0)
{
const char* pstrName = strrchr(strFileA, '\\');
if (!pstrName)
{
pstrName = strFileA;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
if (textureView && *textureView)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
}
}
#else
UNREFERENCED_PARAMETER(fileName);
UNREFERENCED_PARAMETER(texture);
UNREFERENCED_PARAMETER(textureView);
#endif
}
} // anonymous namespace } // anonymous namespace
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemory(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromMemory(
ID3D11Device* d3dDevice,
const uint8_t* wicData, const uint8_t* wicData,
size_t wicDataSize, size_t wicDataSize,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
size_t maxsize) size_t maxsize)
{ {
return CreateWICTextureFromMemoryEx(d3dDevice, nullptr, wicData, wicDataSize, maxsize, return CreateWICTextureFromMemoryEx(d3dDevice, nullptr,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, WIC_LOADER_DEFAULT, wicData, wicDataSize,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
WIC_LOADER_DEFAULT,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemory(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromMemory(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const uint8_t* wicData, const uint8_t* wicData,
size_t wicDataSize, size_t wicDataSize,
@ -702,13 +763,17 @@ HRESULT DirectX::CreateWICTextureFromMemory(ID3D11Device* d3dDevice,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
size_t maxsize) size_t maxsize)
{ {
return CreateWICTextureFromMemoryEx(d3dDevice, d3dContext, wicData, wicDataSize, maxsize, return CreateWICTextureFromMemoryEx(d3dDevice, d3dContext,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, WIC_LOADER_DEFAULT, wicData, wicDataSize,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
WIC_LOADER_DEFAULT,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromMemoryEx(
ID3D11Device* d3dDevice,
const uint8_t* wicData, const uint8_t* wicData,
size_t wicDataSize, size_t wicDataSize,
size_t maxsize, size_t maxsize,
@ -720,13 +785,17 @@ HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView) ID3D11ShaderResourceView** textureView)
{ {
return CreateWICTextureFromMemoryEx(d3dDevice, nullptr, wicData, wicDataSize, maxsize, return CreateWICTextureFromMemoryEx(d3dDevice, nullptr,
usage, bindFlags, cpuAccessFlags, miscFlags, loadFlags, wicData, wicDataSize,
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
loadFlags,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromMemoryEx(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const uint8_t* wicData, const uint8_t* wicData,
size_t wicDataSize, size_t wicDataSize,
@ -782,8 +851,11 @@ HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), maxsize, hr = CreateTextureFromWIC(d3dDevice, d3dContext,
usage, bindFlags, cpuAccessFlags, miscFlags, loadFlags, frame.Get(),
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
loadFlags,
texture, textureView); texture, textureView);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -803,32 +875,40 @@ HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice,
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFile(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromFile(
ID3D11Device* d3dDevice,
const wchar_t* fileName, const wchar_t* fileName,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
size_t maxsize) size_t maxsize)
{ {
return CreateWICTextureFromFileEx(d3dDevice, nullptr, fileName, maxsize, return CreateWICTextureFromFileEx(d3dDevice, nullptr,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, WIC_LOADER_DEFAULT, fileName, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
WIC_LOADER_DEFAULT,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFile(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromFile(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const wchar_t* fileName, const wchar_t* fileName,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView, ID3D11ShaderResourceView** textureView,
size_t maxsize) size_t maxsize)
{ {
return CreateWICTextureFromFileEx(d3dDevice, d3dContext, fileName, maxsize, return CreateWICTextureFromFileEx(d3dDevice, d3dContext,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, WIC_LOADER_DEFAULT, fileName,
maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0,
WIC_LOADER_DEFAULT,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromFileEx(
ID3D11Device* d3dDevice,
const wchar_t* fileName, const wchar_t* fileName,
size_t maxsize, size_t maxsize,
D3D11_USAGE usage, D3D11_USAGE usage,
@ -839,13 +919,17 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
ID3D11Resource** texture, ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView) ID3D11ShaderResourceView** textureView)
{ {
return CreateWICTextureFromFileEx(d3dDevice, nullptr, fileName, maxsize, return CreateWICTextureFromFileEx(d3dDevice, nullptr,
usage, bindFlags, cpuAccessFlags, miscFlags, loadFlags, fileName,
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
loadFlags,
texture, textureView); texture, textureView);
} }
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice, HRESULT DirectX::CreateWICTextureFromFileEx(
ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext, ID3D11DeviceContext* d3dContext,
const wchar_t* fileName, const wchar_t* fileName,
size_t maxsize, size_t maxsize,
@ -875,7 +959,11 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
// Initialize WIC // Initialize WIC
ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapDecoder> decoder;
HRESULT hr = pWIC->CreateDecoderFromFilename(fileName, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf()); HRESULT hr = pWIC->CreateDecoderFromFilename(fileName,
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand,
decoder.GetAddressOf());
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -884,56 +972,17 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), maxsize, hr = CreateTextureFromWIC(d3dDevice, d3dContext,
usage, bindFlags, cpuAccessFlags, miscFlags, loadFlags, frame.Get(),
maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags,
loadFlags,
texture, textureView); texture, textureView);
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (texture || textureView) SetDebugTextureInfo(fileName, texture, textureView);
{
char strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_UTF8,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
FALSE
);
if (result > 0)
{
const char* pstrName = strrchr(strFileA, '\\');
if (!pstrName)
{
pstrName = strFileA;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
if (textureView && *textureView)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
}
}
} }
#endif
return hr; return hr;
} }

View File

@ -529,6 +529,35 @@ namespace
*texture = tex; *texture = tex;
return hr; return hr;
} }
//--------------------------------------------------------------------------------------
void SetDebugTextureInfo(
_In_z_ const wchar_t* fileName,
_In_ ID3D12Resource** texture)
{
#if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture)
{
const wchar_t* pstrName = wcsrchr(fileName, '\\');
if (!pstrName)
{
pstrName = fileName;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetName(pstrName);
}
}
#else
UNREFERENCED_PARAMETER(fileName);
UNREFERENCED_PARAMETER(texture);
#endif
}
} // anonymous namespace } // anonymous namespace
@ -569,50 +598,50 @@ HRESULT DirectX::LoadWICTextureFromMemoryEx(
std::unique_ptr<uint8_t[]>& decodedData, std::unique_ptr<uint8_t[]>& decodedData,
D3D12_SUBRESOURCE_DATA& subresource) D3D12_SUBRESOURCE_DATA& subresource)
{ {
if ( texture ) if (texture)
{ {
*texture = nullptr; *texture = nullptr;
} }
if (!d3dDevice || !wicData || !texture) if (!d3dDevice || !wicData || !texture)
return E_INVALIDARG; return E_INVALIDARG;
if ( !wicDataSize ) if (!wicDataSize)
return E_FAIL; return E_FAIL;
if ( wicDataSize > UINT32_MAX ) if (wicDataSize > UINT32_MAX)
return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE ); return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
auto pWIC = _GetWIC(); auto pWIC = _GetWIC();
if ( !pWIC ) if (!pWIC)
return E_NOINTERFACE; return E_NOINTERFACE;
// Create input stream for memory // Create input stream for memory
ComPtr<IWICStream> stream; ComPtr<IWICStream> stream;
HRESULT hr = pWIC->CreateStream( stream.GetAddressOf() ); HRESULT hr = pWIC->CreateStream(stream.GetAddressOf());
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
hr = stream->InitializeFromMemory( const_cast<uint8_t*>( wicData ), static_cast<DWORD>( wicDataSize ) ); hr = stream->InitializeFromMemory(const_cast<uint8_t*>(wicData), static_cast<DWORD>(wicDataSize));
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
// Initialize WIC // Initialize WIC
ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapDecoder> decoder;
hr = pWIC->CreateDecoderFromStream( stream.Get(), nullptr, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); hr = pWIC->CreateDecoderFromStream(stream.Get(), nullptr, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf());
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
ComPtr<IWICBitmapFrameDecode> frame; ComPtr<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame( 0, frame.GetAddressOf() ); hr = decoder->GetFrame(0, frame.GetAddressOf());
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
hr = CreateTextureFromWIC( d3dDevice, hr = CreateTextureFromWIC(d3dDevice,
frame.Get(), maxsize, frame.Get(), maxsize,
resFlags, loadFlags, resFlags, loadFlags,
texture, decodedData, subresource); texture, decodedData, subresource);
if ( FAILED(hr)) if (FAILED(hr))
return hr; return hr;
_Analysis_assume_(*texture != nullptr); _Analysis_assume_(*texture != nullptr);
@ -656,52 +685,37 @@ HRESULT DirectX::LoadWICTextureFromFileEx(
std::unique_ptr<uint8_t[]>& decodedData, std::unique_ptr<uint8_t[]>& decodedData,
D3D12_SUBRESOURCE_DATA& subresource) D3D12_SUBRESOURCE_DATA& subresource)
{ {
if ( texture ) if (texture)
{ {
*texture = nullptr; *texture = nullptr;
} }
if (!d3dDevice || !fileName || !texture ) if (!d3dDevice || !fileName || !texture)
return E_INVALIDARG; return E_INVALIDARG;
auto pWIC = _GetWIC(); auto pWIC = _GetWIC();
if ( !pWIC ) if (!pWIC)
return E_NOINTERFACE; return E_NOINTERFACE;
// Initialize WIC // Initialize WIC
ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapDecoder> decoder;
HRESULT hr = pWIC->CreateDecoderFromFilename( fileName, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf() ); HRESULT hr = pWIC->CreateDecoderFromFilename(fileName, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, decoder.GetAddressOf());
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
ComPtr<IWICBitmapFrameDecode> frame; ComPtr<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame( 0, frame.GetAddressOf() ); hr = decoder->GetFrame(0, frame.GetAddressOf());
if ( FAILED(hr) ) if (FAILED(hr))
return hr; return hr;
hr = CreateTextureFromWIC( d3dDevice, frame.Get(), maxsize, hr = CreateTextureFromWIC(d3dDevice, frame.Get(), maxsize,
resFlags, loadFlags, resFlags, loadFlags,
texture, decodedData, subresource ); texture, decodedData, subresource);
#if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) if (SUCCEEDED(hr))
if ( SUCCEEDED(hr) )
{ {
const wchar_t* pstrName = wcsrchr(fileName, '\\' ); SetDebugTextureInfo(fileName, texture);
if (!pstrName)
{
pstrName = fileName;
}
else
{
pstrName++;
}
if (texture && *texture)
{
(*texture)->SetName(pstrName);
}
} }
#endif
return hr; return hr;
} }