mirror of
https://github.com/microsoft/DirectXTex.git
synced 2026-02-04 04:16:12 +01:00
ComputePitch now returns an HRESULT (#113)
This commit is contained in:
@@ -406,7 +406,7 @@ namespace
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Get surface information for a particular format
|
||||
//--------------------------------------------------------------------------------------
|
||||
void GetSurfaceInfo(
|
||||
HRESULT GetSurfaceInfo(
|
||||
_In_ size_t width,
|
||||
_In_ size_t height,
|
||||
_In_ DXGI_FORMAT fmt,
|
||||
@@ -414,9 +414,9 @@ namespace
|
||||
_Out_opt_ size_t* outRowBytes,
|
||||
_Out_opt_ size_t* outNumRows)
|
||||
{
|
||||
size_t numBytes = 0;
|
||||
size_t rowBytes = 0;
|
||||
size_t numRows = 0;
|
||||
uint64_t numBytes = 0;
|
||||
uint64_t rowBytes = 0;
|
||||
uint64_t numRows = 0;
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
@@ -477,19 +477,22 @@ namespace
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bc)
|
||||
{
|
||||
size_t numBlocksWide = 0;
|
||||
uint64_t numBlocksWide = 0;
|
||||
if (width > 0)
|
||||
{
|
||||
numBlocksWide = std::max<size_t>(1, (width + 3) / 4);
|
||||
numBlocksWide = std::max<uint64_t>(1u, (uint64_t(width) + 3u) / 4u);
|
||||
}
|
||||
size_t numBlocksHigh = 0;
|
||||
uint64_t numBlocksHigh = 0;
|
||||
if (height > 0)
|
||||
{
|
||||
numBlocksHigh = std::max<size_t>(1, (height + 3) / 4);
|
||||
numBlocksHigh = std::max<uint64_t>(1u, (uint64_t(height) + 3u) / 4u);
|
||||
}
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
@@ -497,42 +500,55 @@ namespace
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = ((width + 1) >> 1) * bpe;
|
||||
numRows = height;
|
||||
rowBytes = ((uint64_t(width) + 1u) >> 1) * bpe;
|
||||
numRows = uint64_t(height);
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if (fmt == DXGI_FORMAT_NV11)
|
||||
{
|
||||
rowBytes = ((width + 3) >> 2) * 4;
|
||||
numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
rowBytes = ((uint64_t(width) + 3u) >> 2) * 4u;
|
||||
numRows = uint64_t(height) * 2u; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
numBytes = rowBytes * numRows;
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ((width + 1) >> 1) * bpe;
|
||||
numBytes = (rowBytes * height) + ((rowBytes * height + 1) >> 1);
|
||||
numRows = height + ((height + 1) >> 1);
|
||||
rowBytes = ((uint64_t(width) + 1u) >> 1) * bpe;
|
||||
numBytes = (rowBytes * uint64_t(height)) + ((rowBytes * uint64_t(height) + 1u) >> 1);
|
||||
numRows = height + ((uint64_t(height) + 1u) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bpp = BitsPerPixel(fmt);
|
||||
rowBytes = (width * bpp + 7) / 8; // round up to nearest byte
|
||||
numRows = height;
|
||||
if (!bpp)
|
||||
return E_INVALIDARG;
|
||||
|
||||
rowBytes = (uint64_t(width) * bpp + 7u) / 8u; // round up to nearest byte
|
||||
numRows = uint64_t(height);
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
|
||||
static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
|
||||
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
#else
|
||||
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
|
||||
#endif
|
||||
|
||||
if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = numBytes;
|
||||
*outNumBytes = static_cast<size_t>(numBytes);
|
||||
}
|
||||
if (outRowBytes)
|
||||
{
|
||||
*outRowBytes = rowBytes;
|
||||
*outRowBytes = static_cast<size_t>(rowBytes);
|
||||
}
|
||||
if (outNumRows)
|
||||
{
|
||||
*outNumRows = numRows;
|
||||
*outNumRows = static_cast<size_t>(numRows);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -851,7 +867,9 @@ namespace
|
||||
size_t d = depth;
|
||||
for (size_t i = 0; i < mipCount; i++)
|
||||
{
|
||||
GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
|
||||
HRESULT hr = GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
@@ -1357,7 +1375,9 @@ namespace
|
||||
{
|
||||
size_t numBytes = 0;
|
||||
size_t rowBytes = 0;
|
||||
GetSurfaceInfo(width, height, format, &numBytes, &rowBytes, nullptr);
|
||||
hr = GetSurfaceInfo(width, height, format, &numBytes, &rowBytes, nullptr);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (numBytes > bitSize)
|
||||
{
|
||||
|
||||
@@ -336,6 +336,7 @@ namespace
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
case DXGI_FORMAT_V408:
|
||||
return 24;
|
||||
|
||||
case DXGI_FORMAT_R8G8_TYPELESS:
|
||||
@@ -354,6 +355,8 @@ namespace
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||
case DXGI_FORMAT_A8P8:
|
||||
case DXGI_FORMAT_B4G4R4A4_UNORM:
|
||||
case DXGI_FORMAT_P208:
|
||||
case DXGI_FORMAT_V208:
|
||||
return 16;
|
||||
|
||||
case DXGI_FORMAT_NV12:
|
||||
@@ -409,17 +412,17 @@ namespace
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Get surface information for a particular format
|
||||
//--------------------------------------------------------------------------------------
|
||||
void GetSurfaceInfo(
|
||||
HRESULT GetSurfaceInfo(
|
||||
_In_ size_t width,
|
||||
_In_ size_t height,
|
||||
_In_ DXGI_FORMAT fmt,
|
||||
size_t* outNumBytes,
|
||||
_Out_opt_ size_t* outRowBytes,
|
||||
_Out_opt_ size_t* outNumRows )
|
||||
_Out_opt_ size_t* outNumRows)
|
||||
{
|
||||
size_t numBytes = 0;
|
||||
size_t rowBytes = 0;
|
||||
size_t numRows = 0;
|
||||
uint64_t numBytes = 0;
|
||||
uint64_t rowBytes = 0;
|
||||
uint64_t numRows = 0;
|
||||
|
||||
bool bc = false;
|
||||
bool packed = false;
|
||||
@@ -433,7 +436,7 @@ namespace
|
||||
case DXGI_FORMAT_BC4_TYPELESS:
|
||||
case DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT_BC4_SNORM:
|
||||
bc=true;
|
||||
bc = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
@@ -471,6 +474,7 @@ namespace
|
||||
|
||||
case DXGI_FORMAT_NV12:
|
||||
case DXGI_FORMAT_420_OPAQUE:
|
||||
case DXGI_FORMAT_P208:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
@@ -480,19 +484,22 @@ namespace
|
||||
planar = true;
|
||||
bpe = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bc)
|
||||
{
|
||||
size_t numBlocksWide = 0;
|
||||
uint64_t numBlocksWide = 0;
|
||||
if (width > 0)
|
||||
{
|
||||
numBlocksWide = std::max<size_t>( 1, (width + 3) / 4 );
|
||||
numBlocksWide = std::max<uint64_t>(1u, (uint64_t(width) + 3u) / 4u);
|
||||
}
|
||||
size_t numBlocksHigh = 0;
|
||||
uint64_t numBlocksHigh = 0;
|
||||
if (height > 0)
|
||||
{
|
||||
numBlocksHigh = std::max<size_t>( 1, (height + 3) / 4 );
|
||||
numBlocksHigh = std::max<uint64_t>(1u, (uint64_t(height) + 3u) / 4u);
|
||||
}
|
||||
rowBytes = numBlocksWide * bpe;
|
||||
numRows = numBlocksHigh;
|
||||
@@ -500,42 +507,55 @@ namespace
|
||||
}
|
||||
else if (packed)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numRows = height;
|
||||
rowBytes = ((uint64_t(width) + 1u) >> 1) * bpe;
|
||||
numRows = uint64_t(height);
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
else if ( fmt == DXGI_FORMAT_NV11 )
|
||||
else if (fmt == DXGI_FORMAT_NV11)
|
||||
{
|
||||
rowBytes = ( ( width + 3 ) >> 2 ) * 4;
|
||||
numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
rowBytes = ((uint64_t(width) + 3u) >> 2) * 4u;
|
||||
numRows = uint64_t(height) * 2u; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||
numBytes = rowBytes * numRows;
|
||||
}
|
||||
else if (planar)
|
||||
{
|
||||
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
|
||||
numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 );
|
||||
numRows = height + ( ( height + 1 ) >> 1 );
|
||||
rowBytes = ((uint64_t(width) + 1u) >> 1) * bpe;
|
||||
numBytes = (rowBytes * uint64_t(height)) + ((rowBytes * uint64_t(height) + 1u) >> 1);
|
||||
numRows = height + ((uint64_t(height) + 1u) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bpp = BitsPerPixel( fmt );
|
||||
rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
|
||||
numRows = height;
|
||||
size_t bpp = BitsPerPixel(fmt);
|
||||
if (!bpp)
|
||||
return E_INVALIDARG;
|
||||
|
||||
rowBytes = (uint64_t(width) * bpp + 7u) / 8u; // round up to nearest byte
|
||||
numRows = uint64_t(height);
|
||||
numBytes = rowBytes * height;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
|
||||
static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
|
||||
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
#else
|
||||
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
|
||||
#endif
|
||||
|
||||
if (outNumBytes)
|
||||
{
|
||||
*outNumBytes = numBytes;
|
||||
*outNumBytes = static_cast<size_t>(numBytes);
|
||||
}
|
||||
if (outRowBytes)
|
||||
{
|
||||
*outRowBytes = rowBytes;
|
||||
*outRowBytes = static_cast<size_t>(rowBytes);
|
||||
}
|
||||
if (outNumRows)
|
||||
{
|
||||
*outNumRows = numRows;
|
||||
*outNumRows = static_cast<size_t>(numRows);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -849,12 +869,6 @@ namespace
|
||||
case DXGI_FORMAT_NV12:
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
|
||||
#if defined(_XBOX_ONE) && defined(_TITLE)
|
||||
case DXGI_FORMAT_D16_UNORM_S8_UINT:
|
||||
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
|
||||
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
|
||||
#endif
|
||||
if (!slicePlane)
|
||||
{
|
||||
// Plane 0
|
||||
@@ -930,7 +944,9 @@ namespace
|
||||
size_t d = depth;
|
||||
for (size_t i = 0; i < mipCount; i++)
|
||||
{
|
||||
GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
|
||||
HRESULT hr = GetSurfaceInfo(w, h, format, &NumBytes, &RowBytes, nullptr);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (NumBytes > UINT32_MAX || RowBytes > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
|
||||
Reference in New Issue
Block a user