1
0
mirror of https://github.com/microsoft/DirectXTex synced 2024-11-22 04:20:07 +00:00

Resync DDSTextureLoader, ScreenGrab, WICTextureLoader

This commit is contained in:
Chuck Walbourn 2018-08-02 15:24:25 -07:00
parent ba0280c500
commit 3f8b8d36b9
6 changed files with 155 additions and 105 deletions

View File

@ -851,13 +851,10 @@ namespace
size_t d = depth; size_t d = depth;
for (size_t i = 0; i < mipCount; i++) for (size_t i = 0; i < mipCount; i++)
{ {
GetSurfaceInfo(w, GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
h,
format, if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX)
&NumBytes, return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
&RowBytes,
nullptr
);
if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize)) if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize))
{ {
@ -959,9 +956,9 @@ namespace
initData, initData,
&tex &tex
); );
if (SUCCEEDED(hr) && tex != 0) if (SUCCEEDED(hr) && tex)
{ {
if (textureView != 0) if (textureView)
{ {
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = format; SRVDesc.Format = format;
@ -989,7 +986,7 @@ namespace
} }
} }
if (texture != 0) if (texture)
{ {
*texture = tex; *texture = tex;
} }
@ -1029,9 +1026,9 @@ namespace
initData, initData,
&tex &tex
); );
if (SUCCEEDED(hr) && tex != 0) if (SUCCEEDED(hr) && tex)
{ {
if (textureView != 0) if (textureView)
{ {
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = format; SRVDesc.Format = format;
@ -1075,7 +1072,7 @@ namespace
} }
} }
if (texture != 0) if (texture)
{ {
*texture = tex; *texture = tex;
} }
@ -1106,9 +1103,9 @@ namespace
initData, initData,
&tex &tex
); );
if (SUCCEEDED(hr) && tex != 0) if (SUCCEEDED(hr) && tex)
{ {
if (textureView != 0) if (textureView)
{ {
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = format; SRVDesc.Format = format;
@ -1127,7 +1124,7 @@ namespace
} }
} }
if (texture != 0) if (texture)
{ {
*texture = tex; *texture = tex;
} }
@ -1330,7 +1327,7 @@ namespace
} }
bool autogen = false; bool autogen = false;
if (mipCount == 1 && d3dContext != 0 && textureView != 0) // Must have context and shader-view to auto generate mipmaps if (mipCount == 1 && d3dContext && textureView) // Must have context and shader-view to auto generate mipmaps
{ {
// See if format is supported for auto-gen mipmaps (varies by feature level) // See if format is supported for auto-gen mipmaps (varies by feature level)
UINT fmtSupport = 0; UINT fmtSupport = 0;
@ -1370,6 +1367,9 @@ namespace
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
} }
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
D3D11_SHADER_RESOURCE_VIEW_DESC desc; D3D11_SHADER_RESOURCE_VIEW_DESC desc;
(*textureView)->GetDesc(&desc); (*textureView)->GetDesc(&desc);
@ -1653,12 +1653,12 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx(ID3D11Device* d3dDevice,
texture, textureView); texture, textureView);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
SetDebugObjectName(*texture, "DDSTextureLoader"); SetDebugObjectName(*texture, "DDSTextureLoader");
} }
if (textureView != 0 && *textureView != 0) if (textureView && *textureView)
{ {
SetDebugObjectName(*textureView, "DDSTextureLoader"); SetDebugObjectName(*textureView, "DDSTextureLoader");
} }
@ -1772,7 +1772,7 @@ HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice,
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture != 0 || textureView != 0) if (texture || textureView)
{ {
CHAR strFileA[MAX_PATH]; CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_ACP, int result = WideCharToMultiByte(CP_ACP,
@ -1796,7 +1796,7 @@ HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice,
pstrName++; pstrName++;
} }
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName, (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)), static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
@ -1804,7 +1804,7 @@ HRESULT DirectX::CreateDDSTextureFromFileEx(ID3D11Device* d3dDevice,
); );
} }
if (textureView != 0 && *textureView != 0) if (textureView && *textureView)
{ {
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName, (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)), static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),

View File

@ -930,13 +930,10 @@ namespace
size_t d = depth; size_t d = depth;
for (size_t i = 0; i < mipCount; i++) for (size_t i = 0; i < mipCount; i++)
{ {
GetSurfaceInfo(w, GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
h,
format, if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX)
&NumBytes, return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
&RowBytes,
nullptr
);
if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize)) if ((mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize))
{ {
@ -1040,7 +1037,7 @@ namespace
IID_PPV_ARGS(texture)); IID_PPV_ARGS(texture));
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
_Analysis_assume_(*texture != 0); _Analysis_assume_(*texture != nullptr);
SetDebugObjectName(*texture, L"DDSTextureLoader"); SetDebugObjectName(*texture, L"DDSTextureLoader");
} }
@ -1434,7 +1431,7 @@ HRESULT DirectX::LoadDDSTextureFromMemoryEx(
texture, subresources, isCubeMap); texture, subresources, isCubeMap);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
SetDebugObjectName(*texture, L"DDSTextureLoader"); SetDebugObjectName(*texture, L"DDSTextureLoader");
} }
@ -1526,7 +1523,7 @@ HRESULT DirectX::LoadDDSTextureFromFileEx(
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
#if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #if !defined(NO_D3D12_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (texture != 0) if (texture)
{ {
CHAR strFileA[MAX_PATH]; CHAR strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_ACP, int result = WideCharToMultiByte(CP_ACP,
@ -1550,7 +1547,7 @@ HRESULT DirectX::LoadDDSTextureFromFileEx(
pstrName++; pstrName++;
} }
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
(*texture)->SetName(pstrName); (*texture)->SetName(pstrName);
} }

View File

@ -629,7 +629,7 @@ namespace
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
ComPtr<ID3D11Texture2D> pTemp; ComPtr<ID3D11Texture2D> pTemp;
hr = d3dDevice->CreateTexture2D( &desc, 0, pTemp.GetAddressOf() ); hr = d3dDevice->CreateTexture2D( &desc, nullptr, pTemp.GetAddressOf() );
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
@ -659,7 +659,7 @@ namespace
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.Usage = D3D11_USAGE_STAGING; desc.Usage = D3D11_USAGE_STAGING;
hr = d3dDevice->CreateTexture2D(&desc, 0, pStaging.ReleaseAndGetAddressOf()); hr = d3dDevice->CreateTexture2D(&desc, nullptr, pStaging.ReleaseAndGetAddressOf());
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
@ -680,7 +680,7 @@ namespace
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.Usage = D3D11_USAGE_STAGING; desc.Usage = D3D11_USAGE_STAGING;
hr = d3dDevice->CreateTexture2D(&desc, 0, pStaging.ReleaseAndGetAddressOf()); hr = d3dDevice->CreateTexture2D(&desc, nullptr, pStaging.ReleaseAndGetAddressOf());
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
@ -745,9 +745,11 @@ namespace
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, _Use_decl_annotations_
_In_ ID3D11Resource* pSource, HRESULT DirectX::SaveDDSTextureToFile(
_In_z_ const wchar_t* fileName ) ID3D11DeviceContext* pContext,
ID3D11Resource* pSource,
const wchar_t* fileName )
{ {
if ( !fileName ) if ( !fileName )
return E_INVALIDARG; return E_INVALIDARG;
@ -834,7 +836,7 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) ); memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) );
headerSize += sizeof(DDS_HEADER_DXT10); headerSize += sizeof(DDS_HEADER_DXT10);
extHeader = reinterpret_cast<DDS_HEADER_DXT10*>( reinterpret_cast<uint8_t*>(&fileHeader[0]) + sizeof(uint32_t) + sizeof(DDS_HEADER) ); extHeader = reinterpret_cast<DDS_HEADER_DXT10*>( fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER) );
memset( extHeader, 0, sizeof(DDS_HEADER_DXT10) ); memset( extHeader, 0, sizeof(DDS_HEADER_DXT10) );
extHeader->dxgiFormat = desc.Format; extHeader->dxgiFormat = desc.Format;
extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; extHeader->resourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
@ -845,6 +847,9 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
size_t rowPitch, slicePitch, rowCount; size_t rowPitch, slicePitch, rowCount;
GetSurfaceInfo( desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount ); GetSurfaceInfo( desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount );
if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
if ( IsCompressed( desc.Format ) ) if ( IsCompressed( desc.Format ) )
{ {
header->flags |= DDS_HEADER_FLAGS_LINEARSIZE; header->flags |= DDS_HEADER_FLAGS_LINEARSIZE;
@ -866,7 +871,7 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
auto sptr = reinterpret_cast<const uint8_t*>( mapped.pData ); auto sptr = static_cast<const uint8_t*>( mapped.pData );
if ( !sptr ) if ( !sptr )
{ {
pContext->Unmap( pStaging.Get(), 0 ); pContext->Unmap( pStaging.Get(), 0 );
@ -905,12 +910,14 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
} }
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, _Use_decl_annotations_
_In_ ID3D11Resource* pSource, HRESULT DirectX::SaveWICTextureToFile(
_In_ REFGUID guidContainerFormat, ID3D11DeviceContext* pContext,
_In_z_ const wchar_t* fileName, ID3D11Resource* pSource,
_In_opt_ const GUID* targetFormat, REFGUID guidContainerFormat,
_In_opt_ std::function<void(IPropertyBag2*)> setCustomProps ) const wchar_t* fileName,
const GUID* targetFormat,
std::function<void(IPropertyBag2*)> setCustomProps )
{ {
if ( !fileName ) if ( !fileName )
return E_INVALIDARG; return E_INVALIDARG;
@ -1037,7 +1044,7 @@ HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext,
} }
else else
{ {
// Screenshots dont typically include the alpha channel of the render target // Screenshots don't typically include the alpha channel of the render target
switch ( desc.Format ) switch ( desc.Format )
{ {
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
@ -1141,7 +1148,7 @@ HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext,
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory( desc.Width, desc.Height, pfGuid, hr = pWIC->CreateBitmapFromMemory( desc.Width, desc.Height, pfGuid,
mapped.RowPitch, mapped.RowPitch * desc.Height, mapped.RowPitch, mapped.RowPitch * desc.Height,
reinterpret_cast<BYTE*>( mapped.pData ), source.GetAddressOf() ); static_cast<BYTE*>( mapped.pData ), source.GetAddressOf() );
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
pContext->Unmap( pStaging.Get(), 0 ); pContext->Unmap( pStaging.Get(), 0 );
@ -1181,7 +1188,7 @@ HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext,
else else
{ {
// No conversion required // No conversion required
hr = frame->WritePixels( desc.Height, mapped.RowPitch, mapped.RowPitch * desc.Height, reinterpret_cast<BYTE*>( mapped.pData ) ); hr = frame->WritePixels( desc.Height, mapped.RowPitch, mapped.RowPitch * desc.Height, static_cast<BYTE*>( mapped.pData ) );
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
} }

View File

@ -601,8 +601,8 @@ namespace
_In_ D3D12_RESOURCE_STATES stateBefore, _In_ D3D12_RESOURCE_STATES stateBefore,
_In_ D3D12_RESOURCE_STATES stateAfter) _In_ D3D12_RESOURCE_STATES stateAfter)
{ {
assert(commandList != 0); assert(commandList != nullptr);
assert(resource != 0); assert(resource != nullptr);
if (stateBefore == stateAfter) if (stateBefore == stateAfter)
return; return;
@ -634,6 +634,9 @@ namespace
if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D) if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
if (srcPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format); UINT numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format);
if (numberOfPlanes != 1) if (numberOfPlanes != 1)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
@ -711,7 +714,7 @@ namespace
DXGI_FORMAT fmt = EnsureNotTypeless(desc.Format); DXGI_FORMAT fmt = EnsureNotTypeless(desc.Format);
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatInfo = { fmt }; D3D12_FEATURE_DATA_FORMAT_SUPPORT formatInfo = { fmt, D3D12_FORMAT_SUPPORT1_NONE, D3D12_FORMAT_SUPPORT2_NONE };
hr = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatInfo, sizeof(formatInfo)); hr = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatInfo, sizeof(formatInfo));
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -769,7 +772,7 @@ namespace
return hr; return hr;
// Execute the command list // Execute the command list
pCommandQ->ExecuteCommandLists(1, (ID3D12CommandList**)commandList.GetAddressOf()); pCommandQ->ExecuteCommandLists(1, CommandListCast(commandList.GetAddressOf()));
// Signal the fence // Signal the fence
hr = pCommandQ->Signal(fence.Get(), 1); hr = pCommandQ->Signal(fence.Get(), 1);
@ -806,7 +809,8 @@ namespace
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ, HRESULT DirectX::SaveDDSTextureToFile(
ID3D12CommandQueue* pCommandQ,
ID3D12Resource* pSource, ID3D12Resource* pSource,
const wchar_t* fileName, const wchar_t* fileName,
D3D12_RESOURCE_STATES beforeState, D3D12_RESOURCE_STATES beforeState,
@ -819,7 +823,11 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
pCommandQ->GetDevice(IID_PPV_ARGS(device.GetAddressOf())); pCommandQ->GetDevice(IID_PPV_ARGS(device.GetAddressOf()));
// Get the size of the image // Get the size of the image
D3D12_RESOURCE_DESC desc = pSource->GetDesc(); const auto desc = pSource->GetDesc();
if (desc.Width > UINT32_MAX)
return E_INVALIDARG;
UINT64 totalResourceSize = 0; UINT64 totalResourceSize = 0;
UINT64 fpRowPitch = 0; UINT64 fpRowPitch = 0;
UINT fpRowCount = 0; UINT fpRowCount = 0;
@ -837,6 +845,9 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
// Round up the srcPitch to multiples of 256 // Round up the srcPitch to multiples of 256
UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFF; UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFF;
if (dstRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture( device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState ); HRESULT hr = CaptureTexture( device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState );
if ( FAILED(hr) ) if ( FAILED(hr) )
@ -861,7 +872,7 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
header->size = sizeof( DDS_HEADER ); header->size = sizeof( DDS_HEADER );
header->flags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP; header->flags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP;
header->height = desc.Height; header->height = desc.Height;
header->width = (uint32_t) desc.Width; header->width = static_cast<uint32_t>(desc.Width);
header->mipMapCount = 1; header->mipMapCount = 1;
header->caps = DDS_SURFACE_FLAGS_TEXTURE; header->caps = DDS_SURFACE_FLAGS_TEXTURE;
@ -914,7 +925,7 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) ); memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) );
headerSize += sizeof(DDS_HEADER_DXT10); headerSize += sizeof(DDS_HEADER_DXT10);
extHeader = reinterpret_cast<DDS_HEADER_DXT10*>( reinterpret_cast<uint8_t*>(&fileHeader[0]) + sizeof(uint32_t) + sizeof(DDS_HEADER) ); extHeader = reinterpret_cast<DDS_HEADER_DXT10*>(fileHeader + sizeof(uint32_t) + sizeof(DDS_HEADER) );
memset( extHeader, 0, sizeof(DDS_HEADER_DXT10) ); memset( extHeader, 0, sizeof(DDS_HEADER_DXT10) );
extHeader->dxgiFormat = desc.Format; extHeader->dxgiFormat = desc.Format;
extHeader->resourceDimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; extHeader->resourceDimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
@ -923,7 +934,10 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
} }
size_t rowPitch, slicePitch, rowCount; size_t rowPitch, slicePitch, rowCount;
GetSurfaceInfo( (size_t)desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount ); GetSurfaceInfo(static_cast<size_t>(desc.Width), desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount);
if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
if ( IsCompressed( desc.Format ) ) if ( IsCompressed( desc.Format ) )
{ {
@ -944,14 +958,18 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
assert(fpRowCount == rowCount); assert(fpRowCount == rowCount);
assert(fpRowPitch == rowPitch); assert(fpRowPitch == rowPitch);
void* pMappedMemory; UINT64 imageSize = dstRowPitch * UINT64(rowCount);
D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(dstRowPitch * rowCount) }; if (imageSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
void* pMappedMemory = nullptr;
D3D12_RANGE readRange = { 0, static_cast<SIZE_T>(imageSize) };
D3D12_RANGE writeRange = { 0, 0 }; D3D12_RANGE writeRange = { 0, 0 };
hr = pStaging->Map(0, &readRange, &pMappedMemory ); hr = pStaging->Map(0, &readRange, &pMappedMemory );
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
auto sptr = reinterpret_cast<const uint8_t*>(pMappedMemory); auto sptr = static_cast<const uint8_t*>(pMappedMemory);
if ( !sptr ) if ( !sptr )
{ {
pStaging->Unmap(0, &writeRange); pStaging->Unmap(0, &writeRange);
@ -991,7 +1009,8 @@ HRESULT DirectX::SaveDDSTextureToFile( ID3D12CommandQueue* pCommandQ,
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
_Use_decl_annotations_ _Use_decl_annotations_
HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ, HRESULT DirectX::SaveWICTextureToFile(
ID3D12CommandQueue* pCommandQ,
ID3D12Resource* pSource, ID3D12Resource* pSource,
REFGUID guidContainerFormat, REFGUID guidContainerFormat,
const wchar_t* fileName, const wchar_t* fileName,
@ -1007,7 +1026,11 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
pCommandQ->GetDevice(IID_PPV_ARGS(device.GetAddressOf())); pCommandQ->GetDevice(IID_PPV_ARGS(device.GetAddressOf()));
// Get the size of the image // Get the size of the image
D3D12_RESOURCE_DESC desc = pSource->GetDesc(); const auto desc = pSource->GetDesc();
if (desc.Width > UINT32_MAX)
return E_INVALIDARG;
UINT64 totalResourceSize = 0; UINT64 totalResourceSize = 0;
UINT64 fpRowPitch = 0; UINT64 fpRowPitch = 0;
UINT fpRowCount = 0; UINT fpRowCount = 0;
@ -1025,6 +1048,9 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
// Round up the srcPitch to multiples of 256 // Round up the srcPitch to multiples of 256
UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFF; UINT64 dstRowPitch = (fpRowPitch + 255) & ~0xFF;
if (dstRowPitch > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState);
if (FAILED(hr)) if (FAILED(hr))
@ -1146,7 +1172,7 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
} }
else else
{ {
// Screenshots dont typically include the alpha channel of the render target // Screenshots don't typically include the alpha channel of the render target
switch ( desc.Format ) switch ( desc.Format )
{ {
case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R32G32B32A32_FLOAT:
@ -1230,8 +1256,12 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
} }
} }
void* pMappedMemory; UINT64 imageSize = dstRowPitch * UINT64(desc.Height);
D3D12_RANGE readRange = {0, static_cast<SIZE_T>(dstRowPitch * desc.Height)}; if (imageSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
void* pMappedMemory = nullptr;
D3D12_RANGE readRange = {0, static_cast<SIZE_T>(imageSize)};
D3D12_RANGE writeRange = {0, 0}; D3D12_RANGE writeRange = {0, 0};
hr = pStaging->Map(0, &readRange, &pMappedMemory); hr = pStaging->Map(0, &readRange, &pMappedMemory);
if (FAILED(hr)) if (FAILED(hr))
@ -1242,8 +1272,8 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
// Conversion required to write // Conversion required to write
ComPtr<IWICBitmap> source; ComPtr<IWICBitmap> source;
hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(desc.Width), desc.Height, pfGuid, hr = pWIC->CreateBitmapFromMemory(static_cast<UINT>(desc.Width), desc.Height, pfGuid,
static_cast<UINT>(dstRowPitch), static_cast<UINT>(dstRowPitch * desc.Height), static_cast<UINT>(dstRowPitch), static_cast<UINT>(imageSize),
reinterpret_cast<BYTE*>(pMappedMemory), source.GetAddressOf() ); static_cast<BYTE*>(pMappedMemory), source.GetAddressOf() );
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
pStaging->Unmap( 0, &writeRange ); pStaging->Unmap( 0, &writeRange );
@ -1283,7 +1313,7 @@ HRESULT DirectX::SaveWICTextureToFile( ID3D12CommandQueue* pCommandQ,
else else
{ {
// No conversion required // No conversion required
hr = frame->WritePixels( desc.Height, static_cast<UINT>(dstRowPitch), static_cast<UINT>(dstRowPitch * desc.Height), reinterpret_cast<BYTE*>( pMappedMemory ) ); hr = frame->WritePixels( desc.Height, static_cast<UINT>(dstRowPitch), static_cast<UINT>(imageSize), static_cast<BYTE*>( pMappedMemory ) );
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
} }

View File

@ -311,6 +311,9 @@ namespace
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
if (maxsize > UINT32_MAX)
return E_INVALIDARG;
assert(width > 0 && height > 0); assert(width > 0 && height > 0);
if (!maxsize) if (!maxsize)
@ -421,7 +424,7 @@ namespace
} }
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
if ((format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0) if ((format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext && textureView)
{ {
// Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT
UINT fmtSupport = 0; UINT fmtSupport = 0;
@ -492,8 +495,14 @@ namespace
} }
// Allocate temporary memory for image // Allocate temporary memory for image
size_t rowPitch = (twidth * bpp + 7) / 8; uint64_t rowBytes = (uint64_t(twidth) * uint64_t(bpp) + 7u) / 8u;
size_t imageSize = rowPitch * theight; uint64_t numBytes = rowBytes * uint64_t(height);
if (rowBytes > UINT32_MAX || numBytes > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
auto rowPitch = static_cast<size_t>(rowBytes);
auto imageSize = static_cast<size_t>(numBytes);
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[imageSize]); std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[imageSize]);
if (!temp) if (!temp)
@ -590,7 +599,7 @@ namespace
// See if format is supported for auto-gen mipmaps (varies by feature level) // See if format is supported for auto-gen mipmaps (varies by feature level)
bool autogen = false; bool autogen = false;
if (d3dContext != 0 && textureView != 0) // Must have context and shader-view to auto generate mipmaps if (d3dContext && textureView) // Must have context and shader-view to auto generate mipmaps
{ {
UINT fmtSupport = 0; UINT fmtSupport = 0;
hr = d3dDevice->CheckFormatSupport(format, &fmtSupport); hr = d3dDevice->CheckFormatSupport(format, &fmtSupport);
@ -630,9 +639,9 @@ namespace
ID3D11Texture2D* tex = nullptr; ID3D11Texture2D* tex = nullptr;
hr = d3dDevice->CreateTexture2D(&desc, (autogen) ? nullptr : &initData, &tex); hr = d3dDevice->CreateTexture2D(&desc, (autogen) ? nullptr : &initData, &tex);
if (SUCCEEDED(hr) && tex != 0) if (SUCCEEDED(hr) && tex)
{ {
if (textureView != 0) if (textureView)
{ {
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = {};
SRVDesc.Format = desc.Format; SRVDesc.Format = desc.Format;
@ -649,13 +658,13 @@ namespace
if (autogen) if (autogen)
{ {
assert(d3dContext != 0); assert(d3dContext != nullptr);
d3dContext->UpdateSubresource(tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize)); d3dContext->UpdateSubresource(tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize));
d3dContext->GenerateMips(*textureView); d3dContext->GenerateMips(*textureView);
} }
} }
if (texture != 0) if (texture)
{ {
*texture = tex; *texture = tex;
} }
@ -779,12 +788,12 @@ HRESULT DirectX::CreateWICTextureFromMemoryEx(ID3D11Device* d3dDevice,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
SetDebugObjectName(*texture, "WICTextureLoader"); SetDebugObjectName(*texture, "WICTextureLoader");
} }
if (textureView != 0 && *textureView != 0) if (textureView && *textureView)
{ {
SetDebugObjectName(*textureView, "WICTextureLoader"); SetDebugObjectName(*textureView, "WICTextureLoader");
} }
@ -882,7 +891,7 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (texture != 0 || textureView != 0) if (texture || textureView)
{ {
char strFileA[MAX_PATH]; char strFileA[MAX_PATH];
int result = WideCharToMultiByte(CP_ACP, int result = WideCharToMultiByte(CP_ACP,
@ -906,7 +915,7 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
pstrName++; pstrName++;
} }
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName, (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)), static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
@ -914,7 +923,7 @@ HRESULT DirectX::CreateWICTextureFromFileEx(ID3D11Device* d3dDevice,
); );
} }
if (textureView != 0 && *textureView != 0) if (textureView && *textureView)
{ {
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName, (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)), static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),

View File

@ -278,13 +278,14 @@ namespace
assert(width > 0 && height > 0); assert(width > 0 && height > 0);
if (maxsize > UINT32_MAX)
return E_INVALIDARG;
if (!maxsize) if (!maxsize)
{ {
maxsize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; maxsize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
} }
assert(maxsize > 0);
UINT twidth, theight; UINT twidth, theight;
if (width > maxsize || height > maxsize) if (width > maxsize || height > maxsize)
{ {
@ -386,8 +387,14 @@ namespace
} }
// Allocate memory for decoded image // Allocate memory for decoded image
size_t rowPitch = (twidth * bpp + 7) / 8; uint64_t rowBytes = (uint64_t(twidth) * uint64_t(bpp) + 7u) / 8u;
size_t imageSize = rowPitch * theight; uint64_t numBytes = rowBytes * uint64_t(height);
if (rowBytes > UINT32_MAX || numBytes > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
auto rowPitch = static_cast<size_t>(rowBytes);
auto imageSize = static_cast<size_t>(numBytes);
decodedData.reset(new (std::nothrow) uint8_t[imageSize]); decodedData.reset(new (std::nothrow) uint8_t[imageSize]);
if (!decodedData) if (!decodedData)
@ -489,7 +496,7 @@ namespace
D3D12_RESOURCE_DESC desc = {}; D3D12_RESOURCE_DESC desc = {};
desc.Width = twidth; desc.Width = twidth;
desc.Height = theight; desc.Height = theight;
desc.MipLevels = (uint16_t)mipCount; desc.MipLevels = static_cast<UINT16>(mipCount);
desc.DepthOrArraySize = 1; desc.DepthOrArraySize = 1;
desc.Format = format; desc.Format = format;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
@ -513,7 +520,7 @@ namespace
return hr; return hr;
} }
_Analysis_assume_(tex != 0); _Analysis_assume_(tex != nullptr);
subresource.pData = decodedData.get(); subresource.pData = decodedData.get();
subresource.RowPitch = rowPitch; subresource.RowPitch = rowPitch;
@ -689,7 +696,7 @@ HRESULT DirectX::LoadWICTextureFromFileEx(
pstrName++; pstrName++;
} }
if (texture != 0 && *texture != 0) if (texture && *texture)
{ {
(*texture)->SetName(pstrName); (*texture)->SetName(pstrName);
} }