diff --git a/CLTool/main.cpp b/CLTool/main.cpp deleted file mode 100755 index 2dab017..0000000 --- a/CLTool/main.cpp +++ /dev/null @@ -1,2126 +0,0 @@ -//-------------------------------------------------------------------------------------- -// Copyright 2011 Intel Corporation -// All Rights Reserved -// -// Permission is granted to use, copy, distribute and prepare derivative works of this -// software for any purpose and without fee, provided, that the above copyright notice -// and this statement appear in all copies. Intel makes no representations about the -// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS." -// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY, -// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE, -// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not -// assume any responsibility for any errors which may appear in this software nor any -// responsibility to update it. -// -//-------------------------------------------------------------------------------------- - -#include "DXUT.h" -#include "DXUTcamera.h" -#include "DXUTgui.h" -#include "DXUTsettingsDlg.h" -#include "SDKmisc.h" -#include "SDKMesh.h" - -#include "DXTCompressorDLL.h" // DXT compressor DLL. -#include "BC7CompressorDLL.h" // BC7 compressor DLL. - -#include "StopWatch.h" // Timer. -#include "TaskMgrTBB.h" // TBB task manager. - -#include -#include - -#define ALIGN16(x) __declspec(align(16)) x -#define ALIGN32(x) __declspec(align(32)) x - -// DXT compressor type. -enum ECompressorType -{ - eCompType_DXT1, - eCompType_DXT5, - eCompType_BC7, - - kNumCompressorTypes -}; - -const TCHAR *kCompressorTypeStr[kNumCompressorTypes] = { - _T("DXT1/BC1"), - _T("DXT5/BC3"), - _T("BC7"), -}; - -enum EInstructionSet -{ - eInstrSet_Scalar - , eInstrSet_SSE - , eInstrSet_AVX2 - - , kNumInstructionSets -}; - -const TCHAR *kInstructionSetStr[kNumInstructionSets] = { - _T("Scalar"), - _T("SSE"), - _T("AVX2"), -}; - -enum EThreadMode -{ - eThreadMode_None, - eThreadMode_TBB, - eThreadMode_Win32, - - kNumThreadModes -}; - -const TCHAR *kThreadModeStr[kNumThreadModes] = { - _T("None"), - _T("TBB"), - _T("Win32") -}; - -static BOOL g_DXT1Available = TRUE; -static BOOL g_AVX2Available = FALSE; -static BOOL g_DX11Available = FALSE; - -const struct ECompressionScheme { - const ECompressorType type; - const EInstructionSet instrSet; - const EThreadMode threadMode; - const BOOL &availabilityOverride; -} kCompressionSchemes[] = { - { eCompType_DXT1, eInstrSet_Scalar, eThreadMode_None, g_DXT1Available }, - { eCompType_DXT1, eInstrSet_Scalar, eThreadMode_TBB, g_DXT1Available }, - { eCompType_DXT1, eInstrSet_Scalar, eThreadMode_Win32, g_DXT1Available }, - { eCompType_DXT1, eInstrSet_SSE, eThreadMode_None, g_DXT1Available }, - { eCompType_DXT1, eInstrSet_SSE, eThreadMode_TBB, g_DXT1Available }, - { eCompType_DXT1, eInstrSet_SSE, eThreadMode_Win32, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_Scalar, eThreadMode_None, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_Scalar, eThreadMode_TBB, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_Scalar, eThreadMode_Win32, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_SSE, eThreadMode_None, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_SSE, eThreadMode_TBB, g_DXT1Available }, - { eCompType_DXT5, eInstrSet_SSE, eThreadMode_Win32, g_DXT1Available }, - { eCompType_BC7, eInstrSet_Scalar, eThreadMode_None, g_DX11Available }, - { eCompType_BC7, eInstrSet_Scalar, eThreadMode_Win32, g_DX11Available }, - { eCompType_BC7, eInstrSet_SSE, eThreadMode_None, g_DX11Available }, - { eCompType_BC7, eInstrSet_SSE, eThreadMode_Win32, g_DX11Available }, - { eCompType_DXT1, eInstrSet_AVX2, eThreadMode_None, g_AVX2Available }, - { eCompType_DXT1, eInstrSet_AVX2, eThreadMode_TBB, g_AVX2Available }, - { eCompType_DXT1, eInstrSet_AVX2, eThreadMode_Win32, g_AVX2Available }, - { eCompType_DXT5, eInstrSet_AVX2, eThreadMode_None, g_AVX2Available }, - { eCompType_DXT5, eInstrSet_AVX2, eThreadMode_TBB, g_AVX2Available }, - { eCompType_DXT5, eInstrSet_AVX2, eThreadMode_Win32, g_AVX2Available }, -}; -const int kNumCompressionSchemes = sizeof(kCompressionSchemes) / sizeof(kCompressionSchemes[0]); -const ECompressionScheme *gCompressionScheme = kCompressionSchemes; - -// Textured vertex. -struct Vertex -{ - D3DXVECTOR3 position; - D3DXVECTOR2 texCoord; -}; - -// Global variables -CDXUTDialogResourceManager gDialogResourceManager; // manager for shared resources of dialogs -CD3DSettingsDlg gD3DSettingsDlg; // Device settings dialog -CDXUTDialog gHUD; // manages the 3D -CDXUTDialog gSampleUI; // dialog for sample specific controls -bool gShowHelp = false; // If true, it renders the UI control text -CDXUTTextHelper* gTxtHelper = NULL; -double gCompTime = 0.0; -double gCompRate = 0.0; -int gBlocksPerTask = 256; -int gFrameNum = 0; -int gFrameDelay = 100; -int gTexWidth = 0; -int gTexHeight = 0; -double gError = 0.0; - -#ifdef REPORT_RMSE -static const WCHAR *kErrorStr = L"Root Mean Squared Error"; -#else -static const WCHAR *kErrorStr = L"Peak Signal/Noise Ratio"; -#endif - -ID3D11DepthStencilState* gDepthStencilState = NULL; -UINT gStencilReference = 0; -ID3D11InputLayout* gVertexLayout = NULL; -ID3D11Buffer* gVertexBuffer = NULL; -ID3D11Buffer* gQuadVB = NULL; -ID3D11Buffer* gIndexBuffer = NULL; -ID3D11VertexShader* gVertexShader = NULL; -ID3D11PixelShader* gRenderFramePS = NULL; -ID3D11PixelShader* gRenderTexturePS = NULL; -ID3D11SamplerState* gSamPoint = NULL; -ID3D11ShaderResourceView* gUncompressedSRV = NULL; // Shader resource view for the uncompressed texture resource. -ID3D11ShaderResourceView* gCompressedSRV = NULL; // Shader resource view for the compressed texture resource. -ID3D11ShaderResourceView* gErrorSRV = NULL; // Shader resource view for the error texture. - -// Win32 thread API -const int kMaxWinThreads = 16; - -enum EThreadState { - eThreadState_WaitForData, - eThreadState_DataLoaded, - eThreadState_Running, - eThreadState_Done -}; - -typedef void (* CompressionFunc)(const BYTE* inBuf, BYTE* outBuf, int width, int height); - -struct WinThreadData { - EThreadState state; - int threadIdx; - const BYTE *inBuf; - BYTE *outBuf; - int width; - int height; - void (*cmpFunc)(const BYTE* inBuf, BYTE* outBuf, int width, int height); - - // Defaults.. - WinThreadData() : - state(eThreadState_Done), - threadIdx(-1), - inBuf(NULL), - outBuf(NULL), - width(-1), - height(-1), - cmpFunc(NULL) - { } - -} gWinThreadData[kMaxWinThreads]; - -HANDLE gWinThreadWorkEvent[kMaxWinThreads]; -HANDLE gWinThreadStartEvent = NULL; -HANDLE gWinThreadDoneEvent = NULL; -int gNumWinThreads = 0; -DWORD gNumProcessors = 1; // We have at least one processor. -DWORD dwThreadIdArray[kMaxWinThreads]; -HANDLE hThreadArray[kMaxWinThreads]; - -// UI control IDs -#define IDC_TOGGLEFULLSCREEN 1 -#define IDC_TOGGLEREF 2 -#define IDC_CHANGEDEVICE 3 -#define IDC_UNCOMPRESSEDTEXT 4 -#define IDC_COMPRESSEDTEXT 5 -#define IDC_ERRORTEXT 6 -#define IDC_SIZETEXT 7 -#define IDC_TIMETEXT 8 -#define IDC_RATETEXT 9 -#define IDC_TBB 10 -#define IDC_SIMD 11 -#define IDC_COMPRESSOR 12 -#define IDC_BLOCKSPERTASKTEXT 13 -#define IDC_BLOCKSPERTASK 14 -#define IDC_LOADTEXTURE 15 -#define IDC_RECOMPRESS 16 -#define IDC_RMSETEXT 17 - -// Forward declarations -bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ); -void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ); -LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, - void* pUserContext ); -void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ); -void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ); - -bool CALLBACK IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, - DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ); -HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, - void* pUserContext ); -HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, - const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ); -void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ); -void CALLBACK OnD3D11DestroyDevice( void* pUserContext ); -void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, - float fElapsedTime, void* pUserContext ); - -void InitApp(); -void RenderText(); - -void UpdateBlockSlider(); -void UpdateCompressionAlgorithms(); -void UpdateThreadingMode(); -void UpdateCompressionModes(); -void UpdateAllowedSettings(); - -void SetCompressionScheme(EInstructionSet instrSet, ECompressorType compType, EThreadMode threadMode); - -HRESULT CreateTextures(LPTSTR file); -void DestroyTextures(); -HRESULT LoadTexture(LPTSTR file); -HRESULT PadTexture(ID3D11ShaderResourceView** textureSRV); -HRESULT SaveTexture(ID3D11ShaderResourceView* textureSRV, LPTSTR file); -HRESULT CompressTexture(ID3D11ShaderResourceView* uncompressedSRV, ID3D11ShaderResourceView** compressedSRV); -HRESULT ComputeError(ID3D11ShaderResourceView* uncompressedSRV, ID3D11ShaderResourceView* compressedSRV, ID3D11ShaderResourceView** errorSRV); -HRESULT RecompressTexture(); - -void ComputeRMSE(const BYTE *errorData, const INT width, const INT height); - -void InitWin32Threads(); -void DestroyThreads(); - -void StoreDepthStencilState(); -void RestoreDepthStencilState(); -HRESULT DisableDepthTest(); - -namespace DXTC -{ - VOID CompressImageDXT(const BYTE* inBuf, BYTE* outBuf, INT width, INT height); - - VOID CompressImageDXTNoThread(const BYTE* inBuf, BYTE* outBuf, INT width, INT height); - VOID CompressImageDXTTBB(const BYTE* inBuf, BYTE* outBuf, INT width, INT height); - VOID CompressImageDXTWIN(const BYTE* inBuf, BYTE* outBuf, INT width, INT height); - - DWORD WINAPI CompressImageDXTWinThread( LPVOID lpParam ); -} - -#ifdef ENABLE_AVX2 -#ifdef _M_X64 -/* On x64, we can't have inline assembly in C files, see avxtest.asm */ -extern "C" int __stdcall supports_AVX2(); - -#else ifdef WIN32 -/* AVX2 instructions require 64 bit mode. */ -extern "C" int __stdcall supports_AVX2() { - return 0; -} -#endif // _M_X64 -#endif // ENABLE_AVX2 - -int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) -{ - // Enable run-time memory check for debug builds. -#if defined(DEBUG) | defined(_DEBUG) - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); -#endif - -#ifdef ENABLE_AVX2 - g_AVX2Available = supports_AVX2(); -#endif - - // Make sure that the event array is set to null... - memset(gWinThreadWorkEvent, 0, sizeof(gWinThreadWorkEvent)); - - // Figure out how many cores there are on this machine - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - gNumProcessors = sysinfo.dwNumberOfProcessors; - - // Make sure all of our threads are empty. - for(int i = 0; i < kMaxWinThreads; i++) { - hThreadArray[i] = NULL; - } - - // Set DXUT callbacks - DXUTSetCallbackDeviceChanging( ModifyDeviceSettings ); - DXUTSetCallbackMsgProc( MsgProc ); - DXUTSetCallbackKeyboard( OnKeyboard ); - DXUTSetCallbackFrameMove( OnFrameMove ); - DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable ); - DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice ); - DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain ); - DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender ); - DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain ); - DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice ); - - InitApp(); - - DXUTInit( true, true, NULL ); - DXUTSetCursorSettings( true, true ); - DXUTCreateWindow( L"Fast Texture Compressor" ); - - // Try to create a device with DX11 feature set - DXUTCreateDevice (D3D_FEATURE_LEVEL_11_0, true, 1280, 1024 ); - - // If we don't have an adequate driver, then we revert to DX10 feature set... - DXUTDeviceSettings settings = DXUTGetDeviceSettings(); - if(settings.d3d11.DriverType == D3D_DRIVER_TYPE_UNKNOWN || settings.d3d11.DriverType == D3D_DRIVER_TYPE_NULL) { - DXUTCreateDevice(D3D_FEATURE_LEVEL_10_1, true, 1280, 1024); - - // !HACK! Force enumeration here in order to relocate hardware with new feature level - DXUTGetD3D11Enumeration(true); - DXUTCreateDevice(D3D_FEATURE_LEVEL_10_1, true, 1280, 1024); - - const TCHAR *noDx11msg = _T("Your hardware does not seem to support DX11. BC7 Compression is disabled."); - MessageBox(NULL, noDx11msg, _T("Error"), MB_OK); - } - else { - g_DX11Available = TRUE; - } - - // Now that we know what things are allowed, update the available options. - UpdateAllowedSettings(); - - DXUTMainLoop(); - - // Destroy all of the threads... - DestroyThreads(); - - return DXUTGetExitCode(); -} - -// Initialize the app -void InitApp() -{ - // Initialize dialogs - gD3DSettingsDlg.Init(&gDialogResourceManager); - gHUD.Init(&gDialogResourceManager); - gSampleUI.Init(&gDialogResourceManager); - - gHUD.SetCallback(OnGUIEvent); - int x = 0; - int y = 10; - gHUD.AddButton(IDC_TOGGLEFULLSCREEN, L"Toggle full screen", x, y, 170, 23); - gHUD.AddButton(IDC_TOGGLEREF, L"Toggle REF (F3)", x, y += 26, 170, 23, VK_F3); - gHUD.AddButton(IDC_CHANGEDEVICE, L"Change device (F2)", x, y += 26, 170, 23, VK_F2); - - gSampleUI.SetCallback(OnGUIEvent); - x = 0; - y = 0; - gSampleUI.AddStatic(IDC_UNCOMPRESSEDTEXT, L"Uncompressed", x, y, 125, 22); - gSampleUI.AddStatic(IDC_COMPRESSEDTEXT, L"Compressed", x, y, 125, 22); - gSampleUI.AddStatic(IDC_ERRORTEXT, L"Error", x, y, 125, 22); - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"Texture Size: %d x %d", gTexWidth, gTexHeight); - gSampleUI.AddStatic(IDC_SIZETEXT, wstr, x, y, 125, 22); - swprintf_s(wstr, MAX_PATH, L"%s: %.2f", kErrorStr, gError); - gSampleUI.AddStatic(IDC_RMSETEXT, wstr, x, y, 125, 22); - swprintf_s(wstr, MAX_PATH, L"Compression Time: %0.2f ms", gCompTime); - gSampleUI.AddStatic(IDC_TIMETEXT, wstr, x, y, 125, 22); - swprintf_s(wstr, MAX_PATH, L"Compression Rate: %0.2f Mp/s", gCompRate); - gSampleUI.AddStatic(IDC_RATETEXT, wstr, x, y, 125, 22); - gSampleUI.AddComboBox(IDC_TBB, x, y, 95, 22); - gSampleUI.AddComboBox(IDC_SIMD, x, y, 140, 22); - gSampleUI.AddComboBox(IDC_COMPRESSOR, x, y, 105, 22); - swprintf_s(wstr, MAX_PATH, L"Blocks Per Task: %d", gBlocksPerTask); - gSampleUI.AddStatic(IDC_BLOCKSPERTASKTEXT, wstr, x, y, 125, 22); - gSampleUI.AddSlider(IDC_BLOCKSPERTASK, x, y, 256, 22, 1, 512, gBlocksPerTask); - gSampleUI.AddButton(IDC_LOADTEXTURE, L"Load Texture", x, y, 125, 22); - gSampleUI.AddButton(IDC_RECOMPRESS, L"Recompress", x, y, 125, 22); -} - -// Called right before creating a D3D11 device, allowing the app to modify the device settings as needed -bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) -{ - // Uncomment this to get debug information from D3D11 - //pDeviceSettings->d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; - - // For the first device created if its a REF device, optionally display a warning dialog box - static bool s_bFirstTime = true; - if( s_bFirstTime ) - { - s_bFirstTime = false; - if( ( DXUT_D3D11_DEVICE == pDeviceSettings->ver && - pDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) ) - { - DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); - } - } - - return true; -} - -// Handle updates to the scene. -void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) -{ - -} - -// Render the help and statistics text -void RenderText() -{ - UINT nBackBufferHeight = ( DXUTIsAppRenderingWithD3D9() ) ? DXUTGetD3D9BackBufferSurfaceDesc()->Height : - DXUTGetDXGIBackBufferSurfaceDesc()->Height; - - gTxtHelper->Begin(); - gTxtHelper->SetInsertionPos( 2, 0 ); - gTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) ); - gTxtHelper->DrawTextLine( DXUTGetFrameStats( false ) ); - gTxtHelper->DrawTextLine( DXUTGetDeviceStats() ); - - // Draw help - if( gShowHelp ) - { - gTxtHelper->SetInsertionPos( 2, nBackBufferHeight - 20 * 6 ); - gTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) ); - gTxtHelper->DrawTextLine( L"Controls:" ); - - gTxtHelper->SetInsertionPos( 20, nBackBufferHeight - 20 * 5 ); - gTxtHelper->DrawTextLine( L"Hide help: F1\n" - L"Quit: ESC\n" ); - } - else - { - gTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) ); - gTxtHelper->DrawTextLine( L"Press F1 for help" ); - } - - gTxtHelper->End(); -} - -// Handle messages to the application -LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, - void* pUserContext ) -{ - // Pass messages to dialog resource manager calls so GUI state is updated correctly - *pbNoFurtherProcessing = gDialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam ); - if( *pbNoFurtherProcessing ) - return 0; - - // Pass messages to settings dialog if its active - if( gD3DSettingsDlg.IsActive() ) - { - gD3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam ); - return 0; - } - - // Give the dialogs a chance to handle the message first - *pbNoFurtherProcessing = gHUD.MsgProc( hWnd, uMsg, wParam, lParam ); - if( *pbNoFurtherProcessing ) - return 0; - *pbNoFurtherProcessing = gSampleUI.MsgProc( hWnd, uMsg, wParam, lParam ); - if( *pbNoFurtherProcessing ) - return 0; - - return 0; -} - -// Handle key presses -void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext ) -{ - if( bKeyDown ) - { - switch( nChar ) - { - case VK_F1: - gShowHelp = !gShowHelp; break; - } - } -} - -// Handles the GUI events -void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ) -{ - switch( nControlID ) - { - case IDC_TOGGLEFULLSCREEN: - { - DXUTToggleFullScreen(); - break; - } - case IDC_TOGGLEREF: - { - DXUTToggleREF(); - break; - } - case IDC_CHANGEDEVICE: - { - gD3DSettingsDlg.SetActive( !gD3DSettingsDlg.IsActive() ); - break; - } - - case IDC_TIMETEXT: - { - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"Compression Time: %0.2f ms", gCompTime); - gSampleUI.GetStatic(IDC_TIMETEXT)->SetText(wstr); - break; - } - case IDC_RATETEXT: - { - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"Compression Rate: %0.2f Mp/s", gCompRate); - gSampleUI.GetStatic(IDC_RATETEXT)->SetText(wstr); - break; - } - - case IDC_RMSETEXT: - { - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"%s: %.2f", kErrorStr, gError); - gSampleUI.GetStatic(IDC_RMSETEXT)->SetText(wstr); - break; - } - - case IDC_TBB: - { - // Shut down all previous threading abilities. - DestroyThreads(); - - EInstructionSet instrSet = gCompressionScheme->instrSet; - ECompressorType compType = gCompressionScheme->type; - - EThreadMode newMode = (EThreadMode)(INT_PTR)gSampleUI.GetComboBox(IDC_TBB)->GetSelectedData(); - - switch(newMode) { - case eThreadMode_TBB: - - // Initialize the TBB task manager. - gTaskMgr.Init(); - - break; - - case eThreadMode_Win32: - - InitWin32Threads(); - - break; - - case eThreadMode_None: - // Do nothing, our threads are fine. - break; - } - - SetCompressionScheme(instrSet, compType, newMode); - UpdateAllowedSettings(); - - // Recompress the texture. - RecompressTexture(); - - break; - } - - case IDC_SIMD: - { - EThreadMode threadMode = gCompressionScheme->threadMode; - ECompressorType compType = gCompressionScheme->type; - - EInstructionSet newInstrSet = (EInstructionSet)(INT_PTR)gSampleUI.GetComboBox(IDC_SIMD)->GetSelectedData(); - - // If we selected AVX2, then the total number of blocks when using AVX2 changes, so we need - // to reflect that in the slider. - UpdateBlockSlider(); - - SetCompressionScheme(newInstrSet, compType, threadMode); - UpdateAllowedSettings(); - - // Recompress the texture. - RecompressTexture(); - - break; - } - case IDC_COMPRESSOR: - { - EThreadMode threadMode = gCompressionScheme->threadMode; - EInstructionSet instrSet = gCompressionScheme->instrSet; - ECompressorType newCompType = (ECompressorType)(INT_PTR)gSampleUI.GetComboBox(IDC_COMPRESSOR)->GetSelectedData(); - - SetCompressionScheme(instrSet, newCompType, threadMode); - UpdateAllowedSettings(); - - // Recompress the texture. - RecompressTexture(); - - break; - } - case IDC_BLOCKSPERTASK: - { - gBlocksPerTask = gSampleUI.GetSlider(IDC_BLOCKSPERTASK)->GetValue(); - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"Blocks Per Task: %d", gBlocksPerTask); - gSampleUI.GetStatic(IDC_BLOCKSPERTASKTEXT)->SetText(wstr); - - // Recompress the texture. - RecompressTexture(); - - break; - } - case IDC_LOADTEXTURE: - { - // Store the current working directory. - TCHAR workingDirectory[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, workingDirectory); - - // Open a file dialog. - OPENFILENAME openFileName; - WCHAR file[MAX_PATH]; - file[0] = 0; - ZeroMemory(&openFileName, sizeof(OPENFILENAME)); - openFileName.lStructSize = sizeof(OPENFILENAME); - openFileName.lpstrFile = file; - openFileName.nMaxFile = MAX_PATH; - openFileName.lpstrFilter = L"DDS\0*.dds\0\0"; - openFileName.nFilterIndex = 1; - openFileName.lpstrInitialDir = NULL; - openFileName.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - if(GetOpenFileName(&openFileName)) - { - CreateTextures(openFileName.lpstrFile); - } - - // Restore the working directory. GetOpenFileName changes the current working directory which causes problems with relative paths to assets. - SetCurrentDirectory(workingDirectory); - - break; - } - case IDC_RECOMPRESS: - { - // Recompress the texture. - RecompressTexture(); - - break; - } - } -} - -// Reject any D3D11 devices that aren't acceptable by returning false -bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, - DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) -{ - return true; -} - -// Find and compile the specified shader -HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut ) -{ - HRESULT hr = S_OK; - - // find the file - WCHAR str[MAX_PATH]; - V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szFileName ) ); - - DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; -#if defined( DEBUG ) || defined( _DEBUG ) - // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. - // Setting this flag improves the shader debugging experience, but still allows - // the shaders to be optimized and to run exactly the way they will run in - // the release configuration of this program. - dwShaderFlags |= D3DCOMPILE_DEBUG; -#endif - - ID3DBlob* pErrorBlob; - hr = D3DX11CompileFromFile( str, NULL, NULL, szEntryPoint, szShaderModel, - dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL ); - if( FAILED(hr) ) - { - if( pErrorBlob != NULL ) - OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() ); - SAFE_RELEASE( pErrorBlob ); - return hr; - } - SAFE_RELEASE( pErrorBlob ); - - return S_OK; -} - -// Create any D3D11 resources that aren't dependent on the back buffer -HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, - void* pUserContext ) -{ - HRESULT hr; - - ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); - V_RETURN(gDialogResourceManager.OnD3D11CreateDevice(pd3dDevice, pd3dImmediateContext)); - V_RETURN(gD3DSettingsDlg.OnD3D11CreateDevice(pd3dDevice)); - gTxtHelper = new CDXUTTextHelper(pd3dDevice, pd3dImmediateContext, &gDialogResourceManager, 15); - - // Create a vertex shader. - ID3DBlob* vertexShaderBuffer = NULL; - V_RETURN(CompileShaderFromFile(L"FastTextureCompressor\\FastTextureCompressor.hlsl", "PassThroughVS", "vs_4_0", &vertexShaderBuffer)); - V_RETURN(pd3dDevice->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &gVertexShader)); - - // Create a pixel shader that renders the composite frame. - ID3DBlob* pixelShaderBuffer = NULL; - V_RETURN(CompileShaderFromFile(L"FastTextureCompressor\\FastTextureCompressor.hlsl", "RenderFramePS", "ps_4_0", &pixelShaderBuffer)); - V_RETURN(pd3dDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &gRenderFramePS)); - - // Create a pixel shader that renders the error texture. - V_RETURN(CompileShaderFromFile(L"FastTextureCompressor\\FastTextureCompressor.hlsl", "RenderTexturePS", "ps_4_0", &pixelShaderBuffer)); - V_RETURN(pd3dDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &gRenderTexturePS)); - - // Create our vertex input layout - const D3D11_INPUT_ELEMENT_DESC layout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 } - }; - - V_RETURN(pd3dDevice->CreateInputLayout(layout, ARRAYSIZE(layout), vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &gVertexLayout)); - - SAFE_RELEASE(vertexShaderBuffer); - SAFE_RELEASE(pixelShaderBuffer); - - // Create a vertex buffer for three textured quads. - D3DXVECTOR2 quadSize(0.32f, 0.32f); - D3DXVECTOR2 quadOrigin(-0.66f, -0.0f); - Vertex tripleQuadVertices[18]; - ZeroMemory(tripleQuadVertices, sizeof(tripleQuadVertices)); - for(int i = 0; i < 18; i += 6) - { - tripleQuadVertices[i].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - tripleQuadVertices[i].texCoord = D3DXVECTOR2(0.0f, 0.0f); - - tripleQuadVertices[i + 1].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - tripleQuadVertices[i + 1].texCoord = D3DXVECTOR2(1.0f, 0.0f); - - tripleQuadVertices[i + 2].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - tripleQuadVertices[i + 2].texCoord = D3DXVECTOR2(1.0f, 1.0f); - - tripleQuadVertices[i + 3].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - tripleQuadVertices[i + 3].texCoord = D3DXVECTOR2(1.0f, 1.0f); - - tripleQuadVertices[i + 4].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - tripleQuadVertices[i + 4].texCoord = D3DXVECTOR2(0.0f, 1.0f); - - tripleQuadVertices[i + 5].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - tripleQuadVertices[i + 5].texCoord = D3DXVECTOR2(0.0f, 0.0f); - - quadOrigin.x += 0.66f; - } - - D3D11_BUFFER_DESC bufDesc; - ZeroMemory(&bufDesc, sizeof(bufDesc)); - bufDesc.Usage = D3D11_USAGE_DEFAULT; - bufDesc.ByteWidth = sizeof(tripleQuadVertices); - bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufDesc.CPUAccessFlags = 0; - D3D11_SUBRESOURCE_DATA data; - ZeroMemory(&data, sizeof(data)); - data.pSysMem = tripleQuadVertices; - V_RETURN(pd3dDevice->CreateBuffer(&bufDesc, &data, &gVertexBuffer)); - - // Create a vertex buffer for a single textured quad. - quadSize = D3DXVECTOR2(1.0f, 1.0f); - quadOrigin = D3DXVECTOR2(0.0f, 0.0f); - Vertex singleQuadVertices[6]; - singleQuadVertices[0].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - singleQuadVertices[0].texCoord = D3DXVECTOR2(0.0f, 0.0f); - singleQuadVertices[1].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - singleQuadVertices[1].texCoord = D3DXVECTOR2(1.0f, 0.0f); - singleQuadVertices[2].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - singleQuadVertices[2].texCoord = D3DXVECTOR2(1.0f, 1.0f); - singleQuadVertices[3].position = D3DXVECTOR3(quadOrigin.x + quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - singleQuadVertices[3].texCoord = D3DXVECTOR2(1.0f, 1.0f); - singleQuadVertices[4].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y - quadSize.y, 0.0f); - singleQuadVertices[4].texCoord = D3DXVECTOR2(0.0f, 1.0f); - singleQuadVertices[5].position = D3DXVECTOR3(quadOrigin.x - quadSize.x, quadOrigin.y + quadSize.y, 0.0f); - singleQuadVertices[5].texCoord = D3DXVECTOR2(0.0f, 0.0f); - - ZeroMemory(&bufDesc, sizeof(bufDesc)); - bufDesc.Usage = D3D11_USAGE_DEFAULT; - bufDesc.ByteWidth = sizeof(singleQuadVertices); - bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufDesc.CPUAccessFlags = 0; - ZeroMemory(&data, sizeof(data)); - data.pSysMem = singleQuadVertices; - V_RETURN(pd3dDevice->CreateBuffer(&bufDesc, &data, &gQuadVB)); - - // Create a sampler state - D3D11_SAMPLER_DESC SamDesc; - SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - SamDesc.MipLODBias = 0.0f; - SamDesc.MaxAnisotropy = 1; - SamDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0; - SamDesc.MinLOD = 0; - SamDesc.MaxLOD = D3D11_FLOAT32_MAX; - V_RETURN(pd3dDevice->CreateSamplerState(&SamDesc, &gSamPoint)); - - // Load and initialize the textures. - WCHAR path[MAX_PATH]; - V_RETURN(DXUTFindDXSDKMediaFileCch(path, MAX_PATH, L"Images\\texture.dds")); - V_RETURN(CreateTextures(path)); - - return S_OK; -} - -// Create any D3D11 resources that depend on the back buffer -HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, - const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) -{ - HRESULT hr; - V_RETURN( gDialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); - V_RETURN( gD3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) ); - - gHUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 ); - gHUD.SetSize( 170, 170 ); - - gSampleUI.SetLocation( 0, 0 ); - gSampleUI.SetSize( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); - - int oneThirdWidth = int(gSampleUI.GetWidth() / 3.0f); - int oneThirdHeight = int(gSampleUI.GetHeight() / 3.0f); - int x = 20; - int y = oneThirdHeight - 20; - gSampleUI.GetStatic(IDC_UNCOMPRESSEDTEXT)->SetLocation(x, y); - gSampleUI.GetStatic(IDC_COMPRESSEDTEXT)->SetLocation(x += oneThirdWidth, y); - gSampleUI.GetStatic(IDC_ERRORTEXT)->SetLocation(x += oneThirdWidth, y); - x = gSampleUI.GetWidth() - 276; - y = gSampleUI.GetHeight() - 216; - gSampleUI.GetStatic(IDC_SIZETEXT)->SetLocation(x, y); - gSampleUI.GetStatic(IDC_RMSETEXT)->SetLocation(x, y += 26); - gSampleUI.GetStatic(IDC_TIMETEXT)->SetLocation(x, y += 26); - gSampleUI.GetStatic(IDC_RATETEXT)->SetLocation(x, y += 26); - gSampleUI.GetComboBox(IDC_SIMD)->SetLocation(x, y += 26); - gSampleUI.GetComboBox(IDC_COMPRESSOR)->SetLocation(x + 150, y); - gSampleUI.GetStatic(IDC_BLOCKSPERTASKTEXT)->SetLocation(x, y += 26); - gSampleUI.GetComboBox(IDC_TBB)->SetLocation(x + 160, y); - gSampleUI.GetSlider(IDC_BLOCKSPERTASK)->SetLocation(x, y += 26); - gSampleUI.GetButton(IDC_LOADTEXTURE)->SetLocation(x, y += 26); - gSampleUI.GetButton(IDC_RECOMPRESS)->SetLocation(x + 131, y); - - return S_OK; -} - -// Render the scene using the D3D11 device -void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, - float fElapsedTime, void* pUserContext ) -{ - // Recompress the texture gFrameDelay frames after the app has started. This produces more accurate timing of the - // compression algorithm. - if(gFrameNum == gFrameDelay) - { - RecompressTexture(); - gFrameNum++; - } - else if(gFrameNum < gFrameDelay) - { - gFrameNum++; - } - - // If the settings dialog is being shown, then render it instead of rendering the app's scene - if( gD3DSettingsDlg.IsActive() ) - { - gD3DSettingsDlg.OnRender( fElapsedTime ); - return; - } - - // Clear the render target and depth stencil - float ClearColor[4] = { 0.02f, 0.02f, 0.02f, 1.0f }; - ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView(); - pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor ); - ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView(); - pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); - - // Set the input layout. - pd3dImmediateContext->IASetInputLayout( gVertexLayout ); - - // Set the vertex buffer. - UINT stride = sizeof( Vertex ); - UINT offset = 0; - pd3dImmediateContext->IASetVertexBuffers( 0, 1, &gVertexBuffer, &stride, &offset ); - - // Set the primitive topology - pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); - - // Set the shaders - pd3dImmediateContext->VSSetShader( gVertexShader, NULL, 0 ); - pd3dImmediateContext->PSSetShader( gRenderFramePS, NULL, 0 ); - - // Set the texture sampler. - pd3dImmediateContext->PSSetSamplers( 0, 1, &gSamPoint ); - - // Render the uncompressed texture. - pd3dImmediateContext->PSSetShaderResources( 0, 1, &gUncompressedSRV ); - pd3dImmediateContext->Draw( 6, 0 ); - - // Render the compressed texture. - pd3dImmediateContext->PSSetShaderResources( 0, 1, &gCompressedSRV ); - pd3dImmediateContext->Draw( 6, 6 ); - - // Render the error texture. - pd3dImmediateContext->PSSetShaderResources( 0, 1, &gErrorSRV ); - pd3dImmediateContext->Draw( 6, 12 ); - - DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); - HRESULT hr; - V(gHUD.OnRender( fElapsedTime )); - V(gSampleUI.OnRender( fElapsedTime )); - RenderText(); - DXUT_EndPerfEvent(); -} - -// Release D3D11 resources created in OnD3D11ResizedSwapChain -void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ) -{ - gDialogResourceManager.OnD3D11ReleasingSwapChain(); -} - -// Release D3D11 resources created in OnD3D11CreateDevice -void CALLBACK OnD3D11DestroyDevice( void* pUserContext ) -{ - gDialogResourceManager.OnD3D11DestroyDevice(); - gD3DSettingsDlg.OnD3D11DestroyDevice(); - //CDXUTDirectionWidget::StaticOnD3D11DestroyDevice(); - DXUTGetGlobalResourceCache().OnDestroyDevice(); - SAFE_DELETE( gTxtHelper ); - - SAFE_RELEASE( gVertexLayout ); - SAFE_RELEASE( gVertexBuffer ); - SAFE_RELEASE( gQuadVB ); - SAFE_RELEASE( gIndexBuffer ); - SAFE_RELEASE( gVertexShader ); - SAFE_RELEASE( gRenderFramePS ); - SAFE_RELEASE( gRenderTexturePS ); - SAFE_RELEASE( gSamPoint ); - - DestroyTextures(); -} - -// Free previously allocated texture resources and create new texture resources. -HRESULT CreateTextures(LPTSTR file) -{ - // Destroy any previously created textures. - DestroyTextures(); - - // Load the uncompressed texture. - HRESULT hr; - V_RETURN(LoadTexture(file)); - - // Compress the texture. - V_RETURN(CompressTexture(gUncompressedSRV, &gCompressedSRV)); - - // Compute the error in the compressed texture. - V_RETURN(ComputeError(gUncompressedSRV, gCompressedSRV, &gErrorSRV)); - - return S_OK; -} - -// Destroy texture resources. -void DestroyTextures() -{ - SAFE_RELEASE(gErrorSRV); - SAFE_RELEASE(gCompressedSRV); - SAFE_RELEASE(gUncompressedSRV); -} - -// This functions loads a texture and prepares it for compression. The compressor only works on texture -// dimensions that are divisible by 4. Textures that are not divisible by 4 are resized and padded with the edge values. -HRESULT LoadTexture(LPTSTR file) -{ - // Load the uncrompressed texture. - // The loadInfo structure disables mipmapping by setting MipLevels to 1. - D3DX11_IMAGE_LOAD_INFO loadInfo; - ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO)); - loadInfo.Width = D3DX11_DEFAULT; - loadInfo.Height = D3DX11_DEFAULT; - loadInfo.Depth = D3DX11_DEFAULT; - loadInfo.FirstMipLevel = D3DX11_DEFAULT; - loadInfo.MipLevels = 1; - loadInfo.Usage = (D3D11_USAGE) D3DX11_DEFAULT; - loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; - loadInfo.CpuAccessFlags = D3DX11_DEFAULT; - loadInfo.MiscFlags = D3DX11_DEFAULT; - loadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - loadInfo.Filter = D3DX11_FILTER_POINT | D3DX11_FILTER_SRGB; - loadInfo.MipFilter = D3DX11_DEFAULT; - loadInfo.pSrcInfo = NULL; - HRESULT hr; - V_RETURN(D3DX11CreateShaderResourceViewFromFile(DXUTGetD3D11Device(), file, &loadInfo, NULL, &gUncompressedSRV, NULL)); - - // Pad the texture. - V_RETURN(PadTexture(&gUncompressedSRV)); - - // Query the texture description. - ID3D11Texture2D* tex; - gUncompressedSRV->GetResource((ID3D11Resource**)&tex); - D3D11_TEXTURE2D_DESC texDesc; - tex->GetDesc(&texDesc); - SAFE_RELEASE(tex); - - // Update the UI's texture width and height. - gTexWidth = texDesc.Width; - gTexHeight = texDesc.Height; - - WCHAR wstr[MAX_PATH]; - swprintf_s(wstr, MAX_PATH, L"Texture Size: %d x %d", gTexWidth, gTexHeight); - gSampleUI.GetStatic(IDC_SIZETEXT)->SetText(wstr); - // gSampleUI.SendEvent(IDC_SIZETEXT, true, gSampleUI.GetStatic(IDC_SIZETEXT)); - - UpdateBlockSlider(); - - return S_OK; -} - -void SetCompressionScheme(EInstructionSet instrSet, ECompressorType compType, EThreadMode threadMode) { - - bool foundMatch = false; - for(int i = 0; i < kNumCompressionSchemes; i++) { - bool match = true; - match = match && kCompressionSchemes[i].instrSet == instrSet; - match = match && kCompressionSchemes[i].type == compType; - match = match && kCompressionSchemes[i].threadMode == threadMode; - if(match) { - gCompressionScheme = &(kCompressionSchemes[i]); - foundMatch = true; - break; - } - } - - if(!foundMatch) { - OutputDebugString(L"ERROR: Did not find match for compression scheme, not changing.\n"); - } -} - -void UpdateCompressionModes() { - - CDXUTComboBox *comboBox = gSampleUI.GetComboBox(IDC_COMPRESSOR); - comboBox->RemoveAllItems(); - - // If we're updating the compression modes, then see - // what we currently have selected and keep everything else constant. - EThreadMode currThreadMode = gCompressionScheme->threadMode; - EInstructionSet currInstrSet = gCompressionScheme->instrSet; - - bool added[kNumCompressorTypes]; - memset(added, 0, sizeof(added)); - - for(int i = 0; i < kNumCompressionSchemes; i++) { - - bool match = kCompressionSchemes[i].instrSet == currInstrSet; - match = match && kCompressionSchemes[i].threadMode == currThreadMode; - match = match && kCompressionSchemes[i].availabilityOverride; - - if(match) { - ECompressorType compType = kCompressionSchemes[i].type; - if(!added[compType]) { - comboBox->AddItem(kCompressorTypeStr[compType], (void*)(INT_PTR)compType); - added[compType] = true; - } - } - } - - comboBox->SetSelectedByData((void *)(INT_PTR)(gCompressionScheme->type)); -} - -void UpdateCompressionAlgorithms() { - - CDXUTComboBox *comboBox = gSampleUI.GetComboBox(IDC_SIMD); - comboBox->RemoveAllItems(); - - // If we're updating the compression algorithms, then see - // what we currently have selected and keep everything else constant. - EThreadMode currThreadMode = gCompressionScheme->threadMode; - ECompressorType currType = gCompressionScheme->type; - - bool added[kNumInstructionSets]; - memset(added, 0, sizeof(added)); - - for(int i = 0; i < kNumCompressionSchemes; i++) { - - bool match = kCompressionSchemes[i].type == currType; - match = match && kCompressionSchemes[i].threadMode == currThreadMode; - match = match && kCompressionSchemes[i].availabilityOverride; - - if(match) { - EInstructionSet instrSet = kCompressionSchemes[i].instrSet; - if(!added[instrSet]) { - comboBox->AddItem(kInstructionSetStr[instrSet], (void*)(INT_PTR)instrSet); - added[instrSet] = true; - } - } - } - - comboBox->SetSelectedByData((void *)(INT_PTR)(gCompressionScheme->instrSet)); -} - -void UpdateThreadingMode() { - - CDXUTComboBox *comboBox = gSampleUI.GetComboBox(IDC_TBB); - comboBox->RemoveAllItems(); - - // If we're updating the compression algorithms, then see - // what we currently have selected and keep everything else constant. - EInstructionSet currInstrSet = gCompressionScheme->instrSet; - ECompressorType currType = gCompressionScheme->type; - - bool added[kNumThreadModes]; - memset(added, 0, sizeof(added)); - - for(int i = 0; i < kNumCompressionSchemes; i++) { - - bool match = kCompressionSchemes[i].type == currType; - match = match && kCompressionSchemes[i].instrSet == currInstrSet; - match = match && kCompressionSchemes[i].availabilityOverride; - - if(match) { - EThreadMode threadMode = kCompressionSchemes[i].threadMode; - if(!added[threadMode]) { - comboBox->AddItem(kThreadModeStr[threadMode], (void*)(INT_PTR)threadMode); - added[threadMode] = true; - } - } - } - - comboBox->SetSelectedByData((void *)(INT_PTR)(gCompressionScheme->threadMode)); -} - -void UpdateAllowedSettings() { - UpdateCompressionModes(); - UpdateCompressionAlgorithms(); - UpdateThreadingMode(); -} - -void UpdateBlockSlider() { - - int blockRows = gTexHeight / 4; - int blockCols = gTexWidth / 4; - if(gCompressionScheme->instrSet == eInstrSet_AVX2) { - blockCols /= 2; - } - - int numBlocks = blockRows * blockCols; - int blksPerProc = numBlocks / gNumProcessors; - - gSampleUI.GetSlider(IDC_BLOCKSPERTASK)->SetRange(1, blksPerProc); -} - -// Pad the texture to dimensions that are divisible by 4. -HRESULT PadTexture(ID3D11ShaderResourceView** textureSRV) -{ - // Query the texture description. - ID3D11Texture2D* tex; - (*textureSRV)->GetResource((ID3D11Resource**)&tex); - D3D11_TEXTURE2D_DESC texDesc; - tex->GetDesc(&texDesc); - - // Exit if the texture dimensions are divisible by 4. - if((texDesc.Width % 4 == 0) && (texDesc.Height % 4 == 0)) - { - SAFE_RELEASE(tex); - return S_OK; - } - - // Compute the size of the padded texture. - UINT padWidth = texDesc.Width / 4 * 4 + 4; - UINT padHeight = texDesc.Height / 4 * 4 + 4; - - // Create a buffer for the padded texels. - BYTE* padTexels = new BYTE[padWidth * padHeight * 4]; - - // Create a staging resource for the texture. - HRESULT hr; - ID3D11Device* device = DXUTGetD3D11Device(); - D3D11_TEXTURE2D_DESC stgTexDesc; - memcpy(&stgTexDesc, &texDesc, sizeof(D3D11_TEXTURE2D_DESC)); - stgTexDesc.Usage = D3D11_USAGE_STAGING; - stgTexDesc.BindFlags = 0; - stgTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - ID3D11Texture2D* stgTex; - V_RETURN(device->CreateTexture2D(&stgTexDesc, NULL, &stgTex)); - - // Copy the texture into the staging resource. - ID3D11DeviceContext* deviceContext = DXUTGetD3D11DeviceContext(); - deviceContext->CopyResource(stgTex, tex); - - // Map the staging resource. - D3D11_MAPPED_SUBRESOURCE texData; - V_RETURN(deviceContext->Map(stgTex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ_WRITE, 0, &texData)); - - // Copy the beginning of each row. - BYTE* texels = (BYTE*)texData.pData; - for(UINT row = 0; row < stgTexDesc.Height; row++) - { - UINT rowStart = row * texData.RowPitch; - UINT padRowStart = row * padWidth * 4; - memcpy(padTexels + padRowStart, texels + rowStart, stgTexDesc.Width * 4); - - // Pad the end of each row. - if(padWidth > stgTexDesc.Width) - { - BYTE* padVal = texels + rowStart + (stgTexDesc.Width - 1) * 4; - for(UINT padCol = stgTexDesc.Width; padCol < padWidth; padCol++) - { - UINT padColStart = padCol * 4; - memcpy(padTexels + padRowStart + padColStart, padVal, 4); - } - } - } - - // Pad the end of each column. - if(padHeight > stgTexDesc.Height) - { - UINT lastRow = (stgTexDesc.Height - 1); - UINT lastRowStart = lastRow * padWidth * 4; - BYTE* padVal = padTexels + lastRowStart; - for(UINT padRow = stgTexDesc.Height; padRow < padHeight; padRow++) - { - UINT padRowStart = padRow * padWidth * 4; - memcpy(padTexels + padRowStart, padVal, padWidth * 4); - } - } - - // Unmap the staging resources. - deviceContext->Unmap(stgTex, D3D11CalcSubresource(0, 0, 1)); - - // Create a padded texture. - D3D11_TEXTURE2D_DESC padTexDesc; - memcpy(&padTexDesc, &texDesc, sizeof(D3D11_TEXTURE2D_DESC)); - padTexDesc.Width = padWidth; - padTexDesc.Height = padHeight; - D3D11_SUBRESOURCE_DATA padTexData; - ZeroMemory(&padTexData, sizeof(D3D11_SUBRESOURCE_DATA)); - padTexData.pSysMem = padTexels; - padTexData.SysMemPitch = padWidth * sizeof(BYTE) * 4; - ID3D11Texture2D* padTex; - V_RETURN(device->CreateTexture2D(&padTexDesc, &padTexData, &padTex)); - - // Delete the padded texel buffer. - delete [] padTexels; - - // Release the shader resource view for the texture. - SAFE_RELEASE(*textureSRV); - - // Create a shader resource view for the padded texture. - D3D11_SHADER_RESOURCE_VIEW_DESC padTexSRVDesc; - padTexSRVDesc.Format = padTexDesc.Format; - padTexSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - padTexSRVDesc.Texture2D.MipLevels = padTexDesc.MipLevels; - padTexSRVDesc.Texture2D.MostDetailedMip = padTexDesc.MipLevels - 1; - V_RETURN(device->CreateShaderResourceView(padTex, &padTexSRVDesc, textureSRV)); - - // Release resources. - SAFE_RELEASE(padTex); - SAFE_RELEASE(stgTex); - SAFE_RELEASE(tex); - - return S_OK; -} - -// Save a texture to a file. -HRESULT SaveTexture(ID3D11ShaderResourceView* textureSRV, LPTSTR file) -{ - // Get the texture resource. - ID3D11Resource* texRes; - textureSRV->GetResource(&texRes); - if(texRes == NULL) - { - return E_POINTER; - } - - // Save the texture to a file. - HRESULT hr; - V_RETURN(D3DX11SaveTextureToFile(DXUTGetD3D11DeviceContext(), texRes, D3DX11_IFF_DDS, file)); - - // Release the texture resources. - SAFE_RELEASE(texRes); - - return S_OK; -} - -// Compress a texture. -HRESULT CompressTexture(ID3D11ShaderResourceView* uncompressedSRV, ID3D11ShaderResourceView** compressedSRV) -{ - // Query the texture description of the uncompressed texture. - ID3D11Resource* uncompRes; - gUncompressedSRV->GetResource(&uncompRes); - D3D11_TEXTURE2D_DESC uncompTexDesc; - ((ID3D11Texture2D*)uncompRes)->GetDesc(&uncompTexDesc); - - // Create a 2D texture for the compressed texture. - HRESULT hr; - ID3D11Texture2D* compTex; - D3D11_TEXTURE2D_DESC compTexDesc; - memcpy(&compTexDesc, &uncompTexDesc, sizeof(D3D11_TEXTURE2D_DESC)); - - switch(gCompressionScheme->type) { - default: - case eCompType_DXT1: - compTexDesc.Format = DXGI_FORMAT_BC1_UNORM_SRGB; - break; - case eCompType_DXT5: - compTexDesc.Format = DXGI_FORMAT_BC3_UNORM_SRGB; - break; - case eCompType_BC7: - compTexDesc.Format = DXGI_FORMAT_BC7_UNORM_SRGB; - break; - } - - ID3D11Device* device = DXUTGetD3D11Device(); - V_RETURN(device->CreateTexture2D(&compTexDesc, NULL, &compTex)); - - // Create a shader resource view for the compressed texture. - SAFE_RELEASE(*compressedSRV); - D3D11_SHADER_RESOURCE_VIEW_DESC compSRVDesc; - compSRVDesc.Format = compTexDesc.Format; - compSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - compSRVDesc.Texture2D.MipLevels = compTexDesc.MipLevels; - compSRVDesc.Texture2D.MostDetailedMip = compTexDesc.MipLevels - 1; - V_RETURN(device->CreateShaderResourceView(compTex, &compSRVDesc, compressedSRV)); - - // Create a staging resource for the compressed texture. - compTexDesc.Usage = D3D11_USAGE_STAGING; - compTexDesc.BindFlags = 0; - compTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - ID3D11Texture2D* compStgTex; - V_RETURN(device->CreateTexture2D(&compTexDesc, NULL, &compStgTex)); - - // Create a staging resource for the uncompressed texture. - uncompTexDesc.Usage = D3D11_USAGE_STAGING; - uncompTexDesc.BindFlags = 0; - uncompTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - ID3D11Texture2D* uncompStgTex; - V_RETURN(device->CreateTexture2D(&uncompTexDesc, NULL, &uncompStgTex)); - - // Copy the uncompressed texture into the staging resource. - ID3D11DeviceContext* deviceContext = DXUTGetD3D11DeviceContext(); - deviceContext->CopyResource(uncompStgTex, uncompRes); - - // Map the staging resources. - D3D11_MAPPED_SUBRESOURCE uncompData; - V_RETURN(deviceContext->Map(uncompStgTex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ_WRITE, 0, &uncompData)); - D3D11_MAPPED_SUBRESOURCE compData; - V_RETURN(deviceContext->Map(compStgTex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ_WRITE, 0, &compData)); - - // Time the compression. - StopWatch stopWatch; - stopWatch.Start(); - - const int kNumCompressions = 1; - for(int cmpNum = 0; cmpNum < kNumCompressions; cmpNum++) { - - // Compress the uncompressed texels. - DXTC::CompressImageDXT((BYTE*)uncompData.pData, (BYTE*)compData.pData, uncompTexDesc.Width, uncompTexDesc.Height); - } - - // Update the compression time. - stopWatch.Stop(); - gCompTime = stopWatch.TimeInMilliseconds(); - gSampleUI.SendEvent(IDC_TIMETEXT, true, gSampleUI.GetStatic(IDC_TIMETEXT)); - - // Compute the compression rate. - INT numPixels = compTexDesc.Width * compTexDesc.Height * kNumCompressions; - gCompRate = (double)numPixels / stopWatch.TimeInSeconds() / 1000000.0; - gSampleUI.SendEvent(IDC_RATETEXT, true, gSampleUI.GetStatic(IDC_RATETEXT)); - stopWatch.Reset(); - - // Unmap the staging resources. - deviceContext->Unmap(compStgTex, D3D11CalcSubresource(0, 0, 1)); - deviceContext->Unmap(uncompStgTex, D3D11CalcSubresource(0, 0, 1)); - - // Copy the staging resourse into the compressed texture. - deviceContext->CopyResource(compTex, compStgTex); - - // Release resources. - SAFE_RELEASE(uncompStgTex); - SAFE_RELEASE(compStgTex); - SAFE_RELEASE(compTex); - SAFE_RELEASE(uncompRes); - - return S_OK; -} - -#define CHECK_WIN_THREAD_FUNC(x) \ - do { \ - if(NULL == (x)) { \ - wchar_t wstr[256]; \ - swprintf_s(wstr, L"Error detected from call %s at line %d of main.cpp", _T(#x), __LINE__); \ - ReportWinThreadError(wstr); \ - } \ - } \ - while(0) - -void ReportWinThreadError(const wchar_t *str) { - - // Retrieve the system error message for the last-error code. - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - - // Display the error message. - - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR)str) + 40) * sizeof(TCHAR)); - StringCchPrintf((LPTSTR)lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s failed with error %d: %s"), - str, dw, lpMsgBuf); - MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); - - // Free error-handling buffer allocations. - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); -} - -void InitWin32Threads() { - - // Already initialized? - if(gNumWinThreads > 0) { - return; - } - - SetLastError(0); - - gNumWinThreads = gNumProcessors; - if(gNumWinThreads >= MAXIMUM_WAIT_OBJECTS) - gNumWinThreads = MAXIMUM_WAIT_OBJECTS; - - // Create the synchronization events. - for(int i = 0; i < gNumWinThreads; i++) { - CHECK_WIN_THREAD_FUNC(gWinThreadWorkEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL)); - } - - CHECK_WIN_THREAD_FUNC(gWinThreadStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL)); - CHECK_WIN_THREAD_FUNC(gWinThreadDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL)); - - // Create threads - for(int threadIdx = 0; threadIdx < gNumWinThreads; threadIdx++) { - gWinThreadData[threadIdx].state = eThreadState_WaitForData; - CHECK_WIN_THREAD_FUNC(hThreadArray[threadIdx] = CreateThread(NULL, 0, DXTC::CompressImageDXTWinThread, &gWinThreadData[threadIdx], 0, &dwThreadIdArray[threadIdx])); - } -} - -void DestroyThreads() { - - switch(gCompressionScheme->threadMode) { - case eThreadMode_TBB: - { - // Shutdown the TBB task manager. - gTaskMgr.Shutdown(); - } - break; - - case eThreadMode_Win32: - { - // Release all windows threads that may be active... - for(int i=0; i < gNumWinThreads; i++) { - gWinThreadData[i].state = eThreadState_Done; - } - - // Send the event for the threads to start. - CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadDoneEvent)); - CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadStartEvent)); - - // Wait for all the threads to finish.... - DWORD dwWaitRet = WaitForMultipleObjects(gNumWinThreads, hThreadArray, TRUE, INFINITE); - if(WAIT_FAILED == dwWaitRet) - ReportWinThreadError(L"DestroyThreads() -- WaitForMultipleObjects"); - - // !HACK! This doesn't actually do anything. There is either a bug in the - // Intel compiler or the windows run-time that causes the threads to not - // be cleaned up properly if the following two lines of code are not present. - // Since we're passing INFINITE to WaitForMultipleObjects, that function will - // never time out and per-microsoft spec, should never give this return value... - // Even with these lines, the bug does not consistently disappear unless you - // clean and rebuild. Heigenbug? - // - // If we compile with MSVC, then the following two lines are not necessary. - else if(WAIT_TIMEOUT == dwWaitRet) - OutputDebugString(L"DestroyThreads() -- WaitForMultipleObjects -- TIMEOUT"); - - // Reset the start event - CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadStartEvent)); - CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadDoneEvent)); - - // Close all thread handles. - for(int i=0; i < gNumWinThreads; i++) { - CHECK_WIN_THREAD_FUNC(CloseHandle(hThreadArray[i])); - } - - for(int i =0; i < kMaxWinThreads; i++ ){ - hThreadArray[i] = NULL; - } - - // Close all event handles... - CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadDoneEvent)); - gWinThreadDoneEvent = NULL; - - CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadStartEvent)); - gWinThreadStartEvent = NULL; - - for(int i = 0; i < gNumWinThreads; i++) { - CHECK_WIN_THREAD_FUNC(CloseHandle(gWinThreadWorkEvent[i])); - } - - for(int i = 0; i < kMaxWinThreads; i++) { - gWinThreadWorkEvent[i] = NULL; - } - - gNumWinThreads = 0; - } - break; - - case eThreadMode_None: - // Do nothing. - break; - } -} - -static inline DXGI_FORMAT GetNonSRGBFormat(DXGI_FORMAT f) { - switch(f) { - case DXGI_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM; - case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM; - default: assert(!"Unknown format!"); - } - return DXGI_FORMAT_R8G8B8A8_UNORM; -} - -// Compute an "error" texture that represents the absolute difference in color between an -// uncompressed texture and a compressed texture. -HRESULT ComputeError(ID3D11ShaderResourceView* uncompressedSRV, ID3D11ShaderResourceView* compressedSRV, ID3D11ShaderResourceView** errorSRV) -{ - HRESULT hr; - - // Query the texture description of the uncompressed texture. - ID3D11Resource* uncompRes; - gUncompressedSRV->GetResource(&uncompRes); - D3D11_TEXTURE2D_DESC uncompTexDesc; - ((ID3D11Texture2D*)uncompRes)->GetDesc(&uncompTexDesc); - - // Query the texture description of the uncompressed texture. - ID3D11Resource* compRes; - gCompressedSRV->GetResource(&compRes); - D3D11_TEXTURE2D_DESC compTexDesc; - ((ID3D11Texture2D*)compRes)->GetDesc(&compTexDesc); - - // Create a 2D resource without gamma correction for the two textures. - compTexDesc.Format = GetNonSRGBFormat(compTexDesc.Format); - uncompTexDesc.Format = GetNonSRGBFormat(uncompTexDesc.Format); - - ID3D11Device* device = DXUTGetD3D11Device(); - - ID3D11Texture2D* uncompTex; - device->CreateTexture2D(&uncompTexDesc, NULL, &uncompTex); - - ID3D11Texture2D* compTex; - device->CreateTexture2D(&compTexDesc, NULL, &compTex); - - // Create a shader resource view for the two textures. - D3D11_SHADER_RESOURCE_VIEW_DESC compSRVDesc; - compSRVDesc.Format = compTexDesc.Format; - compSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - compSRVDesc.Texture2D.MipLevels = compTexDesc.MipLevels; - compSRVDesc.Texture2D.MostDetailedMip = compTexDesc.MipLevels - 1; - ID3D11ShaderResourceView *compSRV; - V_RETURN(device->CreateShaderResourceView(compTex, &compSRVDesc, &compSRV)); - - D3D11_SHADER_RESOURCE_VIEW_DESC uncompSRVDesc; - uncompSRVDesc.Format = uncompTexDesc.Format; - uncompSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - uncompSRVDesc.Texture2D.MipLevels = uncompTexDesc.MipLevels; - uncompSRVDesc.Texture2D.MostDetailedMip = uncompTexDesc.MipLevels - 1; - ID3D11ShaderResourceView *uncompSRV; - V_RETURN(device->CreateShaderResourceView(uncompTex, &uncompSRVDesc, &uncompSRV)); - - // Create a 2D texture for the error texture. - ID3D11Texture2D* errorTex; - D3D11_TEXTURE2D_DESC errorTexDesc; - memcpy(&errorTexDesc, &uncompTexDesc, sizeof(D3D11_TEXTURE2D_DESC)); - errorTexDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - V_RETURN(device->CreateTexture2D(&errorTexDesc, NULL, &errorTex)); - - // Create a render target view for the error texture. - D3D11_RENDER_TARGET_VIEW_DESC errorRTVDesc; - errorRTVDesc.Format = errorTexDesc.Format; - errorRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - errorRTVDesc.Texture2D.MipSlice = 0; - ID3D11RenderTargetView* errorRTV; - V_RETURN(device->CreateRenderTargetView(errorTex, &errorRTVDesc, &errorRTV)); - - // Create a shader resource view for the error texture. - D3D11_SHADER_RESOURCE_VIEW_DESC errorSRVDesc; - errorSRVDesc.Format = errorTexDesc.Format; - errorSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - errorSRVDesc.Texture2D.MipLevels = errorTexDesc.MipLevels; - errorSRVDesc.Texture2D.MostDetailedMip = errorTexDesc.MipLevels - 1; - V_RETURN(device->CreateShaderResourceView(errorTex, &errorSRVDesc, errorSRV)); - - // Create a query for the GPU operations... - D3D11_QUERY_DESC GPUQueryDesc; - GPUQueryDesc.Query = D3D11_QUERY_EVENT; - GPUQueryDesc.MiscFlags = 0; - -#ifdef _DEBUG - D3D11_QUERY_DESC OcclusionQueryDesc; - OcclusionQueryDesc.Query = D3D11_QUERY_OCCLUSION; - OcclusionQueryDesc.MiscFlags = 0; - - D3D11_QUERY_DESC StatsQueryDesc; - StatsQueryDesc.Query = D3D11_QUERY_PIPELINE_STATISTICS; - StatsQueryDesc.MiscFlags = 0; -#endif - - ID3D11Query *GPUQuery; - V_RETURN(device->CreateQuery(&GPUQueryDesc, &GPUQuery)); - - ID3D11DeviceContext* deviceContext = DXUTGetD3D11DeviceContext(); - - deviceContext->CopyResource(compTex, compRes); - deviceContext->CopyResource(uncompTex, uncompRes); - -#ifdef _DEBUG - ID3D11Query *OcclusionQuery, *StatsQuery; - V_RETURN(device->CreateQuery(&OcclusionQueryDesc, &OcclusionQuery)); - V_RETURN(device->CreateQuery(&StatsQueryDesc, &StatsQuery)); - - deviceContext->Begin(OcclusionQuery); - deviceContext->Begin(StatsQuery); -#endif - - // Set the viewport to a 1:1 mapping of pixels to texels. - D3D11_VIEWPORT viewport; - viewport.Width = (FLOAT)errorTexDesc.Width; - viewport.Height = (FLOAT)errorTexDesc.Height; - viewport.MinDepth = 0; - viewport.MaxDepth = 1; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - deviceContext->RSSetViewports(1, &viewport); - - // Bind the render target view of the error texture. - ID3D11RenderTargetView* RTV[1] = { errorRTV }; - deviceContext->OMSetRenderTargets(1, RTV, NULL); - - // Clear the render target. - FLOAT color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - deviceContext->ClearRenderTargetView(errorRTV, color); - - // Set the input layout. - deviceContext->IASetInputLayout(gVertexLayout); - - // Set vertex buffer - UINT stride = sizeof(Vertex); - UINT offset = 0; - deviceContext->IASetVertexBuffers(0, 1, &gQuadVB, &stride, &offset); - - // Set the primitive topology - deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - // Set the shaders - deviceContext->VSSetShader(gVertexShader, NULL, 0); - deviceContext->PSSetShader(gRenderTexturePS, NULL, 0); - - // Set the texture sampler. - deviceContext->PSSetSamplers(0, 1, &gSamPoint); - - // Bind the textures. - ID3D11ShaderResourceView* SRV[2] = { compSRV, uncompSRV}; - deviceContext->PSSetShaderResources(0, 2, SRV); - - // Store the depth/stencil state. - StoreDepthStencilState(); - - // Disable depth testing. - V_RETURN(DisableDepthTest()); - - // Render a quad. - deviceContext->Draw(6, 0); - - // Restore the depth/stencil state. - RestoreDepthStencilState(); - - // Reset the render target. - RTV[0] = DXUTGetD3D11RenderTargetView(); - deviceContext->OMSetRenderTargets(1, RTV, DXUTGetD3D11DepthStencilView()); - - // Reset the viewport. - viewport.Width = (FLOAT)DXUTGetDXGIBackBufferSurfaceDesc()->Width; - viewport.Height = (FLOAT)DXUTGetDXGIBackBufferSurfaceDesc()->Height; - deviceContext->RSSetViewports(1, &viewport); - - deviceContext->End(GPUQuery); -#ifdef _DEBUG - deviceContext->End(OcclusionQuery); - deviceContext->End(StatsQuery); -#endif - - BOOL finishedGPU = false; - - // If we do not have a d3d 11 context, we will still hit this line and try to - // finish using the GPU. If this happens this enters an infinite loop. - int infLoopPrevention = 0; - while(!finishedGPU && ++infLoopPrevention < 10000) { - HRESULT ret; - V_RETURN(ret = deviceContext->GetData(GPUQuery, &finishedGPU, sizeof(BOOL), 0)); - if(ret != S_OK) - Sleep(1); - } - -#ifdef _DEBUG - UINT64 nPixelsWritten = 0; - deviceContext->GetData(OcclusionQuery, (void *)&nPixelsWritten, sizeof(UINT64), 0); - - D3D11_QUERY_DATA_PIPELINE_STATISTICS stats; - deviceContext->GetData(StatsQuery, (void *)&stats, sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS), 0); - - TCHAR nPixelsWrittenMsg[256]; - _stprintf(nPixelsWrittenMsg, _T("Pixels rendered during error computation: %d\n"), nPixelsWritten); - OutputDebugString(nPixelsWrittenMsg); -#endif - - // Create a copy of the error texture that is accessible by the CPU - ID3D11Texture2D* errorTexCopy; - D3D11_TEXTURE2D_DESC errorTexCopyDesc; - memcpy(&errorTexCopyDesc, &uncompTexDesc, sizeof(D3D11_TEXTURE2D_DESC)); - errorTexCopyDesc.Usage = D3D11_USAGE_STAGING; - errorTexCopyDesc.BindFlags = 0; - errorTexCopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - V_RETURN(device->CreateTexture2D(&errorTexCopyDesc, NULL, &errorTexCopy)); - - // Copy the error texture into the copy.... - deviceContext->CopyResource(errorTexCopy, errorTex); - - // Map the staging resource. - D3D11_MAPPED_SUBRESOURCE errorData; - V_RETURN(deviceContext->Map(errorTexCopy, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ, 0, &errorData)); - - // Calculate PSNR - ComputeRMSE((const BYTE *)(errorData.pData), errorTexCopyDesc.Width, errorTexCopyDesc.Height); - gSampleUI.SendEvent(IDC_RMSETEXT, true, gSampleUI.GetStatic(IDC_RMSETEXT)); - - // Unmap the staging resources. - deviceContext->Unmap(errorTexCopy, D3D11CalcSubresource(0, 0, 1)); - - // Release resources. - SAFE_RELEASE(errorRTV); - SAFE_RELEASE(errorTex); - SAFE_RELEASE(errorTexCopy); - SAFE_RELEASE(uncompRes); - SAFE_RELEASE(compRes); - SAFE_RELEASE(GPUQuery); - -#ifdef _DEBUG - SAFE_RELEASE(OcclusionQuery); - SAFE_RELEASE(StatsQuery); -#endif - - SAFE_RELEASE(compSRV); - SAFE_RELEASE(uncompSRV); - SAFE_RELEASE(compTex); - SAFE_RELEASE(uncompTex); - - return S_OK; -} - -// Recompresses the already loaded texture and recomputes the error. -HRESULT RecompressTexture() -{ - // Destroy any previously created textures. - SAFE_RELEASE(gErrorSRV); - SAFE_RELEASE(gCompressedSRV); - - // Compress the texture. - HRESULT hr; - V_RETURN(CompressTexture(gUncompressedSRV, &gCompressedSRV)); - - // Compute the error in the compressed texture. - V_RETURN(ComputeError(gUncompressedSRV, gCompressedSRV, &gErrorSRV)); - - return S_OK; -} - -// Store the depth-stencil state. -void StoreDepthStencilState() -{ - DXUTGetD3D11DeviceContext()->OMGetDepthStencilState(&gDepthStencilState, &gStencilReference); -} - -// Restore the depth-stencil state. -void RestoreDepthStencilState() -{ - DXUTGetD3D11DeviceContext()->OMSetDepthStencilState(gDepthStencilState, gStencilReference); -} - -// Disable depth testing. -HRESULT DisableDepthTest() -{ - D3D11_DEPTH_STENCIL_DESC depStenDesc; - ZeroMemory(&depStenDesc, sizeof(D3D11_DEPTH_STENCIL_DESC)); - depStenDesc.DepthEnable = FALSE; - depStenDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - depStenDesc.DepthFunc = D3D11_COMPARISON_LESS; - depStenDesc.StencilEnable = FALSE; - depStenDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - depStenDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - depStenDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - depStenDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depStenDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - ID3D11DepthStencilState* depStenState; - HRESULT hr; - V_RETURN(DXUTGetD3D11Device()->CreateDepthStencilState(&depStenDesc, &depStenState)); - - DXUTGetD3D11DeviceContext()->OMSetDepthStencilState(depStenState, 0); - - SAFE_RELEASE(depStenState); - - return S_OK; -} - -void ComputeRMSE(const BYTE *errorData, const INT width, const INT height) { - - const float *w = BC7C::GetErrorMetric(); - - const double wr = w[0]; - const double wg = w[1]; - const double wb = w[2]; - - double MSE = 0.0; - for(int i = 0; i < width; i++) { - for(int j = 0; j < height; j++) { - const INT pixel = ((const INT *)errorData)[j * width + i]; - - double dr = double(pixel & 0xFF) * wr; - double dg = double((pixel >> 8) & 0xFF) * wg; - double db = double((pixel >> 16) & 0xFF) * wb; - - const double pixelMSE = (double(dr) * double(dr)) + (double(dg) * double(dg)) + (double(db) * double(db)); - MSE += pixelMSE; - } - } - - MSE /= (double(width) * double(height)); -#ifdef REPORT_RMSE - gError = sqrt(MSE); -#else - double MAXI = (255.0 * wr) * (255.0 * wr) + (255.0 * wg) * (255.0 * wg) + (255.0 * wb) * (255.0 * wb); - gError= 10 * log10(MAXI/MSE); -#endif -} - -namespace DXTC -{ - VOID CompressImageDXT(const BYTE* inBuf, BYTE* outBuf, INT width, INT height) { - - // If we aren't multi-cored, then just run everything serially. - if(gNumProcessors <= 1) { - CompressImageDXTNoThread(inBuf, outBuf, width, height); - return; - } - - switch(gCompressionScheme->threadMode) { - case eThreadMode_None: - CompressImageDXTNoThread(inBuf, outBuf, width, height); - break; - case eThreadMode_TBB: - CompressImageDXTTBB(inBuf, outBuf, width, height); - break; - case eThreadMode_Win32: - CompressImageDXTWIN(inBuf, outBuf, width, height); - break; - } - } - - CompressionFunc GetCompressionFunc() { - switch(gCompressionScheme->instrSet) - { - case eInstrSet_SSE: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: return DXTC::CompressImageDXT1SSE2; - case eCompType_DXT5: return DXTC::CompressImageDXT5SSE2; - case eCompType_BC7: return BC7C::CompressImageBC7SIMD; - } - } - break; - - case eInstrSet_Scalar: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: return DXTC::CompressImageDXT1; - case eCompType_DXT5: return DXTC::CompressImageDXT5; - case eCompType_BC7: return BC7C::CompressImageBC7; - } - } - break; - -#ifdef ENABLE_AVX2 - case eInstrSet_AVX2: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: return DXTC::CompressImageDXT1AVX2; - case eCompType_DXT5: return DXTC::CompressImageDXT5AVX2; - } - } -#endif - } - return NULL; - } - - void CompressImageDXTNoThread(const BYTE* inBuf, BYTE* outBuf, INT width, INT height) { - - CompressionFunc cmpFunc = GetCompressionFunc(); - - if(cmpFunc == NULL) { - OutputDebugString(L"DXTC::CompressImageDXTNoThread -- Compression Scheme not implemented!\n"); - return; - } - - // Do the compression. - (*cmpFunc)(inBuf, outBuf, width, height); - } - - // Use the TBB task manager to compress an image with DXT compression. - VOID CompressImageDXTTBB(const BYTE* inBuf, BYTE* outBuf, INT width, INT height) - { - // Initialize the data. - DXTTaskData data; - data.inBuf = inBuf; - data.outBuf = outBuf; - data.width = width; - data.height = height; - data.numBlocks = width * height / 16; - if(gCompressionScheme->instrSet == eInstrSet_AVX2) { - data.numBlocks = width * height / 32; - } - data.kBlocksPerTask = gBlocksPerTask; - - // Compute the task count. - UINT taskCount = (UINT)ceil((float)data.numBlocks / gBlocksPerTask); - - // Create the task set. - TASKSETFUNC taskFunc = NULL; - switch(gCompressionScheme->instrSet) - { - case eInstrSet_SSE: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: taskFunc = DXTC::CompressImageDXT1SSE2Task; break; - case eCompType_DXT5: taskFunc = DXTC::CompressImageDXT5SSE2Task; break; - } - } - break; - - case eInstrSet_Scalar: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: taskFunc = DXTC::CompressImageDXT1Task; break; - case eCompType_DXT5: taskFunc = DXTC::CompressImageDXT5Task; break; - } - } - break; - -#ifdef ENABLE_AVX2 - case eInstrSet_AVX2: - { - switch(gCompressionScheme->type) { - case eCompType_DXT1: taskFunc = DXTC::CompressImageDXT1AVX2Task; break; - case eCompType_DXT5: taskFunc = DXTC::CompressImageDXT5AVX2Task; break; - } - } - break; -#endif - } - - TASKSETHANDLE taskSet; - gTaskMgr.CreateTaskSet(taskFunc, &data, taskCount, NULL, 0, "Fast Texture Compression", &taskSet); - if(taskSet == TASKSETHANDLE_INVALID) - { - return; - } - - // Wait for the task set. - gTaskMgr.WaitForSet(taskSet); - - // Release the task set. - gTaskMgr.ReleaseHandle(taskSet); - taskSet = TASKSETHANDLE_INVALID; - } - - int GetBlocksPerLoop() { - if(gCompressionScheme->instrSet == eInstrSet_AVX2) - return 2; - return 1; - } - - int GetBytesPerBlock() { - switch(gCompressionScheme->type) { - default: - case eCompType_DXT1: - return 8; - - case eCompType_DXT5: - case eCompType_BC7: - return 16; - } - } - - VOID CompressImageDXTWIN(const BYTE* inBuf, BYTE* outBuf, INT width, INT height) { - - const int numThreads = gNumWinThreads; - const int blocksPerLoop = GetBlocksPerLoop(); - const int bytesPerBlock = GetBytesPerBlock(); - - // We want to split the data evenly among all threads. - const int kNumPixels = width * height; - const int kNumBlocks = kNumPixels >> (3 + blocksPerLoop); - const int kBlocksPerRow = width >> (1 + blocksPerLoop); - - const int kBlocksPerThread = kNumBlocks / numThreads; - const int kBlocksPerColumn = height >> 2; - const int kBlockRowsPerThread = kBlocksPerThread / kBlocksPerRow; - const int kBlockColsPerThread = kBlocksPerThread % kBlocksPerRow; - const int kOffsetPerThread = kBlockRowsPerThread * width * 4 * 4 + kBlockColsPerThread * 4 * 4 * (blocksPerLoop); - const int kHeightPerThread = (blocksPerLoop * 16 * kBlocksPerThread) / width; - - CompressionFunc cmpFunc = GetCompressionFunc(); - if(cmpFunc == NULL) { - OutputDebugString(L"DXTC::CompressImageDXTNoThread -- Compression Scheme not implemented!\n"); - return; - } - - // Load the threads. - for(int threadIdx = 0; threadIdx < numThreads; threadIdx++) { - - WinThreadData *data = &gWinThreadData[threadIdx]; - data->inBuf = inBuf + (threadIdx * kOffsetPerThread); - data->outBuf = outBuf + (threadIdx * kBlocksPerThread * blocksPerLoop * bytesPerBlock); - data->width = width; - data->height = kHeightPerThread; - data->cmpFunc = cmpFunc; - data->state = eThreadState_DataLoaded; - data->threadIdx = threadIdx; - } - - // Send the event for the threads to start. - CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadDoneEvent)); - CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadStartEvent)); - - // Wait for all the threads to finish - if(WAIT_FAILED == WaitForMultipleObjects(numThreads, gWinThreadWorkEvent, TRUE, INFINITE)) - ReportWinThreadError(TEXT("CompressImageDXTWIN -- WaitForMultipleObjects")); - - // Reset the start event - CHECK_WIN_THREAD_FUNC(ResetEvent(gWinThreadStartEvent)); - CHECK_WIN_THREAD_FUNC(SetEvent(gWinThreadDoneEvent)); - } - - DWORD WINAPI CompressImageDXTWinThread( LPVOID lpParam ) { - WinThreadData *data = (WinThreadData *)lpParam; - - while(data->state != eThreadState_Done) { - - if(WAIT_FAILED == WaitForSingleObject(gWinThreadStartEvent, INFINITE)) - ReportWinThreadError(TEXT("CompressImageDXTWinThread -- WaitForSingleObject")); - - if(data->state == eThreadState_Done) - break; - - data->state = eThreadState_Running; - (*(data->cmpFunc))(data->inBuf, data->outBuf, data->width, data->height); - - data->state = eThreadState_WaitForData; - - HANDLE workEvent = gWinThreadWorkEvent[data->threadIdx]; - if(WAIT_FAILED == SignalObjectAndWait(workEvent, gWinThreadDoneEvent, INFINITE, FALSE)) - ReportWinThreadError(TEXT("CompressImageDXTWinThread -- SignalObjectAndWait")); - } - - return 0; - } -} diff --git a/CLTool/StopWatch.cpp b/Core/src/StopWatch.cpp similarity index 100% rename from CLTool/StopWatch.cpp rename to Core/src/StopWatch.cpp diff --git a/CLTool/StopWatch.h b/Core/src/StopWatch.h similarity index 100% rename from CLTool/StopWatch.h rename to Core/src/StopWatch.h