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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
//----------------------------------------------------------------------------------
// File: FaceWorks/samples/sample_d3d11/util.h
// SDK Version: v1.0
// Email: [email protected]
// Site: http://developer.nvidia.com/
//
// Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//----------------------------------------------------------------------------------
#pragma once
#include <string>
#include <vector>
#include <DXUT/Core/DXUT.h>
#include <DXUT/Optional/DXUTcamera.h>
// Get the dimension of a static array
template <typename T, int N> char (&dim_helper(T (&)[N]))[N];
#define dim(x) (sizeof(dim_helper(x)))
#define dim_field(S, m) (dim(((S*)0)->m))
#define sizeof_field(S, m) (sizeof(((S*)0)->m))
// General utilities
std::wstring StrPrintf(const wchar_t * fmt, ...);
void DebugPrintf(const wchar_t * fmt, ...);
HRESULT LoadFile(const wchar_t * strFilename, std::vector<char> * pData, bool bText = false);
const wchar_t * BaseFilename(const wchar_t * strFilename);
void SetDebugName(ID3D11DeviceChild * pD3DObject, const char * strName);
void SetDebugName(ID3D11DeviceChild * pD3DObject, const wchar_t * strName);
// Mesh data & loading
struct Vertex
{
DirectX::XMFLOAT3 m_pos;
DirectX::XMFLOAT3 m_normal;
DirectX::XMFLOAT2 m_uv;
DirectX::XMFLOAT3 m_tangent;
float m_curvature;
};
class CMesh
{
public:
std::vector<Vertex> m_verts;
std::vector<int> m_indices;
ID3D11Buffer * m_pVtxBuffer;
ID3D11Buffer * m_pIdxBuffer;
UINT m_vtxStride; // Vertex stride for IASetVertexBuffers
UINT m_cIdx; // Index count for DrawIndexed
D3D11_PRIMITIVE_TOPOLOGY m_primtopo;
DirectX::XMFLOAT3 m_posMin, m_posMax; // Bounding box in local space
DirectX::XMFLOAT3 m_posCenter; // Center of bounding box
float m_diameter; // Diameter of bounding box
float m_uvScale; // Average world-space size of 1 UV unit
CMesh();
void Draw(ID3D11DeviceContext * pCtx);
void Release();
};
HRESULT CreateFullscreenMesh(ID3D11Device * pDevice, CMesh * pMesh);
HRESULT LoadObjMesh(
const wchar_t * strFilename,
ID3D11Device * pDevice,
CMesh * pMesh);
// Texture loading
enum LTFLAGS
{
LT_None = 0,
LT_Mipmap = 1,
LT_HDR = 2,
LT_Cubemap = 4,
LT_Linear = 8,
};
HRESULT LoadTexture(
const wchar_t * strFilename,
ID3D11Device * pDevice,
ID3D11DeviceContext * pDeviceContext,
ID3D11ShaderResourceView ** ppSrv,
int flags = LT_Mipmap);
HRESULT LoadTexture(
const wchar_t * strFilename,
ID3D11Device * pDevice,
ID3D11ShaderResourceView ** ppSrv,
int flags = 0);
// Camera class, based on DXUT camera but with Maya-style navigation
class CMayaStyleCamera : public CBaseCamera
{
public:
CMayaStyleCamera();
virtual void FrameMove(FLOAT fElapsedTime) override;
virtual void SetProjParams(FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, FLOAT fFarPlane) override;
virtual void SetViewParams(DirectX::FXMVECTOR pvEyePt, DirectX::FXMVECTOR pvLookatPt) override;
protected:
float m_fRadius; // Distance of orbit
};
// First-person camera class with right-handed matrices
class CFirstPersonCameraRH : public CFirstPersonCamera
{
public:
virtual void FrameMove(FLOAT fElapsedTime) override;
virtual void SetProjParams(FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, FLOAT fFarPlane) override;
};
// Very simple shadow map class, fits an orthogonal shadow map around a scene bounding box
class CShadowMap
{
public:
ID3D11DepthStencilView * m_pDsv;
ID3D11ShaderResourceView * m_pSrv;
int m_size; // Shadow map resolution
DirectX::XMFLOAT3 m_vecLight; // Unit vector toward directional light
DirectX::XMFLOAT3 m_posMinScene, m_posMaxScene; // AABB of scene in world space
DirectX::XMFLOAT4X4 m_matProj; // Projection matrix
DirectX::XMFLOAT4X4 m_matWorldToClip; // Matrix for rendering shadow map
DirectX::XMFLOAT4X4 m_matWorldToUvzw; // Matrix for sampling shadow map
DirectX::XMFLOAT4X4 m_matWorldToUvzNormal; // Matrix for transforming normals to shadow map space
DirectX::XMFLOAT3 m_vecDiam; // Diameter in world units along shadow XYZ axes
CShadowMap();
HRESULT Init(unsigned int size, ID3D11Device * pDevice);
void UpdateMatrix();
void BindRenderTarget(ID3D11DeviceContext * pCtx);
DirectX::XMFLOAT3 CalcFilterUVZScale(float filterRadius) const;
void Release()
{
SAFE_RELEASE(m_pDsv);
SAFE_RELEASE(m_pSrv);
}
};
// Variance shadow map
class CVarShadowMap
{
public:
ID3D11RenderTargetView * m_pRtv; // Main RT, stores (z, z^2)
ID3D11ShaderResourceView * m_pSrv;
ID3D11RenderTargetView * m_pRtvTemp; // Temp RT for Gaussian blur
ID3D11ShaderResourceView * m_pSrvTemp;
int m_size; // Shadow map resolution
float m_blurRadius; // Radius of Gaussian in UV space
CVarShadowMap();
HRESULT Init(unsigned int size, ID3D11Device * pDevice);
void UpdateFromShadowMap(const CShadowMap & shadow, ID3D11DeviceContext * pCtx);
void GaussianBlur(ID3D11DeviceContext * pCtx);
void Release()
{
SAFE_RELEASE(m_pRtv);
SAFE_RELEASE(m_pSrv);
SAFE_RELEASE(m_pRtvTemp);
SAFE_RELEASE(m_pSrvTemp);
}
};
// Perf measurement
// Enum of GPU timestamps to record
enum GTS
{
GTS_BeginFrame,
GTS_ShadowMap,
GTS_Skin,
GTS_Eyes,
GTS_EndFrame,
GTS_Max
};
class CGpuProfiler
{
public:
CGpuProfiler();
HRESULT Init(ID3D11Device * pDevice);
void Release();
void BeginFrame(ID3D11DeviceContext * pCtx);
void Timestamp(ID3D11DeviceContext * pCtx, GTS gts);
void EndFrame(ID3D11DeviceContext * pCtx);
// Wait on GPU for last frame's data (not the current frame's) to be available
void WaitForDataAndUpdate(ID3D11DeviceContext * pCtx);
float Dt(GTS gts) const { return m_adT[gts]; }
float GPUFrameTime() const { return m_gpuFrameTime; }
float DtAvg(GTS gts) const { return m_adTAvg[gts]; }
float GPUFrameTimeAvg() const { return m_gpuFrameTimeAvg; }
protected:
int m_iFrameQuery; // Which of the two sets of queries are we currently issuing?
int m_iFrameCollect; // Which of the two did we last collect?
ID3D11Query * m_apQueryTsDisjoint[2]; // "Timestamp disjoint" query; records whether timestamps are valid
ID3D11Query * m_apQueryTs[GTS_Max][2]; // Individual timestamp queries for each relevant point in the frame
bool m_fTsUsed[GTS_Max][2]; // Flags recording which timestamps were actually used in a frame
float m_adT[GTS_Max]; // Last frame's timings (each relative to previous GTS)
float m_gpuFrameTime;
float m_adTAvg[GTS_Max]; // Timings averaged over 0.5 second
float m_gpuFrameTimeAvg;
float m_adTTotal[GTS_Max]; // Total timings thus far within this averaging period
float m_gpuFrameTimeTotal;
int m_frameCount; // Frames rendered in current averaging period
DWORD m_tBeginAvg; // Time (in ms) at which current averaging period started
};
extern CGpuProfiler g_gpuProfiler;
|