DXUT11: Sync DDSTextureLoader, ScreenGrab, and WICTextureLoader

This commit is contained in:
walbourn_cp 2014-02-24 17:42:19 -08:00
Родитель d32ce83c2b
Коммит 86e9be8edf
5 изменённых файлов: 592 добавлений и 82 удалений

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

@ -301,6 +301,9 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
case DXGI_FORMAT_Y416:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
return 64;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
@ -338,8 +341,15 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_AYUV:
case DXGI_FORMAT_Y410:
case DXGI_FORMAT_YUY2:
return 32;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
return 24;
case DXGI_FORMAT_R8G8_TYPELESS:
case DXGI_FORMAT_R8G8_UNORM:
case DXGI_FORMAT_R8G8_UINT:
@ -354,15 +364,24 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_R16_SINT:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_A8P8:
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 16;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_NV11:
return 12;
case DXGI_FORMAT_R8_TYPELESS:
case DXGI_FORMAT_R8_UNORM:
case DXGI_FORMAT_R8_UINT:
case DXGI_FORMAT_R8_SNORM:
case DXGI_FORMAT_R8_SINT:
case DXGI_FORMAT_A8_UNORM:
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
return 8;
case DXGI_FORMAT_R1_UNORM:
@ -393,6 +412,21 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_BC7_UNORM_SRGB:
return 8;
#if defined(_XBOX_ONE) && defined(_TITLE)
case DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT:
case DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT:
return 32;
#if MONOLITHIC
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
return 24;
#endif
#endif // _XBOX_ONE && _TITLE
default:
return 0;
}
@ -414,8 +448,9 @@ static void GetSurfaceInfo( _In_ size_t width,
size_t numRows = 0;
bool bc = false;
bool packed = false;
size_t bcnumBytesPerBlock = 0;
bool packed = false;
bool planar = false;
size_t bpe = 0;
switch (fmt)
{
case DXGI_FORMAT_BC1_TYPELESS:
@ -425,7 +460,7 @@ static void GetSurfaceInfo( _In_ size_t width,
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
bc=true;
bcnumBytesPerBlock = 8;
bpe = 8;
break;
case DXGI_FORMAT_BC2_TYPELESS:
@ -444,13 +479,44 @@ static void GetSurfaceInfo( _In_ size_t width,
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
bc = true;
bcnumBytesPerBlock = 16;
bpe = 16;
break;
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM:
case DXGI_FORMAT_YUY2:
packed = true;
bpe = 4;
break;
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
packed = true;
bpe = 8;
break;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
planar = true;
bpe = 2;
break;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
planar = true;
bpe = 4;
break;
#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
planar = true;
bpe = 4;
break;
#endif
}
if (bc)
@ -465,22 +531,36 @@ static void GetSurfaceInfo( _In_ size_t width,
{
numBlocksHigh = std::max<size_t>( 1, (height + 3) / 4 );
}
rowBytes = numBlocksWide * bcnumBytesPerBlock;
rowBytes = numBlocksWide * bpe;
numRows = numBlocksHigh;
numBytes = rowBytes * numBlocksHigh;
}
else if (packed)
{
rowBytes = ( ( width + 1 ) >> 1 ) * 4;
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
numRows = 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
numBytes = rowBytes * numRows;
}
else if (planar)
{
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 );
numRows = height + ( ( height + 1 ) >> 1 );
}
else
{
size_t bpp = BitsPerPixel( fmt );
rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
numRows = height;
numBytes = rowBytes * height;
}
numBytes = rowBytes * numRows;
if (outNumBytes)
{
*outNumBytes = numBytes;
@ -672,6 +752,11 @@ static DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf )
return DXGI_FORMAT_G8R8_G8B8_UNORM;
}
if (MAKEFOURCC('Y','U','Y','2') == ddpf.fourCC)
{
return DXGI_FORMAT_YUY2;
}
// Check for D3DFORMAT enums being set here
switch( ddpf.fourCC )
{
@ -765,7 +850,6 @@ static HRESULT FillInitData( _In_ size_t width,
size_t NumBytes = 0;
size_t RowBytes = 0;
size_t NumRows = 0;
const uint8_t* pSrcBits = bitData;
const uint8_t* pEndBits = bitData + bitSize;
@ -782,7 +866,7 @@ static HRESULT FillInitData( _In_ size_t width,
format,
&NumBytes,
&RowBytes,
&NumRows
nullptr
);
if ( (mipCount <= 1) || !maxsize || (w <= maxsize && h <= maxsize && d <= maxsize) )
@ -851,11 +935,11 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
_In_ unsigned int miscFlags,
_In_ bool forceSRGB,
_In_ bool isCubeMap,
_In_reads_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData,
_In_reads_opt_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData,
_Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView )
{
if ( !d3dDevice || !initData )
if ( !d3dDevice )
return E_POINTER;
HRESULT hr = E_FAIL;
@ -895,13 +979,13 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
if (arraySize > 1)
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
SRVDesc.Texture1DArray.MipLevels = desc.MipLevels;
SRVDesc.Texture1DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
SRVDesc.Texture1DArray.ArraySize = static_cast<UINT>( arraySize );
}
else
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
SRVDesc.Texture1D.MipLevels = desc.MipLevels;
SRVDesc.Texture1D.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
}
hr = d3dDevice->CreateShaderResourceView( tex,
@ -968,7 +1052,7 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
if (arraySize > 6)
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
SRVDesc.TextureCubeArray.MipLevels = desc.MipLevels;
SRVDesc.TextureCubeArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
// Earlier we set arraySize to (NumCubes * 6)
SRVDesc.TextureCubeArray.NumCubes = static_cast<UINT>( arraySize / 6 );
@ -976,19 +1060,19 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
else
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SRVDesc.TextureCube.MipLevels = desc.MipLevels;
SRVDesc.TextureCube.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
}
}
else if (arraySize > 1)
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
SRVDesc.Texture2DArray.MipLevels = desc.MipLevels;
SRVDesc.Texture2DArray.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
SRVDesc.Texture2DArray.ArraySize = static_cast<UINT>( arraySize );
}
else
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = desc.MipLevels;
SRVDesc.Texture2D.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
}
hr = d3dDevice->CreateShaderResourceView( tex,
@ -1042,7 +1126,7 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
SRVDesc.Format = format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
SRVDesc.Texture3D.MipLevels = desc.MipLevels;
SRVDesc.Texture3D.MipLevels = (!mipCount) ? -1 : desc.MipLevels;
hr = d3dDevice->CreateShaderResourceView( tex,
&SRVDesc,
@ -1075,6 +1159,7 @@ static HRESULT CreateD3DResources( _In_ ID3D11Device* d3dDevice,
//--------------------------------------------------------------------------------------
static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_ const DDS_HEADER* header,
_In_reads_bytes_(bitSize) const uint8_t* bitData,
_In_ size_t bitSize,
@ -1115,9 +1200,19 @@ static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice,
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
}
if (BitsPerPixel( d3d10ext->dxgiFormat ) == 0)
switch( d3d10ext->dxgiFormat )
{
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8:
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
default:
if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 )
{
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
}
}
format = d3d10ext->dxgiFormat;
@ -1242,65 +1337,165 @@ static HRESULT CreateTextureFromDDS( _In_ ID3D11Device* d3dDevice,
break;
}
// Create the texture
std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] );
if ( !initData )
bool autogen = false;
if ( mipCount == 1 && d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps
{
return E_OUTOFMEMORY;
// See if format is supported for auto-gen mipmaps (varies by feature level)
UINT fmtSupport = 0;
hr = d3dDevice->CheckFormatSupport( format, &fmtSupport );
if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) )
{
// 10level9 feature levels do not support auto-gen mipgen for volume textures
if ( ( resDim != D3D11_RESOURCE_DIMENSION_TEXTURE3D )
|| ( d3dDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ) )
{
autogen = true;
}
}
}
size_t skipMip = 0;
size_t twidth = 0;
size_t theight = 0;
size_t tdepth = 0;
hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, initData.get() );
if ( SUCCEEDED(hr) )
if ( autogen )
{
hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
isCubeMap, initData.get(), texture, textureView );
if ( FAILED(hr) && !maxsize && (mipCount > 1) )
// Create texture with auto-generated mipmaps
ID3D11Resource* tex = nullptr;
hr = CreateD3DResources( d3dDevice, resDim, width, height, depth, 0, arraySize,
format, usage,
bindFlags | D3D11_BIND_RENDER_TARGET,
cpuAccessFlags,
miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS, forceSRGB,
isCubeMap, nullptr, &tex, textureView );
if ( SUCCEEDED(hr) )
{
// Retry with a maxsize determined by feature level
switch( d3dDevice->GetFeatureLevel() )
size_t numBytes = 0;
size_t rowBytes = 0;
GetSurfaceInfo( width, height, format, &numBytes, &rowBytes, nullptr );
if ( numBytes > bitSize )
{
case D3D_FEATURE_LEVEL_9_1:
case D3D_FEATURE_LEVEL_9_2:
if ( isCubeMap )
{
maxsize = 512 /*D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION*/;
}
else
{
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
}
break;
case D3D_FEATURE_LEVEL_9_3:
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
default: // D3D_FEATURE_LEVEL_10_0 & D3D_FEATURE_LEVEL_10_1
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 2048 /*D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
(*textureView)->Release();
*textureView = nullptr;
tex->Release();
return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF );
}
hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, initData.get() );
if ( SUCCEEDED(hr) )
if ( arraySize > 1 )
{
hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
isCubeMap, initData.get(), texture, textureView );
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
(*textureView)->GetDesc( &desc );
UINT mipLevels = 1;
switch( desc.ViewDimension )
{
case D3D_SRV_DIMENSION_TEXTURE1D: mipLevels = desc.Texture1D.MipLevels; break;
case D3D_SRV_DIMENSION_TEXTURE1DARRAY: mipLevels = desc.Texture1DArray.MipLevels; break;
case D3D_SRV_DIMENSION_TEXTURE2D: mipLevels = desc.Texture2D.MipLevels; break;
case D3D_SRV_DIMENSION_TEXTURE2DARRAY: mipLevels = desc.Texture2DArray.MipLevels; break;
case D3D_SRV_DIMENSION_TEXTURECUBE: mipLevels = desc.TextureCube.MipLevels; break;
case D3D_SRV_DIMENSION_TEXTURECUBEARRAY:mipLevels = desc.TextureCubeArray.MipLevels; break;
default:
(*textureView)->Release();
*textureView = nullptr;
tex->Release();
return E_UNEXPECTED;
}
const uint8_t* pSrcBits = bitData;
const uint8_t* pEndBits = bitData + bitSize;
for( UINT item = 0; item < arraySize; ++item )
{
if ( (pSrcBits + numBytes) > pEndBits )
{
(*textureView)->Release();
*textureView = nullptr;
tex->Release();
return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF );
}
UINT res = D3D11CalcSubresource( 0, item, mipLevels );
d3dContext->UpdateSubresource( tex, res, nullptr, pSrcBits, static_cast<UINT>(rowBytes), static_cast<UINT>(numBytes) );
pSrcBits += numBytes;
}
}
else
{
d3dContext->UpdateSubresource( tex, 0, nullptr, bitData, static_cast<UINT>(rowBytes), static_cast<UINT>(numBytes) );
}
d3dContext->GenerateMips( *textureView );
if ( texture )
{
*texture = tex;
}
else
{
tex->Release();
}
}
}
else
{
// Create the texture
std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] );
if ( !initData )
{
return E_OUTOFMEMORY;
}
size_t skipMip = 0;
size_t twidth = 0;
size_t theight = 0;
size_t tdepth = 0;
hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, initData.get() );
if ( SUCCEEDED(hr) )
{
hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
isCubeMap, initData.get(), texture, textureView );
if ( FAILED(hr) && !maxsize && (mipCount > 1) )
{
// Retry with a maxsize determined by feature level
switch( d3dDevice->GetFeatureLevel() )
{
case D3D_FEATURE_LEVEL_9_1:
case D3D_FEATURE_LEVEL_9_2:
if ( isCubeMap )
{
maxsize = 512 /*D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION*/;
}
else
{
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
}
break;
case D3D_FEATURE_LEVEL_9_3:
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 256 /*D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
default: // D3D_FEATURE_LEVEL_10_0 & D3D_FEATURE_LEVEL_10_1
maxsize = (resDim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
? 2048 /*D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION*/
: 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
}
hr = FillInitData( width, height, depth, mipCount, arraySize, format, maxsize, bitSize, bitData,
twidth, theight, tdepth, skipMip, initData.get() );
if ( SUCCEEDED(hr) )
{
hr = CreateD3DResources( d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, arraySize,
format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
isCubeMap, initData.get(), texture, textureView );
}
}
}
}
@ -1348,7 +1543,22 @@ HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice,
size_t maxsize,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromMemoryEx( d3dDevice, ddsData, ddsDataSize, maxsize,
return CreateDDSTextureFromMemoryEx( d3dDevice, nullptr, ddsData, ddsDataSize, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView, alphaMode );
}
_Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemory( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
const uint8_t* ddsData,
size_t ddsDataSize,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
size_t maxsize,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromMemoryEx( d3dDevice, d3dContext, ddsData, ddsDataSize, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView, alphaMode );
}
@ -1366,6 +1576,26 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromMemoryEx( d3dDevice, nullptr, ddsData, ddsDataSize, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView, alphaMode );
}
_Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
const uint8_t* ddsData,
size_t ddsDataSize,
size_t maxsize,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode )
{
if ( texture )
{
@ -1424,7 +1654,7 @@ HRESULT DirectX::CreateDDSTextureFromMemoryEx( ID3D11Device* d3dDevice,
+ sizeof( DDS_HEADER )
+ (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0);
HRESULT hr = CreateTextureFromDDS( d3dDevice, header,
HRESULT hr = CreateTextureFromDDS( d3dDevice, d3dContext, header,
ddsData + offset, ddsDataSize - offset, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView );
@ -1456,7 +1686,21 @@ HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice,
size_t maxsize,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromFileEx( d3dDevice, fileName, maxsize,
return CreateDDSTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView, alphaMode );
}
_Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFile( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
const wchar_t* fileName,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
size_t maxsize,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromFileEx( d3dDevice, d3dContext, fileName, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView, alphaMode );
}
@ -1473,6 +1717,25 @@ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode )
{
return CreateDDSTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView, alphaMode );
}
_Use_decl_annotations_
HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
const wchar_t* fileName,
size_t maxsize,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
DDS_ALPHA_MODE* alphaMode )
{
if ( texture )
{
@ -1508,7 +1771,7 @@ HRESULT DirectX::CreateDDSTextureFromFileEx( ID3D11Device* d3dDevice,
return hr;
}
hr = CreateTextureFromDDS( d3dDevice, header,
hr = CreateTextureFromDDS( d3dDevice, d3dContext, header,
bitData, bitSize, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView );

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

@ -33,6 +33,7 @@
#define _In_reads_(exp)
#define _Out_writes_(exp)
#define _In_reads_bytes_(exp)
#define _In_reads_opt_(exp)
#define _Outptr_opt_
#endif
@ -51,6 +52,7 @@ namespace DirectX
DDS_ALPHA_MODE_CUSTOM = 4,
};
// Standard version
HRESULT CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize,
@ -68,6 +70,27 @@ namespace DirectX
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
// Standard version with optional auto-gen mipmap support
HRESULT CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize,
_Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
HRESULT CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* szFileName,
_Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
// Extended version
HRESULT CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize,
@ -94,4 +117,34 @@ namespace DirectX
_Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
// Extended version with optional auto-gen mipmap support
HRESULT CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize,
_In_ size_t maxsize,
_In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags,
_In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
HRESULT CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* szFileName,
_In_ size_t maxsize,
_In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags,
_In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
);
}

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

@ -147,6 +147,9 @@ static const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
static const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G','R','G','B'), 0, 0, 0, 0, 0 };
static const DDS_PIXELFORMAT DDSPF_YUY2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0, 0, 0, 0 };
static const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
@ -227,6 +230,9 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
case DXGI_FORMAT_Y416:
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
return 64;
case DXGI_FORMAT_R10G10B10A2_TYPELESS:
@ -264,8 +270,15 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_TYPELESS:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_AYUV:
case DXGI_FORMAT_Y410:
case DXGI_FORMAT_YUY2:
return 32;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
return 24;
case DXGI_FORMAT_R8G8_TYPELESS:
case DXGI_FORMAT_R8G8_UNORM:
case DXGI_FORMAT_R8G8_UINT:
@ -280,15 +293,24 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_R16_SINT:
case DXGI_FORMAT_B5G6R5_UNORM:
case DXGI_FORMAT_B5G5R5A1_UNORM:
case DXGI_FORMAT_A8P8:
case DXGI_FORMAT_B4G4R4A4_UNORM:
return 16;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_NV11:
return 12;
case DXGI_FORMAT_R8_TYPELESS:
case DXGI_FORMAT_R8_UNORM:
case DXGI_FORMAT_R8_UINT:
case DXGI_FORMAT_R8_SNORM:
case DXGI_FORMAT_R8_SINT:
case DXGI_FORMAT_A8_UNORM:
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
return 8;
case DXGI_FORMAT_R1_UNORM:
@ -319,6 +341,21 @@ static size_t BitsPerPixel( _In_ DXGI_FORMAT fmt )
case DXGI_FORMAT_BC7_UNORM_SRGB:
return 8;
#if defined(_XBOX_ONE) && defined(_TITLE)
case DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT:
case DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT:
return 32;
#if MONOLITHIC
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
return 24;
#endif
#endif // _XBOX_ONE && _TITLE
default:
return 0;
}
@ -376,8 +413,9 @@ static void GetSurfaceInfo( _In_ size_t width,
size_t numRows = 0;
bool bc = false;
bool packed = false;
size_t bcnumBytesPerBlock = 0;
bool packed = false;
bool planar = false;
size_t bpe = 0;
switch (fmt)
{
case DXGI_FORMAT_BC1_TYPELESS:
@ -387,7 +425,7 @@ static void GetSurfaceInfo( _In_ size_t width,
case DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT_BC4_SNORM:
bc=true;
bcnumBytesPerBlock = 8;
bpe = 8;
break;
case DXGI_FORMAT_BC2_TYPELESS:
@ -406,13 +444,44 @@ static void GetSurfaceInfo( _In_ size_t width,
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
bc = true;
bcnumBytesPerBlock = 16;
bpe = 16;
break;
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM:
case DXGI_FORMAT_YUY2:
packed = true;
bpe = 4;
break;
case DXGI_FORMAT_Y210:
case DXGI_FORMAT_Y216:
packed = true;
bpe = 8;
break;
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_420_OPAQUE:
planar = true;
bpe = 2;
break;
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
planar = true;
bpe = 4;
break;
#if defined(_XBOX_ONE) && defined(_TITLE) && MONOLITHIC
case DXGI_FORMAT_D16_UNORM_S8_UINT:
case DXGI_FORMAT_R16_UNORM_X8_TYPELESS:
case DXGI_FORMAT_X16_TYPELESS_G8_UINT:
planar = true;
bpe = 4;
break;
#endif
}
if (bc)
@ -427,22 +496,36 @@ static void GetSurfaceInfo( _In_ size_t width,
{
numBlocksHigh = std::max<size_t>( 1, (height + 3) / 4 );
}
rowBytes = numBlocksWide * bcnumBytesPerBlock;
rowBytes = numBlocksWide * bpe;
numRows = numBlocksHigh;
numBytes = rowBytes * numBlocksHigh;
}
else if (packed)
{
rowBytes = ( ( width + 1 ) >> 1 ) * 4;
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
numRows = 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
numBytes = rowBytes * numRows;
}
else if (planar)
{
rowBytes = ( ( width + 1 ) >> 1 ) * bpe;
numBytes = ( rowBytes * height ) + ( ( rowBytes * height + 1 ) >> 1 );
numRows = height + ( ( height + 1 ) >> 1 );
}
else
{
size_t bpp = BitsPerPixel( fmt );
rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
numRows = height;
numBytes = rowBytes * height;
}
numBytes = rowBytes * numRows;
if (outNumBytes)
{
*outNumBytes = numBytes;
@ -711,7 +794,8 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
case DXGI_FORMAT_B5G5R5A1_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A1R5G5B5, sizeof(DDS_PIXELFORMAT) ); break;
case DXGI_FORMAT_B8G8R8A8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
case DXGI_FORMAT_B8G8R8X8_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_X8R8G8B8, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.1
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break;
case DXGI_FORMAT_YUY2: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_YUY2, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
case DXGI_FORMAT_B4G4R4A4_UNORM: memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_A4R4G4B4, sizeof(DDS_PIXELFORMAT) ); break; // DXGI 1.2
// Legacy D3DX formats using D3DFMT enum value as FourCC
case DXGI_FORMAT_R32G32B32A32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 116; break; // D3DFMT_A32B32G32R32F
@ -723,6 +807,12 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
case DXGI_FORMAT_R32_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 114; break; // D3DFMT_R32F
case DXGI_FORMAT_R16_FLOAT: header->ddspf.size = sizeof(DDS_PIXELFORMAT); header->ddspf.flags = DDS_FOURCC; header->ddspf.fourCC = 111; break; // D3DFMT_R16F
case DXGI_FORMAT_AI44:
case DXGI_FORMAT_IA44:
case DXGI_FORMAT_P8:
case DXGI_FORMAT_A8P8:
return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
default:
memcpy_s( &header->ddspf, sizeof(header->ddspf), &DDSPF_DX10, sizeof(DDS_PIXELFORMAT) );
@ -768,9 +858,9 @@ HRESULT DirectX::SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext,
uint8_t* dptr = pixels.get();
size_t msize = std::min<size_t>( rowPitch, mapped.RowPitch );
for( size_t h = 0; h < rowCount; ++h )
{
size_t msize = std::min<size_t>( rowPitch, mapped.RowPitch );
memcpy_s( dptr, rowPitch, sptr, msize );
sptr += mapped.RowPitch;
dptr += rowPitch;

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

@ -669,6 +669,19 @@ static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice,
}
//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice,
const uint8_t* wicData,
size_t wicDataSize,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
size_t maxsize )
{
return CreateWICTextureFromMemoryEx( d3dDevice, nullptr, wicData, wicDataSize, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
@ -683,6 +696,24 @@ HRESULT DirectX::CreateWICTextureFromMemory( ID3D11Device* d3dDevice,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice,
const uint8_t* wicData,
size_t wicDataSize,
size_t maxsize,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView )
{
return CreateWICTextureFromMemoryEx( d3dDevice, nullptr, wicData, wicDataSize, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
@ -762,6 +793,18 @@ HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice,
}
//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice,
const wchar_t* fileName,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView,
size_t maxsize )
{
return CreateWICTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize,
D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, false,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,
@ -775,6 +818,23 @@ HRESULT DirectX::CreateWICTextureFromFile( ID3D11Device* d3dDevice,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice,
const wchar_t* fileName,
size_t maxsize,
D3D11_USAGE usage,
unsigned int bindFlags,
unsigned int cpuAccessFlags,
unsigned int miscFlags,
bool forceSRGB,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView )
{
return CreateWICTextureFromFileEx( d3dDevice, nullptr, fileName, maxsize,
usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
texture, textureView );
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dContext,

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

@ -52,6 +52,23 @@
namespace DirectX
{
// Standard version
HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0
);
HRESULT CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0
);
// Standard version with optional auto-gen mipmap support
HRESULT CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData,
@ -69,6 +86,33 @@ namespace DirectX
_In_ size_t maxsize = 0
);
// Extended version
HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize,
_In_ size_t maxsize,
_In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags,
_In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView
);
HRESULT CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName,
_In_ size_t maxsize,
_In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags,
_In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView
);
// Extended version with optional auto-gen mipmap support
HRESULT CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData,