-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRenderThread.h
157 lines (134 loc) · 5.42 KB
/
RenderThread.h
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
// Copyright 2020-2021 NVIDIA Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <condition_variable>
#include <mutex>
#include <optional>
#include <thread>
#include <d3dx12.h>
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
#include <nvh/fileoperations.hpp>
#include <nvh/appwindowprofiler.hpp>
#include <nvdx12/base_dx12.hpp>
#include <nvdx12/context_dx12.hpp>
#include <nvapi.h>
enum class DisplayMode
{
WINDOWED,
BORDERLESS,
FULLSCREEN,
};
struct Configuration
{
std::string m_startupDisplayMode = "b";
std::string m_testMode = "n";
std::string m_frameCounterFilePath = "";
bool m_disablePresentBarrier = false;
bool m_stereo = false;
bool m_showVerticalLines = true;
bool m_showHorizontalLines = true;
bool m_scrolling = true;
bool m_quadroSync = false;
std::uint32_t m_testModeInterval = 120;
std::uint32_t m_numLines = 4;
std::uint32_t m_lineSpeedInPixels = 1;
std::uint32_t m_sleepIntervalInMilliseconds = 0;
std::uint32_t m_lineSizeInPixels[2] = {1, 54};
std::uint32_t m_syncTimeoutMillis = 1000;
std::int32_t m_outputIndex = -1;
std::uint32_t m_winSize[2];
};
// window attributes can only be changed from window-owning thread
class WindowCallback
{
public:
virtual void setDecorated(bool decorated) = 0;
virtual void setPosAndSize(int x, int y, int width, int height) = 0;
virtual HWND getWindowHandle() = 0;
virtual struct GLFWwindow* getGlfwWindow() = 0;
};
class RenderThread
{
public:
RenderThread();
~RenderThread() {}
bool start(Configuration const& initialConfig, WindowCallback* windowCallback);
void togglePaused();
void interruptAndJoin();
DisplayMode trySetDisplayMode(DisplayMode displayMode);
void setSleepInterval(std::uint32_t millis);
void changeSleepInterval(std::int32_t deltaMillis);
void toggleStereo();
void toggleQuadroSync();
void setVsync(bool enabled);
void requestBorderlessStateChange();
void requestFullscreenStateChange();
bool requestPresentBarrierChange(std::uint32_t maxWaitMillis);
void requestResetFrameCount();
void forcePresentBarrierChange();
nvdx12::ContextCreateInfo& contextInfo() { return m_contextInfo; }
private:
enum class Status
{
CREATED,
INITIAZATION_ERROR,
RUNNING,
PAUSED,
INTERRUPTED,
};
std::thread m_thread;
Status m_status = Status::CREATED;
std::mutex m_mutex;
std::condition_variable m_conVar;
WindowCallback* m_windowCallback = nullptr;
Configuration m_config;
NvU32 m_linesPosOffset = 0;
bool m_requestToggleStereo = false;
bool m_requestResetFrameCount = false;
bool m_skipNextSwap = false;
std::ofstream m_frameCounterFile;
nvdx12::ContextCreateInfo m_contextInfo;
nvdx12::Context m_context;
ComPtr<ID3D12Fence> m_presentBarrierFence;
ComPtr<ID3D12Fence> m_frameFence;
ComPtr<ID3D12Fence> m_guiFence;
UINT64 m_frameIdx = 0;
HANDLE m_syncEvt = NULL;
ComPtr<IDXGISwapChain3> m_swapChain;
std::vector<ComPtr<ID3D12Resource>> m_backBufferResources;
ComPtr<ID3D12Resource> m_guiTexture;
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
ComPtr<ID3D12DescriptorHeap> m_cbvSrvUavHeap;
ComPtr<ID3D12GraphicsCommandList> m_graphicsCommandList;
std::vector<ComPtr<ID3D12CommandAllocator>> m_graphicsCommandAllocators;
ComPtr<ID3D12GraphicsCommandList> m_guiCommandList;
std::vector<ComPtr<ID3D12CommandAllocator>> m_guiCommandAllocators;
std::vector<UINT64> m_allocatorFrameIndices;
NvPresentBarrierClientHandle m_presentBarrierClient = nullptr;
ComPtr<ID3D12PipelineState> m_linesPipeline;
ComPtr<ID3D12PipelineState> m_indicatorPipeline;
ComPtr<ID3D12PipelineState> m_guiPipeline;
ComPtr<ID3D12RootSignature> m_rootSignature;
DisplayMode m_displayMode = DisplayMode::WINDOWED;
DisplayMode m_requestedDisplayMode = DisplayMode::WINDOWED;
bool m_presentBarrierChangeRequested = false;
bool m_presentBarrierJoined = false;
NvU32 m_frameCount = 0;
NvU32 m_syncInterval = 0;
NV_PRESENT_BARRIER_FRAME_STATISTICS m_presentBarrierFrameStats = {};
bool isInterrupted();
bool init(unsigned int initialWidth, unsigned int initialHeight);
void setStatus(Status newStatus);
void waitIfPaused();
void renderFrame();
void swapResize(int width, int height, bool stereo, bool force);
void swapBuffers();
bool sync();
void end();
void releasePresentBarrier();
void drawLines(ComPtr<ID3D12GraphicsCommandList> commandList, uint32_t offset = 0);
void drawSyncIndicator(ComPtr<ID3D12GraphicsCommandList> commandList);
void drawGui(ComPtr<ID3D12GraphicsCommandList> commandList);
void prepareGui();
};