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:
@@ -434,17 +434,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,
|
||||
_Out_opt_ 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;
|
||||
@@ -458,7 +458,7 @@ namespace
|
||||
case DXGI_FORMAT_BC4_TYPELESS:
|
||||
case DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT_BC4_SNORM:
|
||||
bc=true;
|
||||
bc = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
@@ -505,19 +505,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;
|
||||
@@ -525,42 +528,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -845,7 +861,9 @@ HRESULT DirectX::SaveDDSTextureToFile(
|
||||
}
|
||||
|
||||
size_t rowPitch, slicePitch, rowCount;
|
||||
GetSurfaceInfo( desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount );
|
||||
hr = GetSurfaceInfo( desc.Width, desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount );
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
|
||||
@@ -325,6 +325,7 @@ namespace
|
||||
|
||||
case DXGI_FORMAT_P010:
|
||||
case DXGI_FORMAT_P016:
|
||||
case DXGI_FORMAT_V408:
|
||||
return 24;
|
||||
|
||||
case DXGI_FORMAT_R8G8_TYPELESS:
|
||||
@@ -343,6 +344,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:
|
||||
@@ -434,17 +437,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,
|
||||
_Out_opt_ 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;
|
||||
@@ -458,7 +461,7 @@ namespace
|
||||
case DXGI_FORMAT_BC4_TYPELESS:
|
||||
case DXGI_FORMAT_BC4_UNORM:
|
||||
case DXGI_FORMAT_BC4_SNORM:
|
||||
bc=true;
|
||||
bc = true;
|
||||
bpe = 8;
|
||||
break;
|
||||
|
||||
@@ -496,6 +499,7 @@ namespace
|
||||
|
||||
case DXGI_FORMAT_NV12:
|
||||
case DXGI_FORMAT_420_OPAQUE:
|
||||
case DXGI_FORMAT_P208:
|
||||
planar = true;
|
||||
bpe = 2;
|
||||
break;
|
||||
@@ -505,19 +509,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;
|
||||
@@ -525,42 +532,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -934,7 +954,9 @@ HRESULT DirectX::SaveDDSTextureToFile(
|
||||
}
|
||||
|
||||
size_t rowPitch, slicePitch, rowCount;
|
||||
GetSurfaceInfo(static_cast<size_t>(desc.Width), desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount);
|
||||
hr = GetSurfaceInfo(static_cast<size_t>(desc.Width), desc.Height, desc.Format, &slicePitch, &rowPitch, &rowCount);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (rowPitch > UINT32_MAX || slicePitch > UINT32_MAX)
|
||||
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
|
||||
|
||||
Reference in New Issue
Block a user