diff options
| author | Nathan Hoobler <[email protected]> | 2016-03-22 11:40:34 -0400 |
|---|---|---|
| committer | Nathan Hoobler <[email protected]> | 2016-03-22 11:40:34 -0400 |
| commit | b4ab266c9010aaff5404f6a508a2e592eb367d36 (patch) | |
| tree | 1e9eefa78e90485397b50ce5e780a1d0cb38b493 /samples/VolumetricLightingTest/d3d11 | |
| download | volumetriclighting-b4ab266c9010aaff5404f6a508a2e592eb367d36.tar.xz volumetriclighting-b4ab266c9010aaff5404f6a508a2e592eb367d36.zip | |
initial commit
Diffstat (limited to 'samples/VolumetricLightingTest/d3d11')
7 files changed, 1897 insertions, 0 deletions
diff --git a/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp b/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp new file mode 100644 index 0000000..122da86 --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/DeviceManager.cpp @@ -0,0 +1,609 @@ +// TAGRELEASE: PUBLIC +#include "common.h" + +#include "DeviceManager.h" +#include <WinUser.h> +#include <Windows.h> + +#ifndef SAFE_RELEASE +#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } +#endif + +#define WINDOW_CLASS_NAME L"NvDX11" + +#define WINDOW_STYLE_NORMAL (WS_OVERLAPPEDWINDOW | WS_VISIBLE) +#define WINDOW_STYLE_FULLSCREEN (WS_POPUP | WS_SYSMENU | WS_VISIBLE) + +// A singleton, sort of... To pass the events from WindowProc to the object. +DeviceManager* g_DeviceManagerInstance = NULL; + +LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if(g_DeviceManagerInstance) + return g_DeviceManagerInstance->MsgProc(hWnd, uMsg, wParam, lParam); + else + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +HRESULT +DeviceManager::CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params, LPWSTR title) +{ + g_DeviceManagerInstance = this; + m_WindowTitle = title; + + HINSTANCE hInstance = GetModuleHandle(NULL); + WNDCLASSEX windowClass = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WindowProc, + 0L, 0L, hInstance, NULL, NULL, NULL, NULL, WINDOW_CLASS_NAME, NULL }; + + RegisterClassEx(&windowClass); + + UINT windowStyle = params.startFullscreen + ? WINDOW_STYLE_FULLSCREEN + : params.startMaximized + ? (WINDOW_STYLE_NORMAL | WS_MAXIMIZE) + : WINDOW_STYLE_NORMAL; + + RECT rect = { 0, 0, params.backBufferWidth, params.backBufferHeight }; + AdjustWindowRect(&rect, windowStyle, FALSE); + + m_hWnd = CreateWindowEx( + 0, + WINDOW_CLASS_NAME, + title, + windowStyle, + CW_USEDEFAULT, + CW_USEDEFAULT, + rect.right - rect.left, + rect.bottom - rect.top, + GetDesktopWindow(), + NULL, + hInstance, + NULL + ); + + if(!m_hWnd) + { +#ifdef DEBUG + DWORD errorCode = GetLastError(); + printf("CreateWindowEx error code = 0x%x\n", errorCode); +#endif + + MessageBox(NULL, L"Cannot create window", m_WindowTitle.c_str(), MB_OK | MB_ICONERROR); + return E_FAIL; + } + + UpdateWindow(m_hWnd); + + HRESULT hr = E_FAIL; + + RECT clientRect; + GetClientRect(m_hWnd, &clientRect); + UINT width = clientRect.right - clientRect.left; + UINT height = clientRect.bottom - clientRect.top; + + ZeroMemory(&m_SwapChainDesc, sizeof(m_SwapChainDesc)); + m_SwapChainDesc.BufferCount = params.swapChainBufferCount; + m_SwapChainDesc.BufferDesc.Width = width; + m_SwapChainDesc.BufferDesc.Height = height; + m_SwapChainDesc.BufferDesc.Format = params.swapChainFormat; + m_SwapChainDesc.BufferDesc.RefreshRate.Numerator = params.refreshRate; + m_SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + m_SwapChainDesc.BufferUsage = params.swapChainUsage; + m_SwapChainDesc.OutputWindow = m_hWnd; + m_SwapChainDesc.SampleDesc.Count = params.swapChainSampleCount; + m_SwapChainDesc.SampleDesc.Quality = 0; + m_SwapChainDesc.Windowed = !params.startFullscreen; + m_SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + hr = D3D11CreateDeviceAndSwapChain( + NULL, // pAdapter + params.driverType, // DriverType + NULL, // Software + params.createDeviceFlags, // Flags + ¶ms.featureLevel, // pFeatureLevels + 1, // FeatureLevels + D3D11_SDK_VERSION, // SDKVersion + &m_SwapChainDesc, // pSwapChainDesc + &m_SwapChain, // ppSwapChain + &m_Device, // ppDevice + NULL, // pFeatureLevel + &m_ImmediateContext // ppImmediateContext + ); + + if(FAILED(hr)) + return hr; + + m_DepthStencilDesc.ArraySize = 1; + m_DepthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + m_DepthStencilDesc.CPUAccessFlags = 0; + m_DepthStencilDesc.Format = params.depthStencilFormat; + m_DepthStencilDesc.Width = width; + m_DepthStencilDesc.Height = height; + m_DepthStencilDesc.MipLevels = 1; + m_DepthStencilDesc.MiscFlags = 0; + m_DepthStencilDesc.SampleDesc.Count = params.swapChainSampleCount; + m_DepthStencilDesc.SampleDesc.Quality = 0; + m_DepthStencilDesc.Usage = D3D11_USAGE_DEFAULT; + + hr = CreateRenderTargetAndDepthStencil(); + + if(FAILED(hr)) + return hr; + + DeviceCreated(); + BackBufferResized(); + + return S_OK; +} + +void +DeviceManager::Shutdown() +{ + if(m_SwapChain && GetWindowState() == kWindowFullscreen) + m_SwapChain->SetFullscreenState(false, NULL); + + DeviceDestroyed(); + + SAFE_RELEASE(m_BackBufferRTV); + SAFE_RELEASE(m_DepthStencilDSV); + SAFE_RELEASE(m_DepthStencilBuffer); + + g_DeviceManagerInstance = NULL; + SAFE_RELEASE(m_SwapChain); + SAFE_RELEASE(m_Device); + + if(m_hWnd) + { + DestroyWindow(m_hWnd); + m_hWnd = NULL; + } +} + +HRESULT +DeviceManager::CreateRenderTargetAndDepthStencil() +{ + HRESULT hr; + + ID3D11Texture2D *backBuffer = NULL; + hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); + if (FAILED(hr)) + return hr; + + hr = m_Device->CreateRenderTargetView(backBuffer, NULL, &m_BackBufferRTV); + backBuffer->Release(); + if (FAILED(hr)) + return hr; + + if(m_DepthStencilDesc.Format != DXGI_FORMAT_UNKNOWN) + { + hr = m_Device->CreateTexture2D(&m_DepthStencilDesc, NULL, &m_DepthStencilBuffer); + if (FAILED(hr)) + return hr; + + hr = m_Device->CreateDepthStencilView(m_DepthStencilBuffer, NULL, &m_DepthStencilDSV); + if (FAILED(hr)) + return hr; + } + + return S_OK; +} + +void +DeviceManager::MessageLoop() +{ + MSG msg = {0}; + + LARGE_INTEGER perfFreq, previousTime; + QueryPerformanceFrequency(&perfFreq); + QueryPerformanceCounter(&previousTime); + + while (WM_QUIT != msg.message) + { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + { + LARGE_INTEGER newTime; + QueryPerformanceCounter(&newTime); + + double elapsedSeconds = (m_FixedFrameInterval >= 0) + ? m_FixedFrameInterval + : (double)(newTime.QuadPart - previousTime.QuadPart) / (double)perfFreq.QuadPart; + + if(m_SwapChain && GetWindowState() != kWindowMinimized) + { + Animate(elapsedSeconds); + Render(); + m_SwapChain->Present(m_SyncInterval, 0); + Sleep(0); + } + else + { + // Release CPU resources when idle + Sleep(1); + } + + { + m_vFrameTimes.push_back(elapsedSeconds); + double timeSum = 0; + for(auto it = m_vFrameTimes.begin(); it != m_vFrameTimes.end(); it++) + timeSum += *it; + + if(timeSum > m_AverageTimeUpdateInterval) + { + m_AverageFrameTime = timeSum / (double)m_vFrameTimes.size(); + m_vFrameTimes.clear(); + } + } + + previousTime = newTime; + } + } +} + +LRESULT +DeviceManager::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_DESTROY: + case WM_CLOSE: + PostQuitMessage(0); + return 0; + + case WM_SYSKEYDOWN: + if(wParam == VK_F4) + { + PostQuitMessage(0); + return 0; + } + break; + + case WM_SIZE: + // Ignore the WM_SIZE event if there is no device, + // or if the window has been minimized (size == 0), + // or if it has been restored to the previous size + if (m_Device + && (lParam != 0) + && (LOWORD(lParam) != m_SwapChainDesc.BufferDesc.Width || HIWORD(lParam) != m_SwapChainDesc.BufferDesc.Height)) + { + ID3D11RenderTargetView *nullRTV = NULL; + m_ImmediateContext->OMSetRenderTargets(1, &nullRTV, NULL); + SAFE_RELEASE(m_BackBufferRTV); + SAFE_RELEASE(m_DepthStencilDSV); + SAFE_RELEASE(m_DepthStencilBuffer); + + if (m_SwapChain) + { + // Resize the swap chain + m_SwapChainDesc.BufferDesc.Width = LOWORD(lParam); + m_SwapChainDesc.BufferDesc.Height = HIWORD(lParam); + m_SwapChain->ResizeBuffers(m_SwapChainDesc.BufferCount, m_SwapChainDesc.BufferDesc.Width, + m_SwapChainDesc.BufferDesc.Height, m_SwapChainDesc.BufferDesc.Format, + m_SwapChainDesc.Flags); + + m_DepthStencilDesc.Width = LOWORD(lParam); + m_DepthStencilDesc.Height = HIWORD(lParam); + + CreateRenderTargetAndDepthStencil(); + + BackBufferResized(); + } + } + } + + if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST || + uMsg >= WM_KEYFIRST && uMsg <= WM_KEYLAST ) + { + // processing messages front-to-back + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + if((*it)->IsEnabled()) + { + // for kb/mouse messages, 0 means the message has been handled + if(0 == (*it)->MsgProc(hWnd, uMsg, wParam, lParam)) + return 0; + } + } + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +void +DeviceManager::Render() +{ + D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)m_SwapChainDesc.BufferDesc.Width, (float)m_SwapChainDesc.BufferDesc.Height, 0.0f, 1.0f }; + + // rendering back-to-front + for(auto it = m_vControllers.rbegin(); it != m_vControllers.rend(); it++) + { + if((*it)->IsEnabled()) + { + m_ImmediateContext->OMSetRenderTargets(1, &m_BackBufferRTV, m_DepthStencilDSV); + m_ImmediateContext->RSSetViewports(1, &viewport); + + (*it)->Render(m_Device, m_ImmediateContext, m_BackBufferRTV, m_DepthStencilDSV); + } + } + + m_ImmediateContext->OMSetRenderTargets(0, NULL, NULL); +} + +void +DeviceManager::Animate(double fElapsedTimeSeconds) +{ + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + if((*it)->IsEnabled()) + { + (*it)->Animate(fElapsedTimeSeconds); + } + } +} + +void +DeviceManager::DeviceCreated() +{ + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + (*it)->DeviceCreated(m_Device); + } +} + +void +DeviceManager::DeviceDestroyed() +{ + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + (*it)->DeviceDestroyed(); + } +} + +void +DeviceManager::BackBufferResized() +{ + if(m_SwapChain == NULL) + return; + + DXGI_SURFACE_DESC backSD; + backSD.Format = m_SwapChainDesc.BufferDesc.Format; + backSD.Width = m_SwapChainDesc.BufferDesc.Width; + backSD.Height = m_SwapChainDesc.BufferDesc.Height; + backSD.SampleDesc = m_SwapChainDesc.SampleDesc; + + for(auto it = m_vControllers.begin(); it != m_vControllers.end(); it++) + { + (*it)->BackBufferResized(m_Device, &backSD); + } +} + +HRESULT +DeviceManager::ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount) +{ + HRESULT hr = E_FAIL; + + if((format == DXGI_FORMAT_UNKNOWN || format == m_SwapChainDesc.BufferDesc.Format) && + (sampleCount == 0 || sampleCount == m_SwapChainDesc.SampleDesc.Count)) + return S_FALSE; + + if(m_Device) + { + bool fullscreen = (GetWindowState() == kWindowFullscreen); + if(fullscreen) + m_SwapChain->SetFullscreenState(false, NULL); + + IDXGISwapChain* newSwapChain = NULL; + DXGI_SWAP_CHAIN_DESC newSwapChainDesc = m_SwapChainDesc; + + if(format != DXGI_FORMAT_UNKNOWN) + newSwapChainDesc.BufferDesc.Format = format; + if(sampleCount != 0) + newSwapChainDesc.SampleDesc.Count = sampleCount; + + IDXGIAdapter* pDXGIAdapter = GetDXGIAdapter(); + + IDXGIFactory* pDXGIFactory = NULL; + pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDXGIFactory)); + + hr = pDXGIFactory->CreateSwapChain(m_Device, &newSwapChainDesc, &newSwapChain); + + pDXGIFactory->Release(); + pDXGIAdapter->Release(); + + if (FAILED(hr)) + { + if(fullscreen) + m_SwapChain->SetFullscreenState(true, NULL); + + return hr; + } + + SAFE_RELEASE(m_BackBufferRTV); + SAFE_RELEASE(m_SwapChain); + SAFE_RELEASE(m_DepthStencilBuffer); + SAFE_RELEASE(m_DepthStencilDSV); + + m_SwapChain = newSwapChain; + m_SwapChainDesc = newSwapChainDesc; + + m_DepthStencilDesc.SampleDesc.Count = sampleCount; + + if(fullscreen) + m_SwapChain->SetFullscreenState(true, NULL); + + CreateRenderTargetAndDepthStencil(); + BackBufferResized(); + } + + return S_OK; +} + +void +DeviceManager::AddControllerToFront(IVisualController* pController) +{ + m_vControllers.remove(pController); + m_vControllers.push_front(pController); +} + +void +DeviceManager::AddControllerToBack(IVisualController* pController) +{ + m_vControllers.remove(pController); + m_vControllers.push_back(pController); +} + +void +DeviceManager::RemoveController(IVisualController* pController) +{ + m_vControllers.remove(pController); +} + +HRESULT +DeviceManager::ResizeWindow(int width, int height) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + RECT rect; + GetWindowRect(m_hWnd, &rect); + + ShowWindow(m_hWnd, SW_RESTORE); + + if(!MoveWindow(m_hWnd, rect.left, rect.top, width, height, true)) + return E_FAIL; + + // No need to call m_SwapChain->ResizeBackBuffer because MoveWindow will send WM_SIZE, which calls that function. + + return S_OK; +} + +HRESULT +DeviceManager::EnterFullscreenMode(int width, int height) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + if(GetWindowState() == kWindowFullscreen) + return S_FALSE; + + if(width <= 0 || height <= 0) + { + width = m_SwapChainDesc.BufferDesc.Width; + height = m_SwapChainDesc.BufferDesc.Height; + } + + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_FULLSCREEN); + MoveWindow(m_hWnd, 0, 0, width, height, true); + + HRESULT hr = m_SwapChain->SetFullscreenState(true, NULL); + + if(FAILED(hr)) + { + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL); + return hr; + } + + UpdateWindow(m_hWnd); + m_SwapChain->GetDesc(&m_SwapChainDesc); + + return S_OK; +} + +HRESULT +DeviceManager::LeaveFullscreenMode(int windowWidth, int windowHeight) +{ + if(m_SwapChain == NULL) + return E_FAIL; + + if(GetWindowState() != kWindowFullscreen) + return S_FALSE; + + HRESULT hr = m_SwapChain->SetFullscreenState(false, NULL); + if(FAILED(hr)) return hr; + + SetWindowLong(m_hWnd, GWL_STYLE, WINDOW_STYLE_NORMAL); + + if(windowWidth <= 0 || windowHeight <= 0) + { + windowWidth = m_SwapChainDesc.BufferDesc.Width; + windowHeight = m_SwapChainDesc.BufferDesc.Height; + } + + RECT rect = { 0, 0, windowWidth, windowHeight }; + AdjustWindowRect(&rect, WINDOW_STYLE_NORMAL, FALSE); + MoveWindow(m_hWnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top, true); + UpdateWindow(m_hWnd); + + m_SwapChain->GetDesc(&m_SwapChainDesc); + + return S_OK; +} + +HRESULT +DeviceManager::ToggleFullscreen() +{ + if(GetWindowState() == kWindowFullscreen) + return LeaveFullscreenMode(); + else + return EnterFullscreenMode(); +} + +DeviceManager::WindowState +DeviceManager::GetWindowState() +{ + if(m_SwapChain && !m_SwapChainDesc.Windowed) + return kWindowFullscreen; + + if(m_hWnd == INVALID_HANDLE_VALUE) + return kWindowNone; + + if(IsZoomed(m_hWnd)) + return kWindowMaximized; + + if(IsIconic(m_hWnd)) + return kWindowMinimized; + + return kWindowNormal; +} + +HRESULT +DeviceManager::GetDisplayResolution(int& width, int& height) +{ + if(m_hWnd != INVALID_HANDLE_VALUE) + { + HMONITOR monitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY); + MONITORINFO info; + info.cbSize = sizeof(MONITORINFO); + + if(GetMonitorInfo(monitor, &info)) + { + width = info.rcMonitor.right - info.rcMonitor.left; + height = info.rcMonitor.bottom - info.rcMonitor.top; + return S_OK; + } + } + + return E_FAIL; +} + +IDXGIAdapter* +DeviceManager::GetDXGIAdapter() +{ + if(!m_Device) + return NULL; + + IDXGIDevice* pDXGIDevice = NULL; + m_Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDXGIDevice)); + + IDXGIAdapter* pDXGIAdapter = NULL; + pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pDXGIAdapter)); + + pDXGIDevice->Release(); + + return pDXGIAdapter; +} diff --git a/samples/VolumetricLightingTest/d3d11/DeviceManager.h b/samples/VolumetricLightingTest/d3d11/DeviceManager.h new file mode 100644 index 0000000..4bd164a --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/DeviceManager.h @@ -0,0 +1,148 @@ +// TAGRELEASE: PUBLIC + +#pragma once +#include <Windows.h> +#include <DXGI.h> +#include <D3D11.h> +#include <list> + + +struct DeviceCreationParameters +{ + bool startMaximized; + bool startFullscreen; + int backBufferWidth; + int backBufferHeight; + int refreshRate; + int swapChainBufferCount; + DXGI_FORMAT swapChainFormat; + DXGI_FORMAT depthStencilFormat; + DXGI_USAGE swapChainUsage; + int swapChainSampleCount; + UINT createDeviceFlags; + D3D_DRIVER_TYPE driverType; + D3D_FEATURE_LEVEL featureLevel; + + DeviceCreationParameters() + : startMaximized(false) + , startFullscreen(false) + , backBufferWidth(1280) + , backBufferHeight(720) + , refreshRate(0) + , swapChainBufferCount(1) + , swapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM) + , depthStencilFormat(DXGI_FORMAT_D24_UNORM_S8_UINT) + , swapChainUsage(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT) + , swapChainSampleCount(1) + , createDeviceFlags(0) + , driverType(D3D_DRIVER_TYPE_HARDWARE) + , featureLevel(D3D_FEATURE_LEVEL_11_0) + { } +}; + +#pragma warning(push) +#pragma warning(disable: 4100) // unreferenced formal parameter +class IVisualController +{ +private: + bool m_Enabled; +public: + IVisualController() : m_Enabled(true) { } + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 1; } + virtual void Render(ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11DepthStencilView* pDSV) { } + virtual void Animate(double fElapsedTimeSeconds) { } + virtual HRESULT DeviceCreated(ID3D11Device* pDevice) { return S_OK; } + virtual void DeviceDestroyed() { } + virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { } + + virtual void EnableController() { m_Enabled = true; } + virtual void DisableController() { m_Enabled = false; } + virtual bool IsEnabled() { return m_Enabled; } +}; +#pragma warning(pop) + +class DeviceManager +{ +public: + enum WindowState + { + kWindowNone, + kWindowNormal, + kWindowMinimized, + kWindowMaximized, + kWindowFullscreen + }; + +protected: + ID3D11Device* m_Device; + ID3D11DeviceContext* m_ImmediateContext; + IDXGISwapChain* m_SwapChain; + ID3D11RenderTargetView* m_BackBufferRTV; + ID3D11Texture2D* m_DepthStencilBuffer; + ID3D11DepthStencilView* m_DepthStencilDSV; + DXGI_SWAP_CHAIN_DESC m_SwapChainDesc; + D3D11_TEXTURE2D_DESC m_DepthStencilDesc; + HWND m_hWnd; + std::list<IVisualController*> m_vControllers; + std::wstring m_WindowTitle; + double m_FixedFrameInterval; + UINT m_SyncInterval; + std::list<double> m_vFrameTimes; + double m_AverageFrameTime; + double m_AverageTimeUpdateInterval; +private: + HRESULT CreateRenderTargetAndDepthStencil(); +public: + + DeviceManager() + : m_Device(NULL) + , m_ImmediateContext(NULL) + , m_SwapChain(NULL) + , m_BackBufferRTV(NULL) + , m_DepthStencilBuffer(NULL) + , m_DepthStencilDSV(NULL) + , m_hWnd(NULL) + , m_WindowTitle(L"") + , m_FixedFrameInterval(-1) + , m_SyncInterval(0) + , m_AverageFrameTime(0) + , m_AverageTimeUpdateInterval(0.5) + { } + + virtual ~DeviceManager() + { Shutdown(); } + + virtual HRESULT CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params, LPWSTR windowTitle); + virtual HRESULT ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount); + virtual HRESULT ResizeWindow(int width, int height); + virtual HRESULT EnterFullscreenMode(int width = 0, int height = 0); + virtual HRESULT LeaveFullscreenMode(int windowWidth = 0, int windowHeight = 0); + virtual HRESULT ToggleFullscreen(); + + virtual void Shutdown(); + virtual void MessageLoop(); + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void Render(); + virtual void Animate(double fElapsedTimeSeconds); + virtual void DeviceCreated(); + virtual void DeviceDestroyed(); + virtual void BackBufferResized(); + + void AddControllerToFront(IVisualController* pController); + void AddControllerToBack(IVisualController* pController); + void RemoveController(IVisualController* pController); + + void SetFixedFrameInterval(double seconds) { m_FixedFrameInterval = seconds; } + void DisableFixedFrameInterval() { m_FixedFrameInterval = -1; } + + HWND GetHWND() { return m_hWnd; } + ID3D11Device* GetDevice() { return m_Device; } + WindowState GetWindowState(); + bool GetVsyncEnabled() { return m_SyncInterval > 0; } + void SetVsyncEnabled(bool enabled) { m_SyncInterval = enabled ? 1 : 0; } + HRESULT GetDisplayResolution(int& width, int& height); + IDXGIAdapter* GetDXGIAdapter(); + double GetAverageFrameTime() { return m_AverageFrameTime; } + void SetAverageTimeUpdateInterval(double value) { m_AverageTimeUpdateInterval = value; } +}; diff --git a/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp new file mode 100644 index 0000000..43f2e5d --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.cpp @@ -0,0 +1,36 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2003 - 2016 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and 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 <stdint.h> +namespace d3d11 { namespace shaders { + #include <shaders/post_PS.mux.bytecode> + #include <shaders/quad_VS.mux.bytecode> + #include <shaders/scene_VS.mux.bytecode> + #include <shaders/scene_GS.mux.bytecode> + #include <shaders/scene_PS.mux.bytecode> +}; /* namespace shaders */ }; /* namespace d3d11 */ diff --git a/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h new file mode 100644 index 0000000..2488d61 --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/compiled_shaders_d3d11.h @@ -0,0 +1,45 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2003 - 2016 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and 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. +// + +#ifndef COMPILED_SHADERS_D3D11_H +#define COMPILED_SHADERS_D3D11_H +//////////////////////////////////////////////////////////////////////////////// +#include <stdint.h> +namespace d3d11 { namespace shaders { + #include <shaders/post_PS.mux.h> + #include <shaders/quad_VS.mux.h> + #include <shaders/scene_VS.mux.h> + #include <shaders/scene_GS.mux.h> + #include <shaders/scene_PS.mux.h> +}; /* namespace shaders */ }; /* namespace d3d11 */ +// We use the namespaces to avoid conflicts if supporting multiple APIs +// but they aren't needed wherever these would be included. +using namespace d3d11; +using namespace shaders; +//////////////////////////////////////////////////////////////////////////////// +#endif // COMPILED_SHADERS_D3D11_H diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp b/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp new file mode 100644 index 0000000..308d025 --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/d3d11_main.cpp @@ -0,0 +1,478 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2003 - 2016 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and 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 "common.h" + +#include "compiled_shaders_d3d11.h" +#include "DeviceManager.h" +#include "d3d11_util.h" +#include "scene.h" + +#include <Nv/VolumetricLighting/NvVolumetricLighting.h> +#include <d3d11.h> + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Control rendering of the scene +#define LOAD_SHADERS(x) LoadShaders(device, ##x##::permutation_code, ##x##::permutation_length, shaders::##x##::PERMUTATION_ENTRY_COUNT, shaders.##x) + +class SceneController : public IVisualController +{ +private: + Scene * pScene_; + DeviceManager * pManager_; + + uint32_t framebufferWidth_; + uint32_t framebufferHeight_; + + // Resources used by the scene + + ConstantBuffer <Scene::ViewCB> * pViewCB_; + ConstantBuffer <Scene::ObjectCB> * pObjectCB_; + ConstantBuffer <Scene::LightCB> * pLightCB_; + + RenderTarget * pSceneRT_; + DepthTarget * pSceneDepth_; + DepthTarget * pShadowMap_; + DepthTarget * pParaboloidShadowMap_; + + ID3D11SamplerState * ss_shadowmap_; + ID3D11RasterizerState * rs_render_; + ID3D11BlendState * bs_no_color_; + ID3D11DepthStencilState * ds_shadowmap_; + + struct + { + ID3D11PixelShader ** post_PS; + ID3D11VertexShader ** quad_VS; + ID3D11VertexShader ** scene_VS; + ID3D11GeometryShader ** scene_GS; + ID3D11PixelShader ** scene_PS; + } shaders; + + // GWVL Platform-specific info + Nv::Vl::PlatformDesc platformDesc_; + +public: + + SceneController(Scene * pScene, DeviceManager * pManager) + { + pScene_ = pScene; + pManager_ = pManager; + } + + virtual HRESULT DeviceCreated(ID3D11Device* device) + { + Nv::Vl::OpenLibrary(); + + // Shaders + LOAD_SHADERS(post_PS); + LOAD_SHADERS(quad_VS); + LOAD_SHADERS(scene_VS); + LOAD_SHADERS(scene_GS); + LOAD_SHADERS(scene_PS); + + // Constant Buffers + pViewCB_ = ConstantBuffer<Scene::ViewCB>::Create(device); + pObjectCB_ = ConstantBuffer<Scene::ObjectCB>::Create(device); + pLightCB_ = ConstantBuffer<Scene::LightCB>::Create(device); + + // Textures + pSceneRT_ = nullptr; + pSceneDepth_ = nullptr; + pShadowMap_ = DepthTarget::Create(device, Scene::SHADOWMAP_RESOLUTION, Scene::SHADOWMAP_RESOLUTION, 1, DXGI_FORMAT_D16_UNORM, 1, "Simple Shadow Map"); + pParaboloidShadowMap_ = DepthTarget::Create(device, Scene::SHADOWMAP_RESOLUTION, Scene::SHADOWMAP_RESOLUTION, 1, DXGI_FORMAT_D16_UNORM, 2, "Dual-Paraboloid Shadow Map"); + + // Shadowmap Sampler + { + CD3D11_SAMPLER_DESC desc((CD3D11_DEFAULT())); + desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + desc.ComparisonFunc = D3D11_COMPARISON_LESS; + device->CreateSamplerState(&desc, &ss_shadowmap_); + } + // No color output blend-state + { + CD3D11_BLEND_DESC desc((CD3D11_DEFAULT())); + desc.RenderTarget[0].RenderTargetWriteMask = 0x00000000; + device->CreateBlendState(&desc, &bs_no_color_); + } + { + CD3D11_RASTERIZER_DESC rsDesc((CD3D11_DEFAULT())); + rsDesc.CullMode = D3D11_CULL_NONE; + device->CreateRasterizerState(&rsDesc, &rs_render_); + } + { + CD3D11_DEPTH_STENCIL_DESC dsDesc((CD3D11_DEFAULT())); + device->CreateDepthStencilState(&dsDesc, &ds_shadowmap_); + } + // Initialize GWVL settings info + { + platformDesc_.platform = Nv::Vl::PlatformName::D3D11; + platformDesc_.d3d11.pDevice = device; + } + + return S_OK; + } + + virtual void DeviceDestroyed() + { + // Release resources + SAFE_RELEASE(ss_shadowmap_); + SAFE_RELEASE(bs_no_color_); + SAFE_RELEASE(rs_render_); + SAFE_RELEASE(ds_shadowmap_); + SAFE_DELETE(pViewCB_); + SAFE_DELETE(pObjectCB_); + SAFE_DELETE(pLightCB_); + SAFE_DELETE(pSceneRT_); + SAFE_DELETE(pSceneDepth_); + SAFE_DELETE(pShadowMap_); + SAFE_DELETE(pParaboloidShadowMap_); + SAFE_DELETE_ARRAY(shaders.post_PS); + SAFE_DELETE_ARRAY(shaders.quad_VS); + SAFE_DELETE_ARRAY(shaders.scene_VS); + SAFE_DELETE_ARRAY(shaders.scene_GS); + SAFE_DELETE_ARRAY(shaders.scene_PS); + + pScene_->Release(); + Nv::Vl::CloseLibrary(); + } + + virtual void BackBufferResized(ID3D11Device* device, const DXGI_SURFACE_DESC* surface_desc) + { + framebufferWidth_ = surface_desc->Width; + framebufferHeight_ = surface_desc->Height; + + // Create back-buffer sized resources + SAFE_DELETE(pSceneRT_); + SAFE_DELETE(pSceneDepth_); + pSceneRT_ = RenderTarget::Create(device, framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count, DXGI_FORMAT_R16G16B16A16_FLOAT, "Scene Render Target"); + pSceneDepth_ = DepthTarget::Create(device, framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count, DXGI_FORMAT_D24_UNORM_S8_UINT, 1, "Scene Depth"); + + // Update the context desc and (re-)create the context + pScene_->updateFramebuffer(framebufferWidth_, framebufferHeight_, surface_desc->SampleDesc.Count); + } + + virtual void Render(ID3D11Device*, ID3D11DeviceContext* ctx, ID3D11RenderTargetView* pFramebuffer_RTV, ID3D11DepthStencilView*) + { + NV_PERFEVENT(ctx, "Render Frame"); + if (!pScene_->isCtxValid()) + { + pScene_->createCtx(&platformDesc_); + } + + float clear_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + ctx->ClearRenderTargetView( pSceneRT_->getRTV(), clear_color); + ctx->ClearDepthStencilView(pSceneDepth_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0); + + ID3D11Buffer * CBs[] = { + pViewCB_->getCB(), + pObjectCB_->getCB(), + pLightCB_->getCB() + }; + + auto RenderScene = [=]() + { + NV_PERFEVENT(ctx, "Draw Scene Geometry"); + const float scene_range[] = { -6, -3, 3, 6 }; + for (auto x : scene_range) + { + for (auto y : scene_range) + { + for (auto z : scene_range) + { + Scene::ObjectCB * pObject = this->pObjectCB_->Map(ctx); + pScene_->setupObjectCB(pObject, Nv::NvVec3(x, y, z)); + this->pObjectCB_->Unmap(ctx); + + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->IASetVertexBuffers(0,0,nullptr, nullptr,nullptr); + ctx->IASetInputLayout(nullptr); + ctx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0); + ctx->Draw(36, 0); + } + } + } + }; + + //---------------------------------------------------------------------- + // Render the light's shadow map + { + NV_PERFEVENT(ctx, "Render Shadow Map"); + { + Scene::ViewCB * pView = pViewCB_->Map(ctx); + pScene_->setupLightViewCB(pView); + pViewCB_->Unmap(ctx); + } + + ctx->ClearState(); + CD3D11_VIEWPORT shadowmap_viewport; + shadowmap_viewport.TopLeftX = 0; + shadowmap_viewport.TopLeftY = 0; + shadowmap_viewport.Width = static_cast<float>(Scene::SHADOWMAP_RESOLUTION); + shadowmap_viewport.Height = static_cast<float>(Scene::SHADOWMAP_RESOLUTION); + shadowmap_viewport.MinDepth = 0.0f; + shadowmap_viewport.MaxDepth = 1.0f; + ctx->RSSetState(rs_render_); + ctx->VSSetShader(shaders.scene_VS[scene_VS::SINGLE], nullptr, 0); + ctx->VSSetConstantBuffers(0, 3, CBs); + if (pScene_->getLightMode() == Scene::eLightMode::OMNI) + { + ctx->ClearDepthStencilView(pParaboloidShadowMap_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0); + ctx->OMSetRenderTargets(0, nullptr, pParaboloidShadowMap_->getDSV()); + CD3D11_VIEWPORT dual_viewports[] = { shadowmap_viewport, shadowmap_viewport }; + ctx->RSSetViewports(2, dual_viewports); + ctx->GSSetShader(shaders.scene_GS[scene_GS::SINGLE], nullptr, 0); + ctx->GSSetConstantBuffers(0, 3, CBs); + } + else + { + ctx->ClearDepthStencilView(pShadowMap_->getDSV(), D3D11_CLEAR_DEPTH, 1.0, 0); + ctx->OMSetRenderTargets(0, nullptr, pShadowMap_->getDSV()); + ctx->RSSetViewports(1, &shadowmap_viewport); + } + ctx->PSSetShader(nullptr, nullptr, 0); + ctx->OMSetBlendState(bs_no_color_, nullptr, 0xFFFFFFFF); + ctx->OMSetDepthStencilState(ds_shadowmap_, 0xFF); + RenderScene(); + } + ID3D11ShaderResourceView * shadowmap_srv = (pScene_->getLightMode() == Scene::eLightMode::OMNI) ? pParaboloidShadowMap_->getSRV() : pShadowMap_->getSRV(); + + //---------------------------------------------------------------------- + // Render the scene + { + NV_PERFEVENT(ctx, "Render Main Scene"); + { + Scene::ViewCB * pView = pViewCB_->Map(ctx); + Scene::LightCB * pLight = pLightCB_->Map(ctx); + pScene_->setupSceneCBs(pView, pLight); + pViewCB_->Unmap(ctx); + pLightCB_->Unmap(ctx); + } + + ctx->ClearState(); + CD3D11_VIEWPORT scene_viewport; + scene_viewport.TopLeftX = 0.0f; + scene_viewport.TopLeftY = 0.f; + scene_viewport.Width = static_cast<float>(framebufferWidth_); + scene_viewport.Height = static_cast<float>(framebufferHeight_); + scene_viewport.MinDepth = 0.0f; + scene_viewport.MaxDepth = 1.0f; + ctx->RSSetViewports(1, &scene_viewport); + ctx->RSSetState(rs_render_); + ctx->VSSetShader(shaders.scene_VS[scene_VS::SINGLE], nullptr, 0); + ctx->VSSetConstantBuffers(0, 3, CBs); + ctx->GSSetShader(nullptr, nullptr, 0); + scene_PS::Desc ps_desc; + switch (pScene_->getLightMode()) + { + default: + case Scene::eLightMode::DIRECTIONAL: + ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_DIRECTIONAL; + break; + + case Scene::eLightMode::SPOTLIGHT: + ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_SPOTLIGHT; + break; + + case Scene::eLightMode::OMNI: + ps_desc.flags.LIGHTMODE = scene_PS::LIGHTMODE_OMNI; + break; + } + ctx->PSSetShader(shaders.scene_PS[ps_desc], nullptr, 0); + ctx->PSSetConstantBuffers(0, 3, CBs); + ID3D11ShaderResourceView * SRVs[] = { shadowmap_srv }; + ctx->PSSetShaderResources(0, 1, SRVs); + ctx->PSSetSamplers(0, 1, &ss_shadowmap_); + ID3D11RenderTargetView * RTVs[] = { pSceneRT_->getRTV() }; + ctx->OMSetRenderTargets(1, RTVs, pSceneDepth_->getDSV()); + RenderScene(); + } + + //---------------------------------------------------------------------- + // Render the volumetric lighting + { + NV_PERFEVENT(ctx, "Volumetric Lighting"); + ctx->ClearState(); + pScene_->beginAccumulation(ctx, pSceneDepth_->getSRV()); + pScene_->renderVolume(ctx, shadowmap_srv); + pScene_->endAccumulation(ctx); + pScene_->applyLighting(ctx, pSceneRT_->getRTV(), pSceneDepth_->getSRV()); + } + + //---------------------------------------------------------------------- + // Tonemap to output + { + NV_PERFEVENT(ctx, "Postprocess"); + ctx->ClearState(); + CD3D11_VIEWPORT scene_viewport; + scene_viewport.TopLeftX = 0.0f; + scene_viewport.TopLeftY = 0.f; + scene_viewport.Width = static_cast<float>(framebufferWidth_); + scene_viewport.Height = static_cast<float>(framebufferHeight_); + scene_viewport.MinDepth = 0.0f; + scene_viewport.MaxDepth = 1.0f; + ctx->RSSetViewports(1, &scene_viewport); + ctx->RSSetState(rs_render_); + ID3D11RenderTargetView * RTVs[] = { pFramebuffer_RTV }; + ctx->OMSetRenderTargets(1, RTVs, nullptr); + ctx->VSSetShader(shaders.quad_VS[quad_VS::SINGLE], nullptr, 0); + ctx->PSSetShader(shaders.post_PS[post_PS::SINGLE], nullptr, 0); + ID3D11ShaderResourceView * SRVs[] = { pSceneRT_->getSRV() }; + ctx->PSSetShaderResources(0, 1, SRVs); + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->IASetVertexBuffers(0, 0, nullptr, nullptr, nullptr); + ctx->IASetInputLayout(nullptr); + ctx->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0); + ctx->Draw(3, 0); + } + } + + virtual void Animate(double fElapsedTimeSeconds) + { + pScene_->animate((float)fElapsedTimeSeconds); + } + + virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + hWnd; uMsg; wParam; lParam; + switch (uMsg) + { + case WM_KEYDOWN: + switch (wParam) + { + case VK_ESCAPE: + PostQuitMessage(0); + break; + + case VK_F1: + pScene_->setDebugMode(Nv::Vl::DebugFlags::NONE); + break; + + case VK_F2: + pScene_->setDebugMode(Nv::Vl::DebugFlags::NO_BLENDING); + break; + + case VK_F3: + pScene_->setDebugMode(Nv::Vl::DebugFlags::WIREFRAME); + break; + + case VK_F4: + pManager_->ToggleFullscreen(); + break; + + case VK_SPACE: + pScene_->togglePause(); + break; + + case 0x44: // D key - toggle downsample mode + pScene_->toggleDownsampleMode(); + break; + + case 0x46: // F key - toggle fog + pScene_->toggleFog(); + break; + + case 0x4C: // L key - toggle light type + pScene_->toggleLightMode(); + break; + + case 0x4D: // M key - toggle MSAA mode + pScene_->toggleMsaaMode(); + break; + + case 0x4F: // O key - toggle light intensity + pScene_->toggleMediumType(); + break; + + case 0x50: // P key - toggle light intensity + pScene_->toggleIntensity(); + break; + + case 0x54: // T key - toggle temporal filtering + pScene_->toggleFiltering(); + break; + + case 0x55: // U key - toggle upsample mode + pScene_->toggleUpsampleMode(); + break; + + case 0x56: // V key - toggle view mode + pScene_->toggleViewpoint(); + break; + } + return 0; + } + return 1; + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Entry point to the program. Initializes everything and goes into a message processing +// loop. Idle time is used to render the scene. +//////////////////////////////////////////////////////////////////////////////////////////////////// + +int main_D3D11(Scene * pScene) +{ + // Enable run-time memory check for debug builds. +#if (NV_CHECKED) + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); + + AllocConsole(); + freopen("CONIN$", "r",stdin); + freopen("CONOUT$", "w",stdout); + freopen("CONOUT$", "w",stderr); +#endif + + DeviceManager * device_manager = new DeviceManager(); + + auto scene_controller = SceneController(pScene, device_manager); + device_manager->AddControllerToFront(&scene_controller); + + DeviceCreationParameters deviceParams; + deviceParams.swapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + deviceParams.swapChainSampleCount = 4; + deviceParams.startFullscreen = false; + deviceParams.backBufferWidth = 1920; + deviceParams.backBufferHeight = 1080; +#if (NV_CHECKED) + deviceParams.createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + if(FAILED(device_manager->CreateWindowDeviceAndSwapChain(deviceParams, L"Gameworks Volumetric Lighting Unit Test"))) + { + MessageBox(nullptr, L"Cannot initialize the D3D11 device with the requested parameters", L"Error", MB_OK | MB_ICONERROR); + return 1; + } + // Loop + device_manager->MessageLoop(); + // Shutdown and exit + device_manager->Shutdown(); + delete device_manager; + + return 0; +} diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp b/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp new file mode 100644 index 0000000..4226fdb --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/d3d11_util.cpp @@ -0,0 +1,347 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2003 - 2016 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and 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 "common.h" +#include "d3d11_util.h" +#include <d3d11.h> + +/*============================================================================== + Overloaded functions to make shader compilation simpler +==============================================================================*/ +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader) + { return device->CreateVertexShader(data, length, nullptr, out_shader); } +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader) + { return device->CreateHullShader(data, length, nullptr, out_shader); } +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader) + { return device->CreateDomainShader(data, length, nullptr, out_shader); } +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader) + { return device->CreateGeometryShader(data, length, nullptr, out_shader); } +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader) + { return device->CreatePixelShader(data, length, nullptr, out_shader); } +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader) + { return device->CreateComputeShader(data, length, nullptr, out_shader); } +/*============================================================================== + Texture resource management helpers +==============================================================================*/ + +//------------------------------------------------------------------------------ +ShaderResource::ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav) +{ + resource_ = resource; + srv_ = srv; + uav_ = uav; +} + +ShaderResource::~ShaderResource() +{ + SAFE_RELEASE(resource_); + SAFE_RELEASE(srv_); + SAFE_RELEASE(uav_); +} + +//------------------------------------------------------------------------------ +RenderTarget * RenderTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name) +{ + ID3D11Texture2D * tex = nullptr; + ID3D11ShaderResourceView * srv = nullptr; + ID3D11RenderTargetView * rtv = nullptr; + ID3D11UnorderedAccessView * uav = nullptr; + + CD3D11_TEXTURE2D_DESC texDesc; + texDesc.ArraySize = 1; + texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + if (samples == 1) + texDesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + texDesc.CPUAccessFlags = 0; + texDesc.Format = format; + texDesc.Width = width; + texDesc.Height = height; + texDesc.MipLevels = 1; + texDesc.MiscFlags = 0; + if (samples > 1) + { + texDesc.SampleDesc.Count = samples; + texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN); + } + else + { + texDesc.SampleDesc.Count = 1; + texDesc.SampleDesc.Quality = 0; + } + texDesc.Usage = D3D11_USAGE_DEFAULT; + device->CreateTexture2D(&texDesc, nullptr, &tex); + if (tex == nullptr) + { + return nullptr; + } + + CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = texDesc.Format; + if (samples > 1) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + } + device->CreateShaderResourceView(tex, &srvDesc, &srv); + if (srv == nullptr) + { + tex->Release(); + return nullptr; + } + + CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = texDesc.Format; + if (samples > 1) + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } + else + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + } + device->CreateRenderTargetView(tex, &rtvDesc, &rtv); + if (rtv == nullptr) + { + tex->Release(); + srv->Release(); + return nullptr; + } + + if (samples == 1) + { + CD3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uavDesc.Format = texDesc.Format; + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + uavDesc.Texture2D.MipSlice = 0; + device->CreateUnorderedAccessView(tex, &uavDesc, &uav); + if (uav == nullptr) + { + tex->Release(); + srv->Release(); + rtv->Release(); + return nullptr; + } + } +#if (NV_DEBUG || NV_PROFILE) + if (debug_name) + { + tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name); + } +#else + debug_name; +#endif + return new RenderTarget(tex, srv, rtv, uav); +} + +RenderTarget::RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav) + : ShaderResource(resource, srv, uav) +{ + rtv_ = rtv; +} + +RenderTarget::~RenderTarget() +{ + SAFE_RELEASE(rtv_); +} + +//------------------------------------------------------------------------------ +DepthTarget * DepthTarget::Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices, char * debug_name) +{ + ID3D11Texture2D * tex = nullptr; + ID3D11ShaderResourceView * srv = nullptr; + ID3D11DepthStencilView * dsv = nullptr; + ID3D11DepthStencilView * dsv_ro = nullptr; + + DXGI_FORMAT tex_format; + DXGI_FORMAT srv_format; + DXGI_FORMAT dsv_format; + switch (format) + { + case DXGI_FORMAT_D32_FLOAT: + tex_format = DXGI_FORMAT_R32_TYPELESS; + srv_format = DXGI_FORMAT_R32_FLOAT; + dsv_format = DXGI_FORMAT_D32_FLOAT; + break; + + case DXGI_FORMAT_D24_UNORM_S8_UINT: + tex_format = DXGI_FORMAT_R24G8_TYPELESS; + srv_format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + dsv_format = DXGI_FORMAT_D24_UNORM_S8_UINT; + break; + + case DXGI_FORMAT_D16_UNORM: + tex_format = DXGI_FORMAT_R16_TYPELESS; + srv_format = DXGI_FORMAT_R16_UNORM; + dsv_format = DXGI_FORMAT_D16_UNORM; + break; + + default: + return nullptr; + } + + CD3D11_TEXTURE2D_DESC texDesc; + texDesc.ArraySize = slices; + texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + texDesc.CPUAccessFlags = 0; + texDesc.Format = tex_format; + texDesc.Width = width; + texDesc.Height = height; + texDesc.MipLevels = 1; + texDesc.MiscFlags = 0; + if (samples > 1) + { + texDesc.SampleDesc.Count = samples; + texDesc.SampleDesc.Quality = 0;//static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN); + } + else + { + texDesc.SampleDesc.Count = 1; + texDesc.SampleDesc.Quality = 0; + } + texDesc.Usage = D3D11_USAGE_DEFAULT; + device->CreateTexture2D(&texDesc, nullptr, &tex); + if (tex == nullptr) + { + return nullptr; + } + + CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = srv_format; + if (slices == 1) + { + if (samples > 1) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + } + } + else + { + if (samples > 1) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Texture2DMSArray.FirstArraySlice = 0; + srvDesc.Texture2DMSArray.ArraySize = slices; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = 0; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.ArraySize = slices; + } + } + device->CreateShaderResourceView(tex, &srvDesc, &srv); + + if (srv == nullptr) + { + tex->Release(); + return nullptr; + } + + CD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = dsv_format; + if (slices == 1) + { + if (samples > 1) + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } + else + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = 0; + } + } + else + { + if (samples > 1) + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Texture2DMSArray.FirstArraySlice = 0; + dsvDesc.Texture2DMSArray.ArraySize = slices; + } + else + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = 0; + dsvDesc.Texture2DArray.FirstArraySlice = 0; + dsvDesc.Texture2DArray.ArraySize = slices; + } + } + + device->CreateDepthStencilView(tex, &dsvDesc, &dsv); + dsvDesc.Flags |= D3D11_DSV_READ_ONLY_DEPTH; + if (dsv_format == DXGI_FORMAT_D24_UNORM_S8_UINT) + dsvDesc.Flags |= D3D11_DSV_READ_ONLY_STENCIL; + device->CreateDepthStencilView(tex, &dsvDesc, &dsv_ro); + if (dsv == nullptr || dsv_ro == nullptr) + { + tex->Release(); + srv->Release(); + return nullptr; + } + +#if (NV_DEBUG || NV_PROFILE) + if (debug_name) + { + tex->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(debug_name), debug_name); + } +#else + debug_name; +#endif + + return new DepthTarget(tex, srv, dsv, dsv_ro, nullptr); +} + +DepthTarget::DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav) + : ShaderResource(resource, srv, uav) +{ + dsv_ = dsv; + readonly_dsv_ = readonly_dsv; +} + +DepthTarget::~DepthTarget() +{ + SAFE_RELEASE(dsv_); + SAFE_RELEASE(readonly_dsv_); +} + diff --git a/samples/VolumetricLightingTest/d3d11/d3d11_util.h b/samples/VolumetricLightingTest/d3d11/d3d11_util.h new file mode 100644 index 0000000..e9322cf --- /dev/null +++ b/samples/VolumetricLightingTest/d3d11/d3d11_util.h @@ -0,0 +1,234 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2003 - 2016 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and 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. +// + +#ifndef D3D11_UTIL_H +#define D3D11_UTIL_H +//////////////////////////////////////////////////////////////////////////////// +#include "common.h" + +#include <d3d11.h> +#include <d3d11_1.h> + +#pragma warning( disable: 4127 ) + +//////////////////////////////////////////////////////////////////////////////// +/*============================================================================== + Overloaded functions to make shader compilation simpler +==============================================================================*/ +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11VertexShader ** out_shader); +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11HullShader ** out_shader); +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11DomainShader ** out_shader); +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11GeometryShader ** out_shader); +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11PixelShader ** out_shader); +HRESULT CompileShader(ID3D11Device * device, const void * data, UINT length, ID3D11ComputeShader ** out_shader); + + +template <class T> +NV_FORCE_INLINE HRESULT LoadShaders(ID3D11Device * device, const void ** shader_codes, const uint32_t * shader_lengths, UINT count, T ** &out_shaders) +{ + HRESULT hr = S_OK; + out_shaders = new T*[count]; + for (UINT i = 0; i < count; ++i) + { + const void * code = shader_codes[i]; + uint32_t length = shader_lengths[i]; + if (code == nullptr) + { + out_shaders[i] = nullptr; + continue; + } + hr = CompileShader(device, code, length, &out_shaders[i]); + ASSERT_LOG(hr == S_OK, "Failure loading shader"); + if (FAILED(hr)) + break; + } + return hr; +} + +/*============================================================================== + Perf Events +==============================================================================*/ + +class ScopedPerfEvent +{ +public: + ScopedPerfEvent(ID3D11DeviceContext * ctx, const wchar_t * msg) + { + ctx->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf)); + if (pPerf) + { + pPerf->BeginEvent(msg); + } + } + + ~ScopedPerfEvent() + { + if (pPerf) + { + pPerf->EndEvent(); + SAFE_RELEASE(pPerf); + } + }; + +private: + ScopedPerfEvent() : pPerf(nullptr) {}; + ID3DUserDefinedAnnotation * pPerf; +}; + +#if (NV_PROFILE) +# define NV_PERFEVENT(c, t) ScopedPerfEvent perfevent_##__COUNTER__##(c, L##t) +# define NV_PERFEVENT_BEGIN(c, t) { \ + ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \ + c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \ + if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->BeginEvent(L##t); pPerf_##__COUNTER__##->Release(); } } +# define NV_PERFEVENT_END(c) { \ + ID3DUserDefinedAnnotation * pPerf_##__COUNTER__ ; \ + c->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&pPerf_##__COUNTER__##)); \ + if (pPerf_##__COUNTER__##) { pPerf_##__COUNTER__##->EndEvent(); pPerf_##__COUNTER__##->Release(); } } +#else +# define NV_PERFEVENT(c, t) +# define NV_PERFEVENT_BEGIN(c, t) +# define NV_PERFEVENT_END(c) +#endif + +/*============================================================================== + Constant buffer management +==============================================================================*/ + +template <class T> +class ConstantBuffer +{ +public: + static ConstantBuffer<T> * Create(ID3D11Device * device) + { + HRESULT hr; + ID3D11Buffer * cb = nullptr; + + static_assert((sizeof(T) % 16) == 0, "Constant buffer size must be 16-byte aligned"); + + CD3D11_BUFFER_DESC cbDesc; + cbDesc.ByteWidth = sizeof(T); + cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + cbDesc.Usage = D3D11_USAGE_DYNAMIC; + cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + cbDesc.MiscFlags = 0; + cbDesc.StructureByteStride = 1; + hr = device->CreateBuffer(&cbDesc, nullptr, &cb); + if (cb == nullptr) + return nullptr; + return new ConstantBuffer<T>(cb); + } + + ConstantBuffer(ID3D11Buffer * b) + { + buffer_ = b; + } + + ~ConstantBuffer() + { + SAFE_RELEASE(buffer_); + } + + T * Map(ID3D11DeviceContext * ctx) + { + HRESULT hr; + D3D11_MAPPED_SUBRESOURCE data; + hr = ctx->Map(buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &data); + return static_cast<T*>(data.pData); + } + + void Unmap(ID3D11DeviceContext * ctx) + { + ctx->Unmap(buffer_, 0); + } + + ID3D11Buffer * getCB() { return buffer_; } + +private: + ConstantBuffer() {}; + + ID3D11Buffer *buffer_; +}; + +/*============================================================================== + Texture resource management helpers +==============================================================================*/ + +//------------------------------------------------------------------------------ +class ShaderResource +{ +public: + ShaderResource(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11UnorderedAccessView * uav); + ~ShaderResource(); + + ID3D11Resource * getResource() { return resource_; } + ID3D11ShaderResourceView * getSRV() { return srv_; } + ID3D11UnorderedAccessView * getUAV() { return uav_; } + +protected: + ShaderResource() {}; + + ID3D11Resource * resource_; + ID3D11ShaderResourceView * srv_; + ID3D11UnorderedAccessView * uav_; +}; + +//------------------------------------------------------------------------------ +class RenderTarget : public ShaderResource +{ +public: + static RenderTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, const char * debug_name=nullptr); + RenderTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11RenderTargetView * rtv, ID3D11UnorderedAccessView * uav); + ~RenderTarget(); + + ID3D11RenderTargetView * getRTV() { return rtv_; } + +protected: + RenderTarget() {}; + ID3D11RenderTargetView * rtv_; +}; + +//------------------------------------------------------------------------------ +class DepthTarget : public ShaderResource +{ +public: + static DepthTarget * Create(ID3D11Device * device, UINT width, UINT height, UINT samples, DXGI_FORMAT format, uint32_t slices=1, char * debug_name=nullptr); + DepthTarget(ID3D11Resource * resource, ID3D11ShaderResourceView * srv, ID3D11DepthStencilView * dsv, ID3D11DepthStencilView * readonly_dsv, ID3D11UnorderedAccessView * uav); + ~DepthTarget(); + + ID3D11DepthStencilView * getDSV() { return dsv_; } + ID3D11DepthStencilView * getReadOnlyDSV() { return readonly_dsv_; } + +protected: + DepthTarget() {}; + ID3D11DepthStencilView * dsv_; + ID3D11DepthStencilView * readonly_dsv_; +}; + +//////////////////////////////////////////////////////////////////////////////// +#endif // D3D11_UTIL_H
\ No newline at end of file |