diff options
| author | lbavoil <[email protected]> | 2016-08-08 15:45:59 +0200 |
|---|---|---|
| committer | lbavoil <[email protected]> | 2016-08-08 15:45:59 +0200 |
| commit | 4801bf501ea20940640f0aec98ebb66cc96805a6 (patch) | |
| tree | 32f3b0e3397fd1e364d1e19742c2d9c31985ed92 /test/src/D3D11/TwoPassBlend.cpp | |
| parent | HBAO+ 3.0.0.20735892 (diff) | |
| download | hbaoplus-4801bf501ea20940640f0aec98ebb66cc96805a6.tar.xz hbaoplus-4801bf501ea20940640f0aec98ebb66cc96805a6.zip | |
Add DX11 test app for the TwoPassBlending feature.
Diffstat (limited to 'test/src/D3D11/TwoPassBlend.cpp')
| -rw-r--r-- | test/src/D3D11/TwoPassBlend.cpp | 1693 |
1 files changed, 1693 insertions, 0 deletions
diff --git a/test/src/D3D11/TwoPassBlend.cpp b/test/src/D3D11/TwoPassBlend.cpp new file mode 100644 index 0000000..d28f8d6 --- /dev/null +++ b/test/src/D3D11/TwoPassBlend.cpp @@ -0,0 +1,1693 @@ +/* +* Copyright (c) 2008-2016, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include <DXUT.h> +#include <DXUTgui.h> +#include <DXUTmisc.h> +#include <DXUTCamera.h> +#include <DXUTSettingsDlg.h> +#include <SDKmisc.h> + +#include "..\..\..\src\Renderer_DX11.h" +#include "SceneRTs.h" +#include "Scene3D.h" +#include "GPUProfiler.h" + +#define ENABLE_MESHES 1 +#define ENABLE_SHOW_COLORS 0 +#define ENABLE_GBUFFER_NORMALS 1 +#define ENABLE_DEBUG_NORMALS 0 +#define ENABLE_SMALL_SCALE_AO 1 +#define ENABLE_LARGE_SCALE_AO 1 +#define ENABLE_BLUR_RADIUS 1 +#define ENABLE_BORDER_PIXELS 0 +#define ENABLE_FP16_VIEW_DEPTHS 1 +#define ENABLE_DEPTH_CLAMP_MODES 0 +#define ENABLE_BLUR_SHARPNESS 1 +#define ENABLE_BLUR_SHARPNESS_PROFILE 0 +#define ENABLE_BACKGROUND_AO 0 +#define ENABLE_FOREGROUND_AO 0 +#define ENABLE_VIEW_DEPTH_THRESHOLD 0 +#define ENABLE_INTERNAL_RENDER_TIMES 1 +#define ENABLE_HUD_BACKGROUND 0 +#define ENABLE_NVAPI 0 + +#define TEST_TWO_PASS_BLEND 1 +#define TEST_PARTIAL_VIEWPORT_DIMENSIONS 0 +#define TEST_PARTIAL_VIEWPORT_DEPTH_RANGE 0 +#define TEST_PRE_CREATE_RTS 1 +#define TEST_REVERSED_DEPTH_TEST 1 + +//-------------------------------------------------------------------------------------- +// Scene description +//-------------------------------------------------------------------------------------- + +#define FOVY (40.0f * D3DX_PI / 180.0f) +#define ZNEAR 0.01f +#define ZFAR 500.0f + +#define MESH_PATH L"..\\assets\\" + +MeshDescriptor g_MeshDesc[] = +{ + //{L"Sibenik", MESH_PATH L"sibenik.sdkmesh", SCENE_NO_GROUND_PLANE, SCENE_NO_SHADING, SCENE_USE_FIRST_PERSON_CAMERA, 0.005f }, + {L"AT-AT", MESH_PATH L"AT-AT.sdkmesh", SCENE_USE_GROUND_PLANE, SCENE_NO_SHADING, SCENE_USE_ORBITAL_CAMERA, 0.1f }, +}; + +//-------------------------------------------------------------------------------------- +// MSAA settings +//-------------------------------------------------------------------------------------- + +struct MSAADescriptor +{ + WCHAR Name[32]; + int SampleCount; +}; + +MSAADescriptor g_MSAADesc[] = +{ + {L"1x MSAA", 1}, + {L"2x MSAA", 2}, + {L"4x MSAA", 4}, + {L"8x MSAA", 8}, + {L"", 0}, +}; + +//-------------------------------------------------------------------------------------- +// GUI constants +//-------------------------------------------------------------------------------------- + +#define MAX_RADIUS_MULT 2.f +#define MAX_BACKGROUND_DEPTH 800.f +#define MAX_DEPTH_THRESHOLD 1.f +#define MAX_DEPTH_SHARPNESS 32.f +#define MAX_BLUR_SHARPNESS 32.f + +enum +{ + IDC_TOGGLEFULLSCREEN = 1, + IDC_TOGGLEREF, + IDC_CHANGEDEVICE, + IDC_CHANGESCENE, + IDC_CHANGEMSAA, +#if ENABLE_SHOW_COLORS + IDC_SHOW_COLORS, + IDC_SHOW_AO, +#endif +#if ENABLE_GBUFFER_NORMALS + IDC_USE_GBUFFER_NORMALS, +#endif +#if ENABLE_DEBUG_NORMALS + IDC_DEBUG_NORMALS, +#endif + IDC_RADIUS_STATIC, + IDC_RADIUS_SLIDER, +#if ENABLE_BACKGROUND_AO + IDC_BACKGROUND_DEPTH_STATIC, + IDC_BACKGROUND_DEPTH_SLIDER, +#endif +#if ENABLE_FOREGROUND_AO + IDC_FOREGROUND_DEPTH_STATIC, + IDC_FOREGROUND_DEPTH_SLIDER, +#endif +#if ENABLE_VIEW_DEPTH_THRESHOLD + IDC_DEPTH_THRESHOLD_STATIC, + IDC_DEPTH_THRESHOLD_SLIDER, + IDC_DEPTH_SHARPNESS_STATIC, + IDC_DEPTH_SHARPNESS_SLIDER, +#endif + IDC_BIAS_STATIC, + IDC_BIAS_SLIDER, + IDC_SMALL_SCALE_AO_STATIC, + IDC_SMALL_SCALE_AO_SLIDER, +#if ENABLE_LARGE_SCALE_AO + IDC_LARGE_SCALE_AO_STATIC, + IDC_LARGE_SCALE_AO_SLIDER, +#endif + IDC_EXPONENT_STATIC, + IDC_EXPONENT_SLIDER, +#if ENABLE_BLUR_RADIUS + IDC_BLUR_DISABLED, + IDC_BLUR_RADIUS_2, + IDC_BLUR_RADIUS_4, +#endif +#if ENABLE_BORDER_PIXELS + IDC_BORDER_PIXELS_0, + IDC_BORDER_PIXELS_64, + IDC_BORDER_PIXELS_128, +#endif +#if ENABLE_BLUR_SHARPNESS + IDC_BLUR_SHARPNESS_STATIC, + IDC_BLUR_SHARPNESS_SLIDER, +#endif +#if ENABLE_FP16_VIEW_DEPTHS + IDC_DEPTH_STORAGE_TYPE_FP16, + IDC_DEPTH_STORAGE_TYPE_FP32, +#endif +#if ENABLE_DEPTH_CLAMP_MODES + IDC_DEPTH_CLAMP_TO_EDGE, + IDC_DEPTH_CLAMP_TO_BORDER, +#endif +#if ENABLE_DEBUG_MODES + IDC_SHADER_TYPE_HBAO_PLUS, + IDC_SHADER_TYPE_DEBUG_HBAO_PLUS, +#endif +}; + +enum +{ + MSAA_MODE_1X = 0, + MSAA_MODE_2X, + MSAA_MODE_4X, + MSAA_MODE_8X, +}; + +#define UI_RADIUS_MULT L"Radius multiplier: " +#define UI_BACKGROUND_DEPTH L"Background depth:" +#define UI_FOREGROUND_DEPTH L"Foreground depth:" +#define UI_DEPTH_THRESHOLD L"Depth threshold: " +#define UI_DEPTH_SHARPNESS L"Depth sharpness: " +#define UI_AO_BIAS L"Bias: " +#define UI_POW_EXPONENT L"Power exponent: " +#define UI_SMALL_SCALE_AO L"Small-scale AO: " +#define UI_LARGE_SCALE_AO L"Large-scale AO: " +#define UI_BLUR_SHARPNESS L"Blur sharpness: " + +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- + +CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs +CD3DSettingsDlg g_SettingsDlg; // Device settings dialog +CDXUTDialog g_HUD; // dialog for standard controls +CDXUTTextHelper* g_pTxtHelper = NULL; +UINT g_TextLineHeight = 15; +bool g_DrawUI = true; +bool g_ShowAO = true; +bool g_BlurAO = true; +bool g_ShowColors = false; +bool g_PerSampleAO = true; +bool g_UseGBufferNormals = true; +bool g_DebugNormals = false; +GFSDK_SSAO_RenderMask g_RenderMask; +GFSDK_SSAO_Parameters g_AOParams; +GFSDK_SSAO_Context_D3D11* g_pAOContext = NULL; +GFSDK_SSAO_ProjectionMatrixDepthRange g_ProjectionMatrixDepthRange; + +D3D11_VIEWPORT g_BackBufferViewport; +UINT g_BackBufferWidth = 0; +UINT g_BackBufferHeight = 0; +UINT g_BorderPixels = 0; +SceneRenderer g_pSceneRenderer; +SceneRTs* g_pSceneRTs = NULL; + +#if TEST_TWO_PASS_BLEND +ID3D11BlendState* g_pMinBlendState; +ID3D11DepthStencilState* g_pStencilEqualState; +bool g_EnableTwoPassBlend = true; +#endif + +#if TEST_PARTIAL_VIEWPORT_DIMENSIONS +BOOL g_TestSmallViewport = FALSE; +#endif + +#if ENABLE_NVAPI +BOOL g_MonitorAvailableVidMem = FALSE; +BOOL g_MonitorNvGraphicsClock = TRUE; +#endif + +#if ENABLE_RENDER_TIMES +GFSDK::SSAO::GpuTimeRenderPassIndex GFSDK::SSAO::RenderTimes::CurrentPassIndex = GFSDK::SSAO::RENDER_PASS_0; +#endif + +SceneMesh g_SceneMeshes[SIZEOF_ARRAY(g_MeshDesc)]; +D3D11::GPUProfiler g_GPUProfiler; + +struct Scene +{ + Scene() + : pMesh(NULL) + { + } + SceneMesh *pMesh; +}; +Scene g_Scenes[SIZEOF_ARRAY(g_MeshDesc)]; +bool g_UseOrbitalCamera = true; + +int g_CurrentSceneId = 0; +int g_MSAACurrentSettings = MSAA_MODE_1X; + +#if 1 +#define RENDER_AO_WIDTH g_BackBufferWidth +#define RENDER_AO_HEIGHT g_BackBufferHeight +#else +#define RENDER_AO_WIDTH 3840 +#define RENDER_AO_HEIGHT 2160 +#endif + +//-------------------------------------------------------------------------------------- +class CPUTimer +{ +public: + CPUTimer(float* pTimeUS) + { + QueryPerformanceCounter(&m_StartTime); + m_pTimeUS = pTimeUS; + } + ~CPUTimer() + { + LARGE_INTEGER EndTime, Freq; + QueryPerformanceCounter(&EndTime); + QueryPerformanceFrequency(&Freq); + *m_pTimeUS = float((((double)EndTime.QuadPart) - ((double)m_StartTime.QuadPart))/((double)Freq.QuadPart) * 1.e6); + } + +private: + LARGE_INTEGER m_StartTime; + float* m_pTimeUS; +}; +float g_CPUTimeRenderAO = 0.f; +float g_CPUTimePreCreateRTs = 0.f; + +//-------------------------------------------------------------------------------------- +#if ENABLE_NVAPI +#include "NVAPI/nvapi.h" +//#pragma comment(lib, "nvapi") +class NvApiWrapper +{ +public: + struct MemInfo + { + unsigned int DedicatedVideoMemoryInMB; + unsigned int AvailableDedicatedVideoMemoryInMB; + unsigned int CurrentAvailableDedicatedVideoMemoryInMB; + }; + struct FrequencyInfo + { + unsigned int NvGraphicsClockInMhz; + }; + + NvApiWrapper() + : m_GpuHandle(0) + { + } + + void Init() + { + NvAPI_Status Status = NvAPI_Initialize(); + assert(Status == NVAPI_OK); + + NvPhysicalGpuHandle NvGpuHandles[NVAPI_MAX_PHYSICAL_GPUS] = { 0 }; + NvU32 NvGpuCount = 0; + Status = NvAPI_EnumPhysicalGPUs(NvGpuHandles, &NvGpuCount); + assert(Status == NVAPI_OK); + assert(NvGpuCount != 0); + m_GpuHandle = NvGpuHandles[0]; + } + + bool GetVideoMemoryInfo(MemInfo* pInfo) + { + NV_DISPLAY_DRIVER_MEMORY_INFO MemInfo = { 0 }; + MemInfo.version = NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2; + NvAPI_Status Status = NvAPI_GPU_GetMemoryInfo(m_GpuHandle, &MemInfo); + if (Status != NVAPI_OK) + { + return false; + } + + pInfo->DedicatedVideoMemoryInMB = MemInfo.dedicatedVideoMemory / 1024; + pInfo->AvailableDedicatedVideoMemoryInMB = MemInfo.availableDedicatedVideoMemory / 1024; + pInfo->CurrentAvailableDedicatedVideoMemoryInMB = MemInfo.curAvailableDedicatedVideoMemory / 1024; + return true; + } + + bool GetNVGraphicsClockMhz(FrequencyInfo *pInfo) + { + NV_GPU_CLOCK_FREQUENCIES table = { 0 }; + table.version = NV_GPU_CLOCK_FREQUENCIES_VER; + table.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ; + + NvAPI_Status Status = NvAPI_GPU_GetAllClockFrequencies(m_GpuHandle, &table); + if (Status != NVAPI_OK) + { + return false; + } + + if (!table.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].bIsPresent) + { + return false; + } + + NvU32 GraphicsClockInKhz = table.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency; + pInfo->NvGraphicsClockInMhz = NvU32((GraphicsClockInKhz + 500) / 1000); + return true; + } + +private: + NvPhysicalGpuHandle m_GpuHandle; +}; +NvApiWrapper g_NvApiWrapper; +#endif + +//-------------------------------------------------------------------------------------- +using namespace GFSDK; + +class TextRenderer +{ +public: + void Init(CDXUTDialogResourceManager* pManager) + { +#if ENABLE_HUD_BACKGROUND + const UINT NumTextLines = 5; + const float HudOpacity = 0.32f; + m_BackgroundQuad.Init(pManager); + m_BackgroundQuad.SetLocation(0,0); + m_BackgroundQuad.SetSize(260, g_TextLineHeight * NumTextLines + 15); + m_BackgroundQuad.SetBackgroundColors(D3DCOLOR_COLORVALUE(1,1,1,HudOpacity)); +#endif +#if ENABLE_NVAPI + g_NvApiWrapper.Init(); +#endif + } + + void DrawText() + { + g_pTxtHelper->Begin(); + + g_pTxtHelper->SetInsertionPos(5, 5); + g_pTxtHelper->SetForegroundColor(D3DXCOLOR(0.f, 0.f, 0.f, 1.f)); + + GFSDK_SSAO_Version Version; + GFSDK_SSAO_Status Status; + Status = GFSDK_SSAO_GetVersion(&Version); + assert(Status == GFSDK_SSAO_OK); + + WCHAR VersionString[128]; + StringCchPrintf(VersionString, SIZEOF_ARRAY(VersionString), L"%d.%d.%d.%d", Version.Major, Version.Minor, Version.Branch, Version.Revision); + g_pTxtHelper->DrawFormattedTextLine(L"D3D11 HBAO+ %s\n", VersionString); + + g_pTxtHelper->DrawTextLine(DXUTGetDeviceStats()); + + UINT AOWidth = g_pSceneRTs->Width; + UINT AOHeight = g_pSceneRTs->Height; + g_pTxtHelper->DrawFormattedTextLine(L"AO Resolution: %d x %d", AOWidth, AOHeight); + + g_pTxtHelper->DrawFormattedTextLine(L"ZNear: %g, ZFar: %g", g_ProjectionMatrixDepthRange.ZNear, g_ProjectionMatrixDepthRange.ZFar); + +#if ENABLE_RENDER_TIMES +#if ENABLE_INTERNAL_RENDER_TIMES +#if TEST_TWO_PASS_BLEND + for (UINT PassIndex = 0; PassIndex < GFSDK::SSAO::RENDER_PASS_COUNT; ++PassIndex) +#else + UINT PassIndex = 0; +#endif + { + g_pTxtHelper->DrawFormattedTextLine(L"GPU Times (ms): Total: %0.2f Z {%0.2f, %0.2f} AO {%0.2f, %0.2f, %0.2f} Blur {%0.2f, %0.2f}", + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_TOTAL], + // Z + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_LINEAR_Z], + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_DEINTERLEAVE_Z], + // AO + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_NORMAL], + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_COARSE_AO], + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_INTERLEAVE_AO], + // Blur + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_BLURX], + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[PassIndex][SSAO::REGIME_TIME_BLURY]); + } + + g_pTxtHelper->DrawFormattedTextLine(L"CPU Time (us): PreCreateRTs{%d} RenderAO{%d}", int(g_CPUTimePreCreateRTs), int(g_CPUTimeRenderAO)); +#else + g_pTxtHelper->DrawFormattedTextLine(L"HBAO+ GPU Time: %0.2f ms", + GFSDK::SSAO::D3D11::Renderer::s_RenderTimes.GPUTimeMS[SSAO::REGIME_TIME_TOTAL]); +#endif +#endif + + g_pTxtHelper->DrawFormattedTextLine(L"Allocated Video Memory: %d MB\n", g_pAOContext->GetAllocatedVideoMemoryBytes() / (1024*1024)); + +#if ENABLE_NVAPI + if (g_MonitorAvailableVidMem) + { + NvApiWrapper::MemInfo MemInfo = { 0 }; + g_NvApiWrapper.GetVideoMemoryInfo(&MemInfo); + g_pTxtHelper->DrawFormattedTextLine(L"NVAPI: Current Available Video Memory: %u MB", MemInfo.CurrentAvailableDedicatedVideoMemoryInMB); + } + if (g_MonitorNvGraphicsClock) + { + NvApiWrapper::FrequencyInfo FreqInfo = { 0 }; + g_NvApiWrapper.GetNVGraphicsClockMhz(&FreqInfo); + g_pTxtHelper->DrawFormattedTextLine(L"NVAPI Current NV GPU Graphics Clock: %d", FreqInfo.NvGraphicsClockInMhz); + } +#endif + + g_pTxtHelper->End(); + } + + void OnRender(float fElapsedTime) + { +#if ENABLE_HUD_BACKGROUND + m_BackgroundQuad.OnRender(fElapsedTime); +#endif + + DrawText(); + } + +private: + CDXUTDialog m_BackgroundQuad; +}; +TextRenderer g_TextRenderer; + +//-------------------------------------------------------------------------------------- +struct Cameras +{ + Cameras() + { + // Setup orbital camera + D3DXVECTOR3 vecEye(0.0f, 2.0f, 0.0f); + D3DXVECTOR3 vecAt (0.0f, 0.0f, 0.0f); + Orbital.SetViewParams(&vecEye, &vecAt); + Orbital.SetRadius(1.5f, 0.01f); + Orbital.SetButtonMasks(MOUSE_LEFT_BUTTON, MOUSE_WHEEL, 0); + + // Setup first-person camera + D3DXVECTOR3 sibenikVecEye(0.0960150138f, 0.0273544509f, -0.0185411610f); + D3DXVECTOR3 sibenikVecAt (-0.623801112f, -0.649074197f, -0.174454257f); + FirstPerson.SetViewParams(&sibenikVecEye, &sibenikVecAt); + FirstPerson.SetEnablePositionMovement(1); + FirstPerson.SetScalers(0.001f, 0.05f); + FirstPerson.SetRotateButtons( 1, 1, 1 ); + } + + void SetProjParameters(SceneRTs *pRTs) + { + float Fovy = 2.f * atanf( tanf(FOVY * 0.5f) * (1.f + float(pRTs->BorderPixels) / (0.5f * float(pRTs->OutputHeight)) ) ); + float AspectRatio = float(pRTs->OutputWidth + pRTs->BorderPixels * 2) / float(pRTs->OutputHeight + pRTs->BorderPixels * 2); + + Orbital.SetProjParams (Fovy, AspectRatio, ZNEAR, ZFAR); + Orbital.SetWindow (pRTs->OutputWidth, pRTs->OutputHeight); + FirstPerson.SetProjParams (Fovy, AspectRatio, ZNEAR, ZFAR); + +#if TEST_REVERSED_DEPTH_TEST + D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, Fovy, AspectRatio, FLT_MAX, ZNEAR); + ProjectionMatrix._33 = 0.f; +#endif + } + + CFirstPersonCamera FirstPerson; + CModelViewerCamera Orbital; +#if TEST_REVERSED_DEPTH_TEST + D3DXMATRIX ProjectionMatrix; +#endif +}; +Cameras g_Cameras; + +//-------------------------------------------------------------------------------------- +void GetAdapterDesc(ID3D11Device* pd3dDevice, DXGI_ADAPTER_DESC* pDesc) +{ + IDXGIDevice *pDXGIDevice = NULL; + pd3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + + IDXGIAdapter *pDXGIAdapter = NULL; + pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter); + + pDXGIAdapter->GetDesc(pDesc); + + SAFE_RELEASE(pDXGIAdapter); + SAFE_RELEASE(pDXGIDevice); +} + +//-------------------------------------------------------------------------------------- +char* GetOutputFilename(ID3D11Device* pd3dDevice, char *FileExtension) +{ + static DXGI_ADAPTER_DESC AdapterDesc; + if (AdapterDesc.DeviceId == 0) + { + GetAdapterDesc(pd3dDevice, &AdapterDesc); + } + + static char FilePath[256]; + sprintf_s(FilePath, sizeof(FilePath), "..\\..\\Bin\\D3D11\\D3D11_%S_%dx%d.%s", + AdapterDesc.Description, + g_pSceneRTs->Width, + g_pSceneRTs->Height, + FileExtension + ); + + return FilePath; +} + +//-------------------------------------------------------------------------------------- +void InitAOParams(GFSDK_SSAO_Parameters &AOParams) +{ + AOParams = GFSDK_SSAO_Parameters(); + AOParams.Radius = 2.f; + AOParams.Bias = 0.2f; +#if ENABLE_SMALL_SCALE_AO + AOParams.SmallScaleAO = 1.f; +#endif +#if ENABLE_LARGE_SCALE_AO + AOParams.LargeScaleAO = 1.f; +#endif + AOParams.PowerExponent = 2.f; + AOParams.Blur.Enable = g_BlurAO; + AOParams.Blur.Sharpness = 16.f; +#if ENABLE_BLUR_RADIUS + AOParams.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_4; +#endif +#if ENABLE_BLUR_SHARPNESS_PROFILE + AOParams.Blur.SharpnessProfile.Enable = TRUE; + AOParams.Blur.SharpnessProfile.ForegroundSharpnessScale = 16.f; + AOParams.Blur.SharpnessProfile.ForegroundViewDepth = 4.f; + AOParams.Blur.SharpnessProfile.BackgroundViewDepth = 5.f; +#endif +#if ENABLE_VIEW_DEPTH_THRESHOLD + AOParams.DepthThreshold.Enable = TRUE; + AOParams.DepthThreshold.MaxViewDepth = MAX_DEPTH_THRESHOLD; + AOParams.DepthThreshold.Sharpness = MAX_DEPTH_SHARPNESS; +#endif +#if ENABLE_BACKGROUND_AO + AOParams.BackgroundAO.Enable = TRUE; + AOParams.BackgroundAO.BackgroundViewDepth = MAX_BACKGROUND_DEPTH; +#endif +#if ENABLE_FOREGROUND_AO + AOParams.ForegroundAO.Enable = TRUE; + AOParams.ForegroundAO.ForegroundViewDepth = 0.f; +#endif +} + +//-------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------- +void ReallocateSceneRTs(ID3D11Device* pd3dDevice) +{ + { + SceneRTs::Desc desc; + desc.OutputWidth = RENDER_AO_WIDTH; + desc.OutputHeight = RENDER_AO_HEIGHT; + desc.BorderPixels = g_BorderPixels; + desc.SampleCount = g_MSAADesc[g_MSAACurrentSettings].SampleCount; + + SAFE_DELETE(g_pSceneRTs); + g_pSceneRTs = new SceneRTs(pd3dDevice, desc); + + g_Cameras.SetProjParameters(g_pSceneRTs); + } + +#if TEST_PRE_CREATE_RTS + { + CPUTimer timer(&g_CPUTimePreCreateRTs); + GFSDK_SSAO_Status status; + status = g_pAOContext->PreCreateRTs(g_AOParams, g_BackBufferWidth, g_BackBufferHeight); + assert(status == GFSDK_SSAO_OK); + } +#endif +} + +//-------------------------------------------------------------------------------------- +// This callback function is called immediately before a device is created to allow the +// application to modify the device settings. The supplied pDeviceSettings parameter +// contains the settings that the framework has selected for the new device, and the +// application can make any desired changes directly to this structure. Note however that +// DXUT will not correct invalid device settings so care must be taken +// to return valid device settings, otherwise CreateDevice() will fail. +//-------------------------------------------------------------------------------------- +bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext) +{ + assert(pDeviceSettings->ver == DXUT_D3D11_DEVICE); + + // Disable VSync + pDeviceSettings->d3d11.SyncInterval = 0; + + // Do not allocate any depth buffer in DXUT + pDeviceSettings->d3d11.AutoCreateDepthStencil = false; + +#if defined(DEBUG) + pDeviceSettings->d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + // For the first device created if it is a REF device, optionally display a warning dialog box + static bool s_bFirstTime = true; + if (s_bFirstTime) + { + s_bFirstTime = false; + if ((DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF) || + (DXUT_D3D11_DEVICE == pDeviceSettings->ver && + pDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE)) + { + DXUTDisplaySwitchingToREFWarning(pDeviceSettings->ver); + } + } + + return true; +} + +//-------------------------------------------------------------------------------------- +// 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; +} + +//-------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------- +void LoadScenes(ID3D11Device* pd3dDevice) +{ + int SceneId = 0; + +#if ENABLE_MESHES + // Load the sdkmesh data files + for (int i = 0; i < SIZEOF_ARRAY(g_MeshDesc); ++i) + { + if (FAILED(g_SceneMeshes[i].OnCreateDevice(pd3dDevice, g_MeshDesc[i]))) + { + MessageBox(NULL, L"Unable to create mesh", L"ERROR", MB_OK|MB_SETFOREGROUND|MB_TOPMOST); + PostQuitMessage(0); + } + g_Scenes[SceneId++].pMesh = &g_SceneMeshes[i]; + } +#endif +} + +//-------------------------------------------------------------------------------------- +#if TEST_TWO_PASS_BLEND +void CreateCustomBlendState(ID3D11Device* pd3dDevice) +{ + HRESULT hr; + + D3D11_BLEND_DESC BlendStateDesc; + BlendStateDesc.AlphaToCoverageEnable = FALSE; + BlendStateDesc.IndependentBlendEnable = TRUE; + + for (UINT i = 0; i < SIZEOF_ARRAY(BlendStateDesc.RenderTarget); ++i) + { + BlendStateDesc.RenderTarget[i].BlendEnable = FALSE; + BlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + } + + BlendStateDesc.RenderTarget[0].BlendEnable = TRUE; + BlendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; + + BlendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + BlendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + BlendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_MIN; + + BlendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; + BlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + BlendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + + V( pd3dDevice->CreateBlendState(&BlendStateDesc, &g_pMinBlendState) ); +} +#endif + +//-------------------------------------------------------------------------------------- +#if TEST_TWO_PASS_BLEND +void CreateCustomDepthStencilState(ID3D11Device* pd3dDevice) +{ + HRESULT hr; + + static D3D11_DEPTH_STENCIL_DESC DepthStencilStateDesc = + { + FALSE, //DepthEnable + D3D11_DEPTH_WRITE_MASK_ZERO, //DepthWriteMask + D3D11_COMPARISON_NEVER, //DepthFunc + TRUE, //StencilEnable + 0xFF, //StencilReadMask + 0, //StencilWriteMask + + { D3D11_STENCIL_OP_KEEP, //StencilFailOp + D3D11_STENCIL_OP_KEEP, //StencilDepthFailOp + D3D11_STENCIL_OP_KEEP, //StencilPassOp + D3D11_COMPARISON_EQUAL //StencilFunc + }, //FrontFace + + { D3D11_STENCIL_OP_KEEP, //StencilFailOp + D3D11_STENCIL_OP_KEEP, //StencilDepthFailOp + D3D11_STENCIL_OP_KEEP, //StencilPassOp + D3D11_COMPARISON_EQUAL //StencilFunc + } //BackFace + }; + + V(pd3dDevice->CreateDepthStencilState(&DepthStencilStateDesc, &g_pStencilEqualState)); +} +#endif + +//-------------------------------------------------------------------------------------- +// Create any D3D11 resources that aren't dependant on the back buffer +//-------------------------------------------------------------------------------------- +HRESULT CALLBACK OnD3D11CreateDevice(ID3D11Device* pD3D11Device, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext) +{ + HRESULT hr; + + DXUTTRACE(L"OnD3D11CreateDevice called\n"); + + SetCursor(LoadCursor(0, IDC_ARROW)); + + ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); // does not addref + V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice(pD3D11Device, pd3dImmediateContext) ); + V_RETURN( g_SettingsDlg.OnD3D11CreateDevice(pD3D11Device) ); + g_pTxtHelper = new CDXUTTextHelper(pD3D11Device, pd3dImmediateContext, &g_DialogResourceManager, g_TextLineHeight); + g_pSceneRenderer.OnCreateDevice(pD3D11Device, TEST_REVERSED_DEPTH_TEST); + + // Load meshes and bin files + LoadScenes(pD3D11Device); + + GFSDK_SSAO_CustomHeap CustomHeap; + CustomHeap.new_ = ::operator new; + CustomHeap.delete_ = ::operator delete; + + GFSDK_SSAO_Status status; + status = GFSDK_SSAO_CreateContext_D3D11(pD3D11Device, &g_pAOContext, &CustomHeap); + assert(status == GFSDK_SSAO_OK); + +#if TEST_TWO_PASS_BLEND + CreateCustomBlendState(pD3D11Device); + CreateCustomDepthStencilState(pD3D11Device); +#endif + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// SwapChain has changed and may have new attributes such as size. +// 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; + + DXUTTRACE(L"OnD3D11ResizedSwapChain called\n"); + + V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain(pd3dDevice, pBackBufferSurfaceDesc) ); + V_RETURN( g_SettingsDlg.OnD3D11ResizedSwapChain(pd3dDevice, pBackBufferSurfaceDesc) ); + + g_BackBufferWidth = pBackBufferSurfaceDesc->Width; + g_BackBufferHeight = pBackBufferSurfaceDesc->Height; + + g_BackBufferViewport.TopLeftX = 0.f; + g_BackBufferViewport.TopLeftY = 0.f; + g_BackBufferViewport.MinDepth = 0.f; + g_BackBufferViewport.MaxDepth = 1.f; + g_BackBufferViewport.Width = (FLOAT)g_BackBufferWidth; + g_BackBufferViewport.Height = (FLOAT)g_BackBufferHeight; + + UINT HudWidth = 256; + float HudOpacity = 0.32f; + g_HUD.SetLocation(g_BackBufferWidth - HudWidth, 0); + g_HUD.SetSize (HudWidth, g_BackBufferHeight); + g_HUD.SetBackgroundColors(D3DCOLOR_COLORVALUE(0,0,0,HudOpacity)); + + ReallocateSceneRTs(pd3dDevice); + + return hr; +} + +//-------------------------------------------------------------------------------------- +// Handle updates to the scene. This is called regardless of which D3D API is used +//-------------------------------------------------------------------------------------- +void CALLBACK OnFrameMove(double fTime, float fElapsedTime, void* pUserContext) +{ + SceneMesh *pSceneMesh = g_Scenes[g_CurrentSceneId].pMesh; + g_UseOrbitalCamera = pSceneMesh && pSceneMesh->UseOrbitalCamera(); + + if (g_UseOrbitalCamera) + { + g_Cameras.Orbital.FrameMove(fElapsedTime); + } + else + { + g_Cameras.FirstPerson.FrameMove(fElapsedTime); + } +} + +//-------------------------------------------------------------------------------------- +void InitSceneViewInfo(SceneViewInfo &ViewInfo, UINT PassIndex) +{ + // PassIndex==0 is drawing the ground plane and the background mesh + // PassIndex==1 is drawing the foreground mesh only + ViewInfo.UseGBufferNormals = g_UseGBufferNormals; + ViewInfo.AllowGroundPlane = PassIndex == 0; + ViewInfo.StencilRef = PassIndex == 0 ? 1 : 2; + + if (g_UseOrbitalCamera) + { + const float TranslationZ = PassIndex == 1 ? 0.f : 0.4f; + D3DXMATRIX TranslationMatrix; + D3DXMatrixTranslation(&TranslationMatrix, 0.f, 0.f, TranslationZ); + + ViewInfo.WorldViewMatrix = TranslationMatrix * (*g_Cameras.Orbital.GetWorldMatrix()) * (*g_Cameras.Orbital.GetViewMatrix()); + ViewInfo.ProjectionMatrix = *g_Cameras.Orbital.GetProjMatrix(); + } + else + { + D3DXMATRIX WorldMatrix; + D3DXMatrixRotationX(&WorldMatrix, -D3DX_PI * 0.5f); + ViewInfo.WorldViewMatrix = WorldMatrix * (*g_Cameras.FirstPerson.GetViewMatrix()); + ViewInfo.ProjectionMatrix = *g_Cameras.FirstPerson.GetProjMatrix(); + } + +#if TEST_REVERSED_DEPTH_TEST + ViewInfo.ProjectionMatrix = g_Cameras.ProjectionMatrix; +#endif +} + +//-------------------------------------------------------------------------------------- +void RenderAOFromMesh(ID3D11Device* pd3dDevice, + ID3D11DeviceContext* pd3dImmediateContext, + ID3D11RenderTargetView* pBackBufferRTV, + SceneMesh *pMesh) +{ + //-------------------------------------------------------------------------------------- + // Set viewport + //-------------------------------------------------------------------------------------- + D3D11_VIEWPORT Viewport; + Viewport.TopLeftX = 0.f; + Viewport.TopLeftY = 0.f; + Viewport.MinDepth = 0.f; + Viewport.MaxDepth = 1.f; + Viewport.Width = FLOAT(g_pSceneRTs->Width); + Viewport.Height = FLOAT(g_pSceneRTs->Height); + +#if TEST_PARTIAL_VIEWPORT_DEPTH_RANGE + Viewport.MinDepth = 0.2f; + Viewport.MaxDepth = 0.8f; +#endif + + pd3dImmediateContext->RSSetViewports(1, &Viewport); + +#if TEST_PARTIAL_VIEWPORT_DIMENSIONS + if (g_TestSmallViewport) + { + Viewport.TopLeftX = 100.f; + Viewport.TopLeftY = 100.f; + Viewport.Width -= 200.f; + Viewport.Height -= 200.f; + } +#endif + + //-------------------------------------------------------------------------------------- + // Clear output AO render target + //-------------------------------------------------------------------------------------- + float ClearColor[4] = { 1.f, 1.f, 1.f, 0.f }; + pd3dImmediateContext->ClearRenderTargetView(g_pSceneRTs->ColorRTV, ClearColor); + + //-------------------------------------------------------------------------------------- + // Clear scene depth-stencil buffer + //-------------------------------------------------------------------------------------- +#if TEST_REVERSED_DEPTH_TEST + pd3dImmediateContext->ClearDepthStencilView(g_pSceneRTs->DepthStencilDSV, D3D11_CLEAR_DEPTH, 0.0, 0); +#else + pd3dImmediateContext->ClearDepthStencilView(g_pSceneRTs->DepthStencilDSV, D3D11_CLEAR_DEPTH, 1.0, 0); +#endif + +#if TEST_TWO_PASS_BLEND + for (UINT PassIndex = 0; PassIndex < 2; ++PassIndex) + { + GFSDK::SSAO::RenderTimes::CurrentPassIndex = (GFSDK::SSAO::GpuTimeRenderPassIndex)PassIndex; +#else + UINT PassIndex = 0; +#endif + + SceneViewInfo ViewInfo; + InitSceneViewInfo(ViewInfo, PassIndex); + + //-------------------------------------------------------------------------------------- + // Render depth with the Scene3D class + //-------------------------------------------------------------------------------------- + if (ViewInfo.UseGBufferNormals) + { + ID3D11RenderTargetView* pMRTs[] = { NULL, g_pSceneRTs->NormalRTV }; + pd3dImmediateContext->OMSetRenderTargets(SIZEOF_ARRAY(pMRTs), pMRTs, g_pSceneRTs->DepthStencilDSV); + } + else + { + pd3dImmediateContext->OMSetRenderTargets(0, NULL, g_pSceneRTs->DepthStencilDSV); + } + + g_pSceneRenderer.RenderMesh(pd3dImmediateContext, &ViewInfo, pMesh); + + //-------------------------------------------------------------------------------------- + // Render the SSAO + //-------------------------------------------------------------------------------------- + if (g_ShowAO) + { + GFSDK_SSAO_InputData_D3D11 Input; + +#if TEST_PARTIAL_VIEWPORT_DEPTH_RANGE + Input.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS_SUB_RANGE; +#else + Input.DepthData.DepthTextureType = GFSDK_SSAO_HARDWARE_DEPTHS; +#endif + Input.DepthData.pFullResDepthTextureSRV = g_pSceneRTs->DepthStencilSRV; + Input.DepthData.ProjectionMatrix.Data = GFSDK_SSAO_Float4x4((CONST FLOAT*)ViewInfo.ProjectionMatrix); + Input.DepthData.ProjectionMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + Input.DepthData.MetersToViewSpaceUnits = pMesh->GetSceneScale(); + +#if TEST_PARTIAL_VIEWPORT_DIMENSIONS + Input.DepthData.Viewport.Enable = TRUE; + Input.DepthData.Viewport.TopLeftX = (GFSDK_SSAO_UINT)Viewport.TopLeftX; + Input.DepthData.Viewport.TopLeftY = (GFSDK_SSAO_UINT)Viewport.TopLeftY; + Input.DepthData.Viewport.Width = (GFSDK_SSAO_UINT)Viewport.Width; + Input.DepthData.Viewport.Height = (GFSDK_SSAO_UINT)Viewport.Height; + Input.DepthData.Viewport.MinDepth = Viewport.MinDepth; + Input.DepthData.Viewport.MaxDepth = Viewport.MaxDepth; +#endif + + if (ViewInfo.UseGBufferNormals) + { + Input.NormalData.Enable = TRUE; + Input.NormalData.pFullResNormalTextureSRV = g_pSceneRTs->NormalSRV; + Input.NormalData.WorldToViewMatrix.Data = GFSDK_SSAO_Float4x4((CONST FLOAT*)ViewInfo.WorldViewMatrix); + Input.NormalData.WorldToViewMatrix.Layout = GFSDK_SSAO_ROW_MAJOR_ORDER; + Input.NormalData.DecodeScale = 2.f; + Input.NormalData.DecodeBias = -1.f; + } + + GFSDK_SSAO_Output_D3D11 Output; + Output.pRenderTargetView = g_pSceneRTs->ColorRTV; + Output.Blend.Mode = GFSDK_SSAO_OVERWRITE_RGB; + +#if TEST_TWO_PASS_BLEND + if (PassIndex == 1) + { + Output.TwoPassBlend.Enable = g_EnableTwoPassBlend; + Output.TwoPassBlend.pDepthStencilView = g_pSceneRTs->DepthStencilDSV; + + // No blending for stencil == 2 (foreground mesh, rendered last) + Output.TwoPassBlend.FirstPass.Blend.Mode = GFSDK_SSAO_OVERWRITE_RGB; + Output.TwoPassBlend.FirstPass.DepthStencil.Mode = GFSDK_SSAO_CUSTOM_DEPTH_STENCIL; + Output.TwoPassBlend.FirstPass.DepthStencil.CustomState.pDepthStencilState = g_pStencilEqualState; + Output.TwoPassBlend.FirstPass.DepthStencil.CustomState.StencilRef = 2; + + // MIN blending for stencil == 1 + Output.TwoPassBlend.SecondPass.Blend.Mode = GFSDK_SSAO_CUSTOM_BLEND; + Output.TwoPassBlend.SecondPass.Blend.CustomState.pBlendState = g_pMinBlendState; + Output.TwoPassBlend.SecondPass.DepthStencil.Mode = GFSDK_SSAO_CUSTOM_DEPTH_STENCIL; + Output.TwoPassBlend.SecondPass.DepthStencil.CustomState.pDepthStencilState = g_pStencilEqualState; + Output.TwoPassBlend.SecondPass.DepthStencil.CustomState.StencilRef = 1; + } +#endif + + { + CPUTimer timer(&g_CPUTimeRenderAO); + GFSDK_SSAO_Status status; + status = g_pAOContext->RenderAO(pd3dImmediateContext, Input, g_AOParams, Output, g_RenderMask); + assert(status == GFSDK_SSAO_OK); + } + + { + GFSDK_SSAO_Status status; + status = g_pAOContext->GetProjectionMatrixDepthRange(Input, g_ProjectionMatrixDepthRange); + assert(status == GFSDK_SSAO_OK); + } + } + +#if TEST_TWO_PASS_BLEND + } +#endif + + //-------------------------------------------------------------------------------------- + // Copy/resolve colors + //-------------------------------------------------------------------------------------- + + D3D11_BOX SrcBox; + SrcBox.left = g_BorderPixels; + SrcBox.right = g_pSceneRTs->OutputWidth + g_BorderPixels; + SrcBox.top = g_BorderPixels; + SrcBox.bottom = g_pSceneRTs->OutputHeight + g_BorderPixels; + SrcBox.front = 0; + SrcBox.back = 1; + + if (g_pSceneRTs->SampleCount > 1) + { + pd3dImmediateContext->ResolveSubresource(g_pSceneRTs->ResolvedColorTexture, 0, g_pSceneRTs->ColorTexture, 0, DXGI_FORMAT_R8G8B8A8_UNORM); + pd3dImmediateContext->CopySubresourceRegion(g_pSceneRTs->OutputTexture, 0, 0, 0, 0, g_pSceneRTs->ResolvedColorTexture, 0, &SrcBox); + } + else + { + pd3dImmediateContext->CopySubresourceRegion(g_pSceneRTs->OutputTexture, 0, 0, 0, 0, g_pSceneRTs->ColorTexture, 0, &SrcBox); + } + + //-------------------------------------------------------------------------------------- + // Dump screenshot on first frame + //-------------------------------------------------------------------------------------- + + static bool DumpedShot = false; + if (!DumpedShot) + { + DumpedShot = true; + + HRESULT hr; + hr = D3DX11SaveTextureToFileA(pd3dImmediateContext, g_pSceneRTs->OutputTexture, D3DX11_IFF_BMP, GetOutputFilename(pd3dDevice,"bmp")); + assert(hr == S_OK); + } + + //-------------------------------------------------------------------------------------- + // Copy/stretch the output colors to the backbuffer + //-------------------------------------------------------------------------------------- + + pd3dImmediateContext->OMSetRenderTargets(1, &pBackBufferRTV, NULL); + pd3dImmediateContext->RSSetViewports(1, &g_BackBufferViewport); + g_pSceneRenderer.CopyColors(pd3dImmediateContext, g_pSceneRTs->OutputSRV); +} + +//-------------------------------------------------------------------------------------- +// Callback function that renders the frame. This function sets up the rendering +// matrices and renders the scene and UI. +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11FrameRender(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, + double fTime, float fElapsedTime, void* pUserContext) +{ + // If the settings dialog is being shown, then render it instead of rendering the app's scene + if (g_SettingsDlg.IsActive()) + { + g_SettingsDlg.OnRender(fElapsedTime); + return; + } + + // Reallocate the render targets and depth buffer if the MSAA mode has been changed in the GUI. + int SelectedId = g_HUD.GetComboBox(IDC_CHANGEMSAA)->GetSelectedIndex(); + if (g_MSAACurrentSettings != SelectedId) + { + g_MSAACurrentSettings = SelectedId; + ReallocateSceneRTs(pd3dDevice); + } + + if (g_BorderPixels != g_pSceneRTs->BorderPixels) + { + ReallocateSceneRTs(pd3dDevice); + } + + SceneMesh *pMesh = g_Scenes[g_CurrentSceneId].pMesh; + + // These have no effect if the mesh is not rendered + g_HUD.GetComboBox(IDC_CHANGEMSAA)->SetVisible(pMesh != NULL); + +#if ENABLE_BLUR_RADIUS + g_HUD.GetStatic(IDC_BLUR_SHARPNESS_STATIC)->SetVisible(g_BlurAO); + g_HUD.GetSlider(IDC_BLUR_SHARPNESS_SLIDER)->SetVisible(g_BlurAO); +#endif + + g_AOParams.Blur.Enable = g_BlurAO; + g_RenderMask = g_DebugNormals ? GFSDK_SSAO_RENDER_DEBUG_NORMAL : GFSDK_SSAO_RENDER_AO; + + ID3D11RenderTargetView* pBackBufferRTV = DXUTGetD3D11RenderTargetView(); // does not addref + + if (pMesh) + { + RenderAOFromMesh(pd3dDevice, + pd3dImmediateContext, + pBackBufferRTV, + pMesh); + } + + pd3dImmediateContext->RSSetViewports(1, &g_BackBufferViewport); + + if (!g_ShowColors && !g_ShowAO) + { + // If both "Show Colors" and "Show AO" are disabled in the GUI + float ClearColor[4] = { 0.0f, 0.0f, 0.0f }; + pd3dImmediateContext->ClearRenderTargetView(pBackBufferRTV, ClearColor); + } + + //-------------------------------------------------------------------------------------- + // Render the GUI + //-------------------------------------------------------------------------------------- + if (g_DrawUI && !g_GPUProfiler.IsProfiling()) + { + g_HUD.OnRender(fElapsedTime); + g_TextRenderer.OnRender(fElapsedTime); + } + + g_GPUProfiler.Tick(GFSDK::SSAO::D3D11::Renderer::s_RenderTimes, GetOutputFilename(pd3dDevice,"csv")); +} + +//-------------------------------------------------------------------------------------- +// Release D3D11 resources created in OnD3D11ResizedSwapChain +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11ReleasingSwapChain(void* pUserContext) +{ + DXUTTRACE(L"OnD3D11ReleasingSwapChain called\n"); + + g_DialogResourceManager.OnD3D11ReleasingSwapChain(); +} + +//-------------------------------------------------------------------------------------- +// This callback function will be called immediately after the Direct3D device has +// been destroyed, which generally happens as a result of application termination or +// windowed/full screen toggles. +//-------------------------------------------------------------------------------------- +void CALLBACK OnD3D11DestroyDevice(void* pUserContext) +{ + DXUTTRACE(L"OnD3D11DestroyDevice called\n"); + + g_DialogResourceManager.OnD3D11DestroyDevice(); + g_SettingsDlg.OnD3D11DestroyDevice(); + DXUTGetGlobalResourceCache().OnDestroyDevice(); + SAFE_DELETE(g_pTxtHelper); + + g_pSceneRenderer.OnDestroyDevice(); + +#if ENABLE_MESHES + for (int i = 0; i < SIZEOF_ARRAY(g_MeshDesc); i++) + { + g_SceneMeshes[i].OnDestroyDevice(); + } +#endif + + SAFE_DELETE(g_pSceneRTs); + +#if TEST_TWO_PASS_BLEND + SAFE_RELEASE(g_pMinBlendState); + SAFE_RELEASE(g_pStencilEqualState); +#endif + + SAFE_RELEASE(g_pAOContext); +} + +//-------------------------------------------------------------------------------------- +// Handle messages to the application +//-------------------------------------------------------------------------------------- +LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, + bool* pbNoFurtherProcessing, void* pUserContext) +{ + // Always allow dialog resource manager calls to handle global messages + // so GUI state is updated correctly + *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc(hWnd, uMsg, wParam, lParam); + if (*pbNoFurtherProcessing) + { + return 0; + } + + if (g_SettingsDlg.IsActive()) + { + g_SettingsDlg.MsgProc(hWnd, uMsg, wParam, lParam); + return 0; + } + + // Give the dialogs a chance to handle the message first + *pbNoFurtherProcessing = g_HUD.MsgProc(hWnd, uMsg, wParam, lParam); + if (*pbNoFurtherProcessing) + { + return 0; + } + + // Pass all windows messages to camera so it can respond to user input + if (g_UseOrbitalCamera) + { + g_Cameras.Orbital.HandleMessages(hWnd, uMsg, wParam, lParam); + } + else + { + g_Cameras.FirstPerson.HandleMessages(hWnd, uMsg, wParam, lParam); + } + + return 0; +} + +//-------------------------------------------------------------------------------------- +// 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: + { + g_SettingsDlg.SetActive(!g_SettingsDlg.IsActive()); + break; + } + case IDC_CHANGESCENE: + { + CDXUTComboBox* pComboBox = (CDXUTComboBox*) pControl; + g_CurrentSceneId = pComboBox->GetSelectedIndex(); + break; + } +#if ENABLE_SHOW_COLORS + case IDC_SHOW_COLORS: + { + g_ShowColors = g_HUD.GetCheckBox(IDC_SHOW_COLORS)->GetChecked(); + break; + } + case IDC_SHOW_AO: + { + g_ShowAO = g_HUD.GetCheckBox(IDC_SHOW_AO)->GetChecked(); + break; + } +#endif +#if ENABLE_GBUFFER_NORMALS + case IDC_USE_GBUFFER_NORMALS: + { + g_UseGBufferNormals = g_HUD.GetCheckBox(IDC_USE_GBUFFER_NORMALS)->GetChecked(); + break; + } +#endif +#if ENABLE_DEBUG_NORMALS + case IDC_DEBUG_NORMALS: + { + g_DebugNormals = g_HUD.GetCheckBox(IDC_DEBUG_NORMALS)->GetChecked(); + break; + } +#endif + case IDC_RADIUS_SLIDER: + { + g_AOParams.Radius = (float) g_HUD.GetSlider(IDC_RADIUS_SLIDER)->GetValue() * MAX_RADIUS_MULT / 100.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_RADIUS_MULT L"%0.2f", g_AOParams.Radius); + g_HUD.GetStatic(IDC_RADIUS_STATIC)->SetText(sz); + + break; + } +#if ENABLE_BACKGROUND_AO + case IDC_BACKGROUND_DEPTH_SLIDER: + { + g_AOParams.BackgroundAO.BackgroundViewDepth = (float) g_HUD.GetSlider(IDC_BACKGROUND_DEPTH_SLIDER)->GetValue() * MAX_BACKGROUND_DEPTH / 10000.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_BACKGROUND_DEPTH L"%0.2f", g_AOParams.BackgroundAO.BackgroundViewDepth); + g_HUD.GetStatic(IDC_BACKGROUND_DEPTH_STATIC)->SetText(sz); + + break; + } +#endif +#if ENABLE_FOREGROUND_AO + case IDC_FOREGROUND_DEPTH_SLIDER: + { + g_AOParams.ForegroundAO.ForegroundViewDepth = (float)g_HUD.GetSlider(IDC_FOREGROUND_DEPTH_SLIDER)->GetValue() * MAX_BACKGROUND_DEPTH / 10000.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_FOREGROUND_DEPTH L"%0.2f", g_AOParams.ForegroundAO.ForegroundViewDepth); + g_HUD.GetStatic(IDC_FOREGROUND_DEPTH_STATIC)->SetText(sz); + + break; + } +#endif +#if ENABLE_VIEW_DEPTH_THRESHOLD + case IDC_DEPTH_THRESHOLD_SLIDER: + { + g_AOParams.DepthThreshold.MaxViewDepth = (float) g_HUD.GetSlider(IDC_DEPTH_THRESHOLD_SLIDER)->GetValue() * MAX_DEPTH_THRESHOLD / 10000.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_DEPTH_THRESHOLD L"%0.2f", g_AOParams.DepthThreshold.MaxViewDepth); + g_HUD.GetStatic(IDC_DEPTH_THRESHOLD_STATIC)->SetText(sz); + + break; + } + case IDC_DEPTH_SHARPNESS_SLIDER: + { + g_AOParams.DepthThreshold.Sharpness = (float) g_HUD.GetSlider(IDC_DEPTH_SHARPNESS_SLIDER)->GetValue() * MAX_DEPTH_SHARPNESS / 10000.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_DEPTH_SHARPNESS L"%0.1f", g_AOParams.DepthThreshold.Sharpness); + g_HUD.GetStatic(IDC_DEPTH_SHARPNESS_STATIC)->SetText(sz); + + break; + } +#endif + case IDC_BIAS_SLIDER: + { + g_AOParams.Bias = (float) g_HUD.GetSlider(IDC_BIAS_SLIDER)->GetValue() / 1000.f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_AO_BIAS L"%g", g_AOParams.Bias); + g_HUD.GetStatic(IDC_BIAS_STATIC)->SetText(sz); + + break; + } +#if ENABLE_SMALL_SCALE_AO + case IDC_SMALL_SCALE_AO_SLIDER: + { + g_AOParams.SmallScaleAO = (float)g_HUD.GetSlider(IDC_SMALL_SCALE_AO_SLIDER)->GetValue() / 100.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_SMALL_SCALE_AO L"%0.2f", g_AOParams.SmallScaleAO); + g_HUD.GetStatic(IDC_SMALL_SCALE_AO_STATIC)->SetText(sz); + + break; + } +#endif +#if ENABLE_LARGE_SCALE_AO + case IDC_LARGE_SCALE_AO_SLIDER: + { + g_AOParams.LargeScaleAO = (float)g_HUD.GetSlider(IDC_LARGE_SCALE_AO_SLIDER)->GetValue() / 100.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_LARGE_SCALE_AO L"%0.2f", g_AOParams.LargeScaleAO); + g_HUD.GetStatic(IDC_LARGE_SCALE_AO_STATIC)->SetText(sz); + + break; + } +#endif + case IDC_EXPONENT_SLIDER: + { + g_AOParams.PowerExponent = (float)g_HUD.GetSlider(IDC_EXPONENT_SLIDER)->GetValue() / 100.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_POW_EXPONENT L"%0.2f", g_AOParams.PowerExponent); + g_HUD.GetStatic(IDC_EXPONENT_STATIC)->SetText(sz); + + break; + } +#if ENABLE_BLUR_RADIUS + case IDC_BLUR_DISABLED: + { + g_BlurAO = false; + break; + } + case IDC_BLUR_RADIUS_2: + { + g_BlurAO = true; + g_AOParams.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_2; + break; + } + case IDC_BLUR_RADIUS_4: + { + g_BlurAO = true; + g_AOParams.Blur.Radius = GFSDK_SSAO_BLUR_RADIUS_4; + break; + } +#endif +#if ENABLE_BORDER_PIXELS + case IDC_BORDER_PIXELS_0: + { + g_BorderPixels = 0; + break; + } + case IDC_BORDER_PIXELS_64: + { + g_BorderPixels = 64; + break; + } + case IDC_BORDER_PIXELS_128: + { + g_BorderPixels = 128; + break; + } +#endif +#if ENABLE_BLUR_SHARPNESS + case IDC_BLUR_SHARPNESS_SLIDER: + { + g_AOParams.Blur.Sharpness = (float)g_HUD.GetSlider(IDC_BLUR_SHARPNESS_SLIDER)->GetValue() * MAX_BLUR_SHARPNESS / 10000.0f; + + WCHAR sz[100]; + StringCchPrintf(sz, 100, UI_BLUR_SHARPNESS L"%0.2f", g_AOParams.Blur.Sharpness); + g_HUD.GetStatic(IDC_BLUR_SHARPNESS_STATIC)->SetText(sz); + + break; + } +#endif +#if ENABLE_FP16_VIEW_DEPTHS + case IDC_DEPTH_STORAGE_TYPE_FP16: + { + g_AOParams.DepthStorage = GFSDK_SSAO_FP16_VIEW_DEPTHS; + break; + } + case IDC_DEPTH_STORAGE_TYPE_FP32: + { + g_AOParams.DepthStorage = GFSDK_SSAO_FP32_VIEW_DEPTHS; + break; + } +#endif +#if ENABLE_DEPTH_CLAMP_MODES + case IDC_DEPTH_CLAMP_TO_EDGE: + { + g_AOParams.DepthClampMode = GFSDK_SSAO_CLAMP_TO_EDGE; + break; + } + case IDC_DEPTH_CLAMP_TO_BORDER: + { + g_AOParams.DepthClampMode = GFSDK_SSAO_CLAMP_TO_BORDER; + break; + } +#endif +#if ENABLE_DEBUG_MODES + case IDC_SHADER_TYPE_HBAO_PLUS: + { + GFSDK::SSAO::D3D11::Renderer::s_AOShaderType = GFSDK::SSAO::D3D11::Renderer::NVSDK_HBAO_PLUS_PS; + break; + } + case IDC_SHADER_TYPE_DEBUG_HBAO_PLUS: + { + GFSDK::SSAO::D3D11::Renderer::s_AOShaderType = GFSDK::SSAO::D3D11::Renderer::NVSDK_DEBUG_HBAO_PLUS_PS; + break; + } +#endif + } +} + +//-------------------------------------------------------------------------------------- +// Handle key presses +//-------------------------------------------------------------------------------------- +void CALLBACK OnKeyboard(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext) +{ + if (bKeyDown) + { + switch (nChar) + { +#if TEST_PARTIAL_VIEWPORT_DIMENSIONS + case 'V': + g_TestSmallViewport = !g_TestSmallViewport; + break; +#endif +#if ENABLE_NVAPI + case 'M': + g_MonitorAvailableVidMem = !g_MonitorAvailableVidMem; + break; + case 'C': + g_MonitorNvGraphicsClock = !g_MonitorNvGraphicsClock; + break; +#endif + case 'U': + g_DrawUI = !g_DrawUI; + break; + case 'P': + g_GPUProfiler.StartProfiling(); + break; +#if TEST_TWO_PASS_BLEND + case 'T': + g_EnableTwoPassBlend = !g_EnableTwoPassBlend; + break; +#endif + } + } +} + +//-------------------------------------------------------------------------------------- +// Handle mouse button presses +//-------------------------------------------------------------------------------------- +void CALLBACK OnMouse(bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, + bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, + int xPos, int yPos, void* pUserContext) +{ +} + +//-------------------------------------------------------------------------------------- +// Call if device was removed. Return true to find a new device, false to quit +//-------------------------------------------------------------------------------------- +bool CALLBACK OnDeviceRemoved(void* pUserContext) +{ + return true; +} + +//-------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------- +void InitGUI() +{ + // Initialize dialogs + g_SettingsDlg.Init(&g_DialogResourceManager); + g_HUD.Init(&g_DialogResourceManager); + g_HUD.SetCallback(OnGUIEvent); + g_TextRenderer.Init(&g_DialogResourceManager); + + int iY = 10; + g_HUD.AddButton (IDC_TOGGLEFULLSCREEN, L"Toggle full screen" , 35, iY, 160, 22); + g_HUD.AddButton (IDC_TOGGLEREF, L"Toggle REF (F3)" , 35, iY += 24, 160, 22, VK_F3); + g_HUD.AddButton (IDC_CHANGEDEVICE, L"Change device (F2)" , 35, iY += 24, 160, 22, VK_F2); + iY += 20; + +#if ENABLE_SHOW_COLORS + g_HUD.AddCheckBox(IDC_SHOW_COLORS, L"Show Colors", 35, iY += 26, 125, 22, g_ShowColors); + g_HUD.AddCheckBox(IDC_SHOW_AO, L"Show HBAO+", 35, iY += 26, 125, 22, g_ShowAO); +#endif +#if ENABLE_DEBUG_NORMALS + g_HUD.AddCheckBox(IDC_DEBUG_NORMALS, L"Debug Normals", 35, iY += 26, 125, 22, g_DebugNormals); +#endif +#if ENABLE_GBUFFER_NORMALS + g_HUD.AddCheckBox(IDC_USE_GBUFFER_NORMALS, L"GBuffer Normals", 35, iY += 26, 125, 22, g_UseGBufferNormals); +#endif + iY += 20; + + CDXUTComboBox *pComboBox; + g_HUD.AddComboBox(IDC_CHANGESCENE, 35, iY += 24, 160, 22, 'S', false, &pComboBox); +#if ENABLE_MESHES + for (int i = 0; i < SIZEOF_ARRAY(g_MeshDesc); i++) + { + pComboBox->AddItem(g_MeshDesc[i].Name, NULL); + } +#endif + + g_HUD.AddComboBox(IDC_CHANGEMSAA, 35, iY += 24, 160, 22, 'N', false, &pComboBox); + for (int i = 0; g_MSAADesc[i].SampleCount != 0; i++) + { + pComboBox->AddItem(g_MSAADesc[i].Name, (void*)i); + } + pComboBox->SetSelectedByIndex(g_MSAACurrentSettings); + iY += 20; + + WCHAR sz[100]; + int dy = 20; + StringCchPrintf(sz, 100, UI_RADIUS_MULT L"%0.2f", g_AOParams.Radius); + g_HUD.AddStatic(IDC_RADIUS_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_RADIUS_SLIDER, 50, iY += dy, 100, 22, 0, 100, int(g_AOParams.Radius / MAX_RADIUS_MULT * 100)); + +#if ENABLE_VIEW_DEPTH_THRESHOLD + StringCchPrintf(sz, 100, UI_DEPTH_THRESHOLD L"%0.2f", g_AOParams.DepthThreshold.MaxViewDepth); + g_HUD.AddStatic(IDC_DEPTH_THRESHOLD_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_DEPTH_THRESHOLD_SLIDER, 50, iY += dy, 100, 22, 0, 10000, int(g_AOParams.DepthThreshold.MaxViewDepth / MAX_DEPTH_THRESHOLD * 10000)); + + StringCchPrintf(sz, 100, UI_DEPTH_SHARPNESS L"%0.1f", g_AOParams.DepthThreshold.Sharpness); + g_HUD.AddStatic(IDC_DEPTH_SHARPNESS_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_DEPTH_SHARPNESS_SLIDER, 50, iY += dy, 100, 22, 0, 10000, int(g_AOParams.DepthThreshold.Sharpness / MAX_DEPTH_SHARPNESS * 10000)); +#endif + +#if ENABLE_BACKGROUND_AO + StringCchPrintf(sz, 100, UI_BACKGROUND_DEPTH L"%0.2f", g_AOParams.BackgroundAO.BackgroundViewDepth); + g_HUD.AddStatic(IDC_BACKGROUND_DEPTH_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_BACKGROUND_DEPTH_SLIDER, 50, iY += dy, 100, 22, 1000, 10000, int(g_AOParams.BackgroundAO.BackgroundViewDepth / MAX_BACKGROUND_DEPTH * 10000)); +#endif + +#if ENABLE_FOREGROUND_AO + StringCchPrintf(sz, 100, UI_FOREGROUND_DEPTH L"%0.2f", g_AOParams.ForegroundAO.ForegroundViewDepth); + g_HUD.AddStatic(IDC_FOREGROUND_DEPTH_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_FOREGROUND_DEPTH_SLIDER, 50, iY += dy, 100, 22, 1000, 10000, int(g_AOParams.ForegroundAO.ForegroundViewDepth / MAX_BACKGROUND_DEPTH * 10000)); +#endif + + StringCchPrintf(sz, 100, UI_AO_BIAS L"%g", g_AOParams.Bias); + g_HUD.AddStatic(IDC_BIAS_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_BIAS_SLIDER, 50, iY += dy, 100, 22, 0, 500, int(g_AOParams.Bias * 1000)); + +#if ENABLE_SMALL_SCALE_AO + StringCchPrintf(sz, 100, UI_SMALL_SCALE_AO L"%0.2f", g_AOParams.SmallScaleAO); + g_HUD.AddStatic(IDC_SMALL_SCALE_AO_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_SMALL_SCALE_AO_SLIDER, 50, iY += dy, 100, 22, 0, 200, (int)(100.0f*g_AOParams.SmallScaleAO)); +#endif + +#if ENABLE_LARGE_SCALE_AO + StringCchPrintf(sz, 100, UI_LARGE_SCALE_AO L"%0.2f", g_AOParams.LargeScaleAO); + g_HUD.AddStatic(IDC_LARGE_SCALE_AO_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_LARGE_SCALE_AO_SLIDER, 50, iY += dy, 100, 22, 0, 200, (int)(100.0f*g_AOParams.LargeScaleAO)); +#endif + + StringCchPrintf(sz, 100, UI_POW_EXPONENT L"%0.2f", g_AOParams.PowerExponent); + g_HUD.AddStatic(IDC_EXPONENT_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_EXPONENT_SLIDER, 50, iY += dy, 100, 22, 0, 400, (int)(100.0f*g_AOParams.PowerExponent)); + +#if ENABLE_BLUR_SHARPNESS + StringCchPrintf(sz, 100, UI_BLUR_SHARPNESS L"%0.2f", g_AOParams.Blur.Sharpness); + g_HUD.AddStatic(IDC_BLUR_SHARPNESS_STATIC, sz, 35, iY += dy, 125, 22); + g_HUD.AddSlider(IDC_BLUR_SHARPNESS_SLIDER, 50, iY += dy, 100, 22, 0, 10000, int(g_AOParams.Blur.Sharpness / MAX_DEPTH_SHARPNESS * 10000)); +#endif + + UINT ButtonGroup = 0; + +#if ENABLE_DEBUG_MODES + ButtonGroup++; + iY += 20; + g_HUD.AddRadioButton( IDC_SHADER_TYPE_HBAO_PLUS, ButtonGroup, L"HBAO+", 35, iY += 24, 125, 22, (GFSDK::SSAO::D3D11::Renderer::s_AOShaderType == GFSDK::SSAO::D3D11::Renderer::NVSDK_HBAO_PLUS_PS) ); + g_HUD.AddRadioButton( IDC_SHADER_TYPE_DEBUG_HBAO_PLUS, ButtonGroup, L"DEBUG_HBAO+", 35, iY += 24, 125, 22, (GFSDK::SSAO::D3D11::Renderer::s_AOShaderType == GFSDK::SSAO::D3D11::Renderer::NVSDK_DEBUG_HBAO_PLUS_PS) ); +#endif + +#if ENABLE_BLUR_RADIUS + ButtonGroup++; + iY += 20; + g_HUD.AddRadioButton( IDC_BLUR_DISABLED, ButtonGroup, L"BLUR_DISABLED", 35, iY += 24, 125, 22, !g_BlurAO ); + g_HUD.AddRadioButton( IDC_BLUR_RADIUS_2, ButtonGroup, L"BLUR_RADIUS_2", 35, iY += 24, 125, 22, g_BlurAO && (g_AOParams.Blur.Radius == GFSDK_SSAO_BLUR_RADIUS_2) ); + g_HUD.AddRadioButton( IDC_BLUR_RADIUS_4, ButtonGroup, L"BLUR_RADIUS_4", 35, iY += 24, 125, 22, g_BlurAO && (g_AOParams.Blur.Radius == GFSDK_SSAO_BLUR_RADIUS_4) ); +#endif + +#if ENABLE_FP16_VIEW_DEPTHS + ButtonGroup++; + iY += 20; + g_HUD.AddRadioButton( IDC_DEPTH_STORAGE_TYPE_FP16, ButtonGroup, L"FP16_VIEW_DEPTHS", 35, iY += 24, 125, 22, (g_AOParams.DepthStorage == GFSDK_SSAO_FP16_VIEW_DEPTHS) ); + g_HUD.AddRadioButton( IDC_DEPTH_STORAGE_TYPE_FP32, ButtonGroup, L"FP32_VIEW_DEPTHS", 35, iY += 24, 125, 22, (g_AOParams.DepthStorage == GFSDK_SSAO_FP32_VIEW_DEPTHS) ); +#endif + +#if ENABLE_DEPTH_CLAMP_MODES + ButtonGroup++; + iY += 20; + g_HUD.AddRadioButton( IDC_DEPTH_CLAMP_TO_EDGE, ButtonGroup, L"CLAMP_TO_EDGE", 35, iY += 24, 125, 22, (g_AOParams.DepthClampMode == GFSDK_SSAO_CLAMP_TO_EDGE) ); + g_HUD.AddRadioButton( IDC_DEPTH_CLAMP_TO_BORDER, ButtonGroup, L"CLAMP_TO_BORDER", 35, iY += 24, 125, 22, (g_AOParams.DepthClampMode == GFSDK_SSAO_CLAMP_TO_BORDER) ); +#endif + +#if ENABLE_BORDER_PIXELS + ButtonGroup++; + iY += 20; + g_HUD.AddRadioButton( IDC_BORDER_PIXELS_0, ButtonGroup, L"BORDER_PIXELS_0", 35, iY += 24, 125, 22, (g_BorderPixels == 0) ); + g_HUD.AddRadioButton( IDC_BORDER_PIXELS_64, ButtonGroup, L"BORDER_PIXELS_64", 35, iY += 24, 125, 22, (g_BorderPixels == 64) ); + g_HUD.AddRadioButton( IDC_BORDER_PIXELS_128, ButtonGroup, L"BORDER_PIXELS_128", 35, iY += 24, 125, 22, (g_BorderPixels == 128) ); +#endif +} + +//-------------------------------------------------------------------------------------- +// Initialize everything and go into a render loop +//-------------------------------------------------------------------------------------- +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) +{ + HRESULT hr; + V_RETURN(DXUTSetMediaSearchPath(L"..\\..\\assets")); + + // Enable run-time memory check for debug builds. +#if defined(DEBUG) && defined (DEBUG_CRT) + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + + // Set general DXUT callbacks + DXUTSetCallbackFrameMove(OnFrameMove); + DXUTSetCallbackKeyboard(OnKeyboard); + DXUTSetCallbackMouse(OnMouse); + DXUTSetCallbackMsgProc(MsgProc); + DXUTSetCallbackDeviceChanging(ModifyDeviceSettings); + DXUTSetCallbackDeviceRemoved(OnDeviceRemoved); + + // Set the D3D11 DXUT callbacks + DXUTSetCallbackD3D11DeviceAcceptable (IsD3D11DeviceAcceptable); + DXUTSetCallbackD3D11DeviceCreated (OnD3D11CreateDevice); + DXUTSetCallbackD3D11SwapChainResized (OnD3D11ResizedSwapChain); + DXUTSetCallbackD3D11FrameRender (OnD3D11FrameRender); + DXUTSetCallbackD3D11SwapChainReleasing(OnD3D11ReleasingSwapChain); + DXUTSetCallbackD3D11DeviceDestroyed (OnD3D11DestroyDevice); + + // Perform any application-level initialization here + InitAOParams(g_AOParams); + InitGUI(); + + UINT Width = 1280; + UINT Height = 720; + + DXUTInit(true, true, NULL); // Parse the command line, show msgboxes on error, no extra command line params + DXUTSetCursorSettings(true, true); // Show the cursor and clip it when in full screen + DXUTSetIsInGammaCorrectMode(false); // Do not use a SRGB back buffer for this sample + DXUTCreateWindow(L"NVIDIA HBAO+"); + DXUTCreateDevice(D3D_FEATURE_LEVEL_11_0, true, Width, Height); + //DXUTToggleFullScreen(); + + DXUTMainLoop(); // Enter into the DXUT render loop + + // Perform any application-level cleanup here + + return DXUTGetExitCode(); +} |