From 72a1f29d1fff27408f7d3a9cba791d8d097e7988 Mon Sep 17 00:00:00 2001 From: walbourn_cp Date: Wed, 14 Nov 2012 14:09:35 -0800 Subject: [PATCH] DirectXTex: WIC2 support for ScreenGrab & WICTextureLoader --- DirectXTex/DirectXTexUtil.cpp | 1 + ScreenGrab/ScreenGrab.cpp | 46 ++++++++++++++- WICTextureLoader/WICTextureLoader.cpp | 85 ++++++++++++++++++++++----- 3 files changed, 113 insertions(+), 19 deletions(-) diff --git a/DirectXTex/DirectXTexUtil.cpp b/DirectXTex/DirectXTexUtil.cpp index 5e4f496..4ee83c3 100644 --- a/DirectXTex/DirectXTexUtil.cpp +++ b/DirectXTex/DirectXTexUtil.cpp @@ -153,6 +153,7 @@ IWICImagingFactory* _GetWIC() if ( SUCCEEDED(hr) ) { + // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed g_WIC2 = true; } else diff --git a/ScreenGrab/ScreenGrab.cpp b/ScreenGrab/ScreenGrab.cpp index a159a4b..4d6a366 100644 --- a/ScreenGrab/ScreenGrab.cpp +++ b/ScreenGrab/ScreenGrab.cpp @@ -624,6 +624,8 @@ static HRESULT CaptureTexture( _In_ ID3D11DeviceContext* pContext, //-------------------------------------------------------------------------------------- #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) +static bool g_WIC2 = false; + static IWICImagingFactory* _GetWIC() { static IWICImagingFactory* s_Factory = nullptr; @@ -631,6 +633,37 @@ static IWICImagingFactory* _GetWIC() if ( s_Factory ) return s_Factory; +#if(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory2, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory2), + (LPVOID*)&s_Factory + ); + + if ( SUCCEEDED(hr) ) + { + // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed + g_WIC2 = true; + } + else + { + hr = CoCreateInstance( + CLSID_WICImagingFactory1, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } + } +#else HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory, nullptr, @@ -644,10 +677,10 @@ static IWICImagingFactory* _GetWIC() s_Factory = nullptr; return nullptr; } +#endif return s_Factory; } - #endif @@ -923,11 +956,18 @@ HRESULT DirectX::SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, // Screenshots don’t typically include the alpha channel of the render target switch ( desc.Format ) { -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) case DXGI_FORMAT_R32G32B32A32_FLOAT: case DXGI_FORMAT_R16G16B16A16_FLOAT: case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - targetGuid = GUID_WICPixelFormat96bppRGBFloat; + if ( g_WIC2 ) + { + targetGuid = GUID_WICPixelFormat96bppRGBFloat; + } + else + { + targetGuid = GUID_WICPixelFormat24bppBGR; + } break; #endif diff --git a/WICTextureLoader/WICTextureLoader.cpp b/WICTextureLoader/WICTextureLoader.cpp index 35db725..f09ba88 100644 --- a/WICTextureLoader/WICTextureLoader.cpp +++ b/WICTextureLoader/WICTextureLoader.cpp @@ -126,10 +126,6 @@ static WICTranslate g_WICFormats[] = { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM }, { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM }, - -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) - { GUID_WICPixelFormat96bppRGBFloat, DXGI_FORMAT_R32G32B32_FLOAT }, -#endif }; //------------------------------------------------------------------------------------- @@ -202,18 +198,17 @@ static WICConvert g_WICConvert[] = { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT - { GUID_WICPixelFormat96bppRGBFixedPoint, GUID_WICPixelFormat96bppRGBFloat }, // DXGI_FORMAT_R32G32B32_FLOAT -#else - { GUID_WICPixelFormat96bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT #endif // We don't support n-channel formats }; +static bool g_WIC2 = false; + //-------------------------------------------------------------------------------------- static IWICImagingFactory* _GetWIC() { @@ -222,6 +217,37 @@ static IWICImagingFactory* _GetWIC() if ( s_Factory ) return s_Factory; +#if(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory2, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory2), + (LPVOID*)&s_Factory + ); + + if ( SUCCEEDED(hr) ) + { + // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed + g_WIC2 = true; + } + else + { + hr = CoCreateInstance( + CLSID_WICImagingFactory1, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } + } +#else HRESULT hr = CoCreateInstance( CLSID_WICImagingFactory, nullptr, @@ -235,6 +261,7 @@ static IWICImagingFactory* _GetWIC() s_Factory = nullptr; return nullptr; } +#endif return s_Factory; } @@ -248,6 +275,14 @@ static DXGI_FORMAT _WICToDXGI( const GUID& guid ) return g_WICFormats[i].format; } +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) + { + if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 ) + return DXGI_FORMAT_R32G32B32_FLOAT; + } +#endif + return DXGI_FORMAT_UNKNOWN; } @@ -361,16 +396,34 @@ static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice, DXGI_FORMAT format = _WICToDXGI( pixelFormat ); if ( format == DXGI_FORMAT_UNKNOWN ) { - for( size_t i=0; i < _countof(g_WICConvert); ++i ) + if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) { - if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) { - memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); + memcpy( &convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32_FLOAT; + } + else +#endif + { + memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + else + { + for( size_t i=0; i < _countof(g_WICConvert); ++i ) + { + if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) + { + memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); - format = _WICToDXGI( g_WICConvert[i].target ); - assert( format != DXGI_FORMAT_UNKNOWN ); - bpp = _WICBitsPerPixel( convertGUID ); - break; + format = _WICToDXGI( g_WICConvert[i].target ); + assert( format != DXGI_FORMAT_UNKNOWN ); + bpp = _WICBitsPerPixel( convertGUID ); + break; + } } } @@ -382,7 +435,7 @@ static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice, bpp = _WICBitsPerPixel( pixelFormat ); } -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) +#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE) if ( (format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0 ) { // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT