aboutsummaryrefslogtreecommitdiff
path: root/demo/d3d12/appD3D12Ctx.h
blob: 4f6ba770e926bdb56b607d4e193c440da3277f38 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * Copyright (c) 2014-2017, 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.
 */

#ifndef APP_D3D12_CTX_H
#define APP_D3D12_CTX_H

#include "../d3d/appGraphCtx.h"
#include "NvCoDx12Resource.h"
#include "NvCoDx12Handle.h"

struct IDXGISwapChain3;

struct AppGraphProfilerD3D12;

struct AppDescriptorReserveHandleD3D12
{
	ID3D12DescriptorHeap* heap;
	UINT descriptorSize;
	D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle;
	D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle;
};

struct AppDynamicDescriptorHeapD3D12
{
	ID3D12Device* m_device = nullptr;
	ID3D12DescriptorHeap* m_heap = nullptr;
	UINT m_descriptorSize = 0u;
	UINT m_startSlot = 0u;
	UINT m_heapSize = 0u;

	void init(ID3D12Device* device, D3D12_DESCRIPTOR_HEAP_TYPE heapType, UINT minHeapSize);
	void release();
	AppDescriptorReserveHandleD3D12 reserveDescriptors(UINT numDescriptors, UINT64 lastFenceCompleted, UINT64 nextFenceValue);

	AppDynamicDescriptorHeapD3D12() {}
	~AppDynamicDescriptorHeapD3D12() { release(); }
};

struct AppGraphCtxD3D12
{
	HWND                    m_hWnd = nullptr;

	int m_winW = 0;
	int m_winH = 0;
	bool m_fullscreen = false;
	bool m_valid = false;

	size_t m_dedicatedVideoMemory = 0u;

	// D3D12 non-replicated objects
	D3D12_VIEWPORT          m_viewport = {};
	D3D12_RECT              m_scissorRect = {};
	ID3D12Device*           m_device = nullptr;
	ID3D12CommandQueue*     m_commandQueue = nullptr;

	// D3D12 render target pipeline
	static const UINT       m_renderTargetCount = 6u;
	UINT                    m_renderTargetIndex = 0u;
	UINT64                  m_renderTargetID = 0u;
	IDXGISwapChain3*        m_swapChain = nullptr;
	HANDLE                  m_swapChainWaitableObject = nullptr;
	ID3D12DescriptorHeap*   m_rtvHeap = nullptr;
	UINT                    m_rtvDescriptorSize = 0u;
	nvidia::Common::Dx12Resource   m_backBuffers[m_renderTargetCount];
	nvidia::Common::Dx12Resource   m_renderTargetResources[m_renderTargetCount];
	nvidia::Common::Dx12Resource*  m_renderTargets[m_renderTargetCount];

	ID3D12Resource*			m_depthStencil = nullptr;
	ID3D12DescriptorHeap*	m_dsvHeap = nullptr;
	ID3D12DescriptorHeap*	m_depthSrvHeap = nullptr;

	// D3D12 frame pipeline objects
	static const UINT       m_frameCount = 8u;
	UINT                    m_frameIndex = 0u;
	UINT64                  m_frameID = 0u;
	ID3D12CommandAllocator* m_commandAllocators[m_frameCount];

	// D3D12 synchronization objects
	ID3D12Fence*            m_fence = nullptr;
	HANDLE                  m_fenceEvent = 0u;
	UINT64					m_fenceValues[m_frameCount];

	// fence values for library synchronization
	UINT64					m_lastFenceComplete = 1u;
	UINT64					m_thisFrameFenceID = 2u;

	// D3D12 per asset objects
	ID3D12GraphicsCommandList*	m_commandList = nullptr;
	UINT						m_commandListOpenCount = 0;
	ID3D12Resource*				m_current_renderTarget = nullptr;
	D3D12_CPU_DESCRIPTOR_HANDLE m_current_rtvHandle;
	D3D12_RENDER_TARGET_VIEW_DESC m_current_rtvDesc;
	D3D12_CPU_DESCRIPTOR_HANDLE m_current_dsvHandle;
	D3D12_DEPTH_STENCIL_VIEW_DESC m_current_dsvDesc;
	D3D12_CPU_DESCRIPTOR_HANDLE m_current_depth_srvHandle;
	D3D12_SHADER_RESOURCE_VIEW_DESC m_current_depth_srvDesc;

	DXGI_FORMAT m_rtv_format = DXGI_FORMAT_R8G8B8A8_UNORM;
	DXGI_FORMAT m_dsv_format = DXGI_FORMAT_D32_FLOAT;
	DXGI_FORMAT m_depth_srv_format = DXGI_FORMAT_R32_FLOAT;
	DXGI_FORMAT m_depth_format = DXGI_FORMAT_R32_TYPELESS;

	UINT m_numMsaaSamples = 1;

	nvidia::Common::Dx12TargetInfo m_targetInfo;

	AppDynamicDescriptorHeapD3D12 m_dynamicHeapCbvSrvUav;

	AppGraphProfilerD3D12* m_profiler = nullptr;

	AppGraphCtxD3D12();
	~AppGraphCtxD3D12();
};

inline AppGraphCtxD3D12* cast_to_AppGraphCtxD3D12(AppGraphCtx* appctx)
{
	return (AppGraphCtxD3D12*)(appctx);
}

inline AppGraphCtx* cast_from_AppGraphCtxD3D12(AppGraphCtxD3D12* appctx)
{
	return (AppGraphCtx*)(appctx);
}

APP_GRAPH_CTX_API AppGraphCtx* AppGraphCtxCreateD3D12(int deviceID);

APP_GRAPH_CTX_API bool AppGraphCtxUpdateSizeD3D12(AppGraphCtx* context, SDL_Window* window, bool fullscreen, int numMSAASamples);

APP_GRAPH_CTX_API void AppGraphCtxReleaseRenderTargetD3D12(AppGraphCtx* context);

APP_GRAPH_CTX_API void AppGraphCtxReleaseD3D12(AppGraphCtx* context);

APP_GRAPH_CTX_API void AppGraphCtxFrameStartD3D12(AppGraphCtx* context, AppGraphColor clearColor);

APP_GRAPH_CTX_API void AppGraphCtxFramePresentD3D12(AppGraphCtx* context, bool fullsync);

APP_GRAPH_CTX_API void AppGraphCtxWaitForFramesD3D12(AppGraphCtx* context, unsigned int maxFramesInFlight);

APP_GRAPH_CTX_API void AppGraphCtxProfileEnableD3D12(AppGraphCtx* context, bool enabled);

APP_GRAPH_CTX_API void AppGraphCtxProfileBeginD3D12(AppGraphCtx* context, const char* label);

APP_GRAPH_CTX_API void AppGraphCtxProfileEndD3D12(AppGraphCtx* context, const char* label);

APP_GRAPH_CTX_API bool AppGraphCtxProfileGetD3D12(AppGraphCtx* context, const char** plabel, float* cpuTime, float* gpuTime, int index);

APP_GRAPH_CTX_API size_t AppGraphCtxDedicatedVideoMemoryD3D12(AppGraphCtx* context);

APP_GRAPH_CTX_API void AppGraphCtxBeginGpuWork(AppGraphCtxD3D12* context);

APP_GRAPH_CTX_API void AppGraphCtxEndGpuWork(AppGraphCtxD3D12* context);

APP_GRAPH_CTX_API void AppGraphCtxPrepareRenderTarget(AppGraphCtxD3D12* context);

APP_GRAPH_CTX_API void AppGraphCtxWaitForGPU(AppGraphCtxD3D12* context);

/// ScopeGpuWork is used to handle gpu work that must be synchronized with the CPU.
/// It is guaranteed when scope is released the CPU and GPU will sync. NOTE! This means 
/// you don't want to do this as part of render/update unless you have to because it will be slow.
struct ScopeGpuWork
{
	inline ScopeGpuWork(AppGraphCtxD3D12* context) :
		m_context(context)
	{
		AppGraphCtxBeginGpuWork(context);
	}
	inline ~ScopeGpuWork()
	{
		AppGraphCtxEndGpuWork(m_context);
	}
private:
	AppGraphCtxD3D12* m_context;
};
#endif