aboutsummaryrefslogtreecommitdiff
path: root/test/src/D3D11/TwoPassBlend.cpp
diff options
context:
space:
mode:
authorlbavoil <[email protected]>2016-08-08 15:45:59 +0200
committerlbavoil <[email protected]>2016-08-08 15:45:59 +0200
commit4801bf501ea20940640f0aec98ebb66cc96805a6 (patch)
tree32f3b0e3397fd1e364d1e19742c2d9c31985ed92 /test/src/D3D11/TwoPassBlend.cpp
parentHBAO+ 3.0.0.20735892 (diff)
downloadhbaoplus-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.cpp1693
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();
+}