├── Shader.h
├── Demo.png
├── SimpleVS.hlsl
├── Shaders
├── BasicPS.cso
├── BasicVS.cso
├── LightPassPS.cso
└── ScreenQuadVS.cso
├── clusteredShadingD3D12.exe
├── Executable
├── Shaders
│ ├── BasicPS.cso
│ ├── BasicVS.cso
│ ├── LightPassPS.cso
│ └── ScreenQuadVS.cso
└── DeferredShadingD3D12.exe
├── ScreenQuadVS.hlsl
├── README.md
├── BasicVS.hlsl
├── ScreenQuadRenderer.h
├── stdafx.cpp
├── main.cpp
├── BasicPS.hlsl
├── .gitattributes
├── ShaderManager.h
├── stdafx.h
├── SphereRenderer.h
├── windowsApp.h
├── VertexStructures.h
├── DirectXMathConverter.h
├── DeferredRender.hlsli
├── SimpleDeferredShadingD3D12.sln
├── LightPassPS.hlsl
├── Lighting.hlsli
├── ScreenQuadRenderer.cpp
├── ShaderManager.cpp
├── DeferredRender.h
├── windowsApp.cpp
├── .gitignore
├── clusteredShadingD3D12.vcxproj.filters
├── SphereRenderer.cpp
├── DirectxApp.h
├── DeviceResources.h
├── CameraManager.h
├── DirectxHelper.h
├── clusteredShadingD3D12.vcxproj
├── CameraManager.cpp
├── DirectxHelper.cpp
├── DeviceResources.cpp
├── DeferredRender.cpp
└── d3dx12.h
/Shader.h:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Demo.png
--------------------------------------------------------------------------------
/SimpleVS.hlsl:
--------------------------------------------------------------------------------
1 | float4 main( float4 pos : POSITION ) : SV_POSITION
2 | {
3 | return pos;
4 | }
--------------------------------------------------------------------------------
/Shaders/BasicPS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Shaders/BasicPS.cso
--------------------------------------------------------------------------------
/Shaders/BasicVS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Shaders/BasicVS.cso
--------------------------------------------------------------------------------
/Shaders/LightPassPS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Shaders/LightPassPS.cso
--------------------------------------------------------------------------------
/Shaders/ScreenQuadVS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Shaders/ScreenQuadVS.cso
--------------------------------------------------------------------------------
/clusteredShadingD3D12.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/clusteredShadingD3D12.exe
--------------------------------------------------------------------------------
/Executable/Shaders/BasicPS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Executable/Shaders/BasicPS.cso
--------------------------------------------------------------------------------
/Executable/Shaders/BasicVS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Executable/Shaders/BasicVS.cso
--------------------------------------------------------------------------------
/Executable/Shaders/LightPassPS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Executable/Shaders/LightPassPS.cso
--------------------------------------------------------------------------------
/Executable/DeferredShadingD3D12.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Executable/DeferredShadingD3D12.exe
--------------------------------------------------------------------------------
/Executable/Shaders/ScreenQuadVS.cso:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shuhuai/DeferredShadingD3D12/HEAD/Executable/Shaders/ScreenQuadVS.cso
--------------------------------------------------------------------------------
/ScreenQuadVS.hlsl:
--------------------------------------------------------------------------------
1 | #include "DeferredRender.hlsli"
2 |
3 |
4 |
5 | vs_out main(vs_in vIn)
6 | {
7 | vs_out vOut;
8 | vOut.position = vIn.position;
9 | vOut.texcoord = vIn.texcoord;
10 | return vIn;
11 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Simple deferred shading with DirectX 12
2 |
3 | A DirectX 12 simple deferred shading system.
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BasicVS.hlsl:
--------------------------------------------------------------------------------
1 |
2 | #include "DeferredRender.hlsli"
3 |
4 |
5 |
6 | vs_gbuffer_out main(vs_gbuffer_in vIn)
7 | {
8 |
9 | vs_gbuffer_out vOut;
10 | vOut.position = mul(vIn.position, gMVP);
11 |
12 | vOut.normal = vIn.normal;
13 | vOut.worldPos = vOut.position/ vOut.position.w;
14 | return vOut;
15 | }
--------------------------------------------------------------------------------
/ScreenQuadRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "DirectxHelper.h"
3 |
4 | class ScreenQuadRenderer
5 | {
6 | public:
7 | void Init();
8 | void Draw(ComPtr commandList);
9 |
10 | private:
11 | ComPtr mVB;
12 |
13 | D3D12_VERTEX_BUFFER_VIEW mVbView;
14 |
15 | };
--------------------------------------------------------------------------------
/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // triangleDX12.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 | // TODO: reference any additional headers you need in STDAFX.H
8 | // and not in this file
9 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "stdafx.h"
4 |
5 |
6 | #include "directxApp.h"
7 |
8 |
9 |
10 | int APIENTRY WinMain(_In_ HINSTANCE hInstance,
11 | _In_opt_ HINSTANCE hPrevInstance,
12 | _In_ LPSTR lpCmdLine,
13 | _In_ int nCmdShow)
14 | {
15 | directxProcess* App = new directxProcess();
16 | return App->Run(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
17 | }
18 |
--------------------------------------------------------------------------------
/BasicPS.hlsl:
--------------------------------------------------------------------------------
1 | #include "DeferredRender.hlsli"
2 | struct ps_output
3 | {
4 | float3 albedo : SV_TARGET0;
5 | float4 normal : SV_TARGET1;
6 | float4 specgloss : SV_TARGET2;
7 | };
8 |
9 | ps_output main(vs_gbuffer_out pIn) : SV_TARGET
10 | {
11 | ps_output output;
12 | output.albedo= float3(1.0f, 0.0f, 0.0f);
13 | output.normal= float4(pIn.normal, 1.0f);
14 |
15 |
16 | output.specgloss = float4(0.5,0.5,0.5,0.6);
17 |
18 | return output;
19 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/ShaderManager.h:
--------------------------------------------------------------------------------
1 | //a list to save all shader
2 | //using name get shader
3 |
4 | //To do :
5 |
6 | //2.Multi-thread loading
7 | //3.A Map table to speed up accessing shaders
8 | #pragma once
9 | #include "DirectxHelper.h"
10 | #include
11 |
12 |
13 |
14 | class ShaderManager
15 | {
16 | public:
17 | BOOL loadCompiledShader(std::string filename);
18 | BOOL LoadFolder(std::string foldername);
19 | ShaderObject* getShaderObj(std::string filename);
20 |
21 | private:
22 | std::vector mShaderList;
23 | std::string mFolderName="Shaders\\";
24 | std::string mExtensionName = ".cso";
25 | };
26 |
27 | extern ShaderManager g_ShaderManager;
--------------------------------------------------------------------------------
/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 |
9 |
10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11 | // Windows Header Files:
12 | #include
13 |
14 | // C RunTime Header Files
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
--------------------------------------------------------------------------------
/SphereRenderer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "DirectxHelper.h"
4 |
5 | class SphereRenderer
6 | {
7 | public:
8 | void Init(float radius,int slices,int segments);
9 | void resourceSetup();
10 | void Render(ComPtr commandList);
11 |
12 | private:
13 | ComPtr mVertexBuffer;
14 | ComPtr mDefaultBuffer;
15 | ComPtr mIndexBuffer;
16 | D3D12_VERTEX_BUFFER_VIEW mVertexView;
17 | D3D12_INDEX_BUFFER_VIEW mIndexView;
18 | int mSlices;
19 | int mSegments;
20 | int mTriangleSize;
21 | int mIndexSize;
22 | float mRadius;
23 | struct SimpleVertex
24 | {
25 | DirectX::XMFLOAT4 position;
26 | DirectX::XMFLOAT4 color;
27 | DirectX::XMFLOAT2 texcoord;
28 | };
29 | };
--------------------------------------------------------------------------------
/windowsApp.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class windowsApp
4 | {
5 |
6 | public:
7 | windowsApp();
8 |
9 | int Run(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow);
10 | protected:
11 | static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
12 | virtual void Setup(){ return ; }
13 | virtual void Update(){ return; }
14 | virtual void Render(){ return; }
15 | virtual void Resize(UINT width, UINT height) { return; }
16 | virtual void KeyDown(UINT key) { return; }
17 | virtual void KeyUp(UINT key) { return; }
18 | virtual void MouseMove(UINT xpos,UINT ypos) { return; }
19 | virtual void MousePress(UINT xpos, UINT ypos) { return; }
20 | virtual void MouseRelease(UINT key) { return; }
21 | int mWidth;
22 | int mHeight;
23 | HWND mHwnd;
24 | };
--------------------------------------------------------------------------------
/VertexStructures.h:
--------------------------------------------------------------------------------
1 | #include "DirectXMath.h"
2 |
3 | struct NormalVertex
4 | {
5 | DirectX::XMFLOAT4 position;
6 | DirectX::XMFLOAT3 normal;
7 |
8 |
9 | };
10 |
11 | static D3D12_INPUT_ELEMENT_DESC desNormalVertex[] = {
12 | { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
13 | { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
14 | };
15 |
16 | struct ScreenQuadVertex
17 | {
18 | DirectX::XMFLOAT4 position;
19 | DirectX::XMFLOAT2 texcoord;
20 |
21 |
22 | };
23 |
24 | static D3D12_INPUT_ELEMENT_DESC desScreenQuadVertex[] = {
25 | { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
26 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
27 | };
--------------------------------------------------------------------------------
/DirectXMathConverter.h:
--------------------------------------------------------------------------------
1 | #ifndef DirectXMathConverter
2 | #define DirectXMathConverter
3 |
4 | #include
5 | using namespace DirectX;
6 |
7 | inline XMVECTOR GMathFV(XMFLOAT3& val)
8 | {
9 | return XMLoadFloat3(&val);
10 | }
11 |
12 | inline XMVECTOR GMathFV(XMFLOAT2& val)
13 | {
14 | return XMLoadFloat2(&val);
15 | }
16 |
17 | inline XMFLOAT3 GMathVF(XMVECTOR& vec)
18 | {
19 | XMFLOAT3 val;
20 | XMStoreFloat3(&val, vec);
21 | return val;
22 | }
23 |
24 | inline XMFLOAT2 GMathVF2(XMVECTOR& vec)
25 | {
26 | XMFLOAT2 val;
27 | XMStoreFloat2(&val, vec);
28 | return val;
29 | }
30 |
31 |
32 | inline XMMATRIX GMathFM(XMFLOAT4X4& mat)
33 | {
34 | return XMLoadFloat4x4(&mat);
35 | }
36 |
37 | inline XMFLOAT4X4 GMathMF(XMMATRIX& mat)
38 | {
39 |
40 | XMFLOAT4X4 val;
41 | XMStoreFloat4x4(&val, mat);
42 | return val;
43 |
44 | }
45 | #endif
--------------------------------------------------------------------------------
/DeferredRender.hlsli:
--------------------------------------------------------------------------------
1 |
2 | cbuffer ViewData : register (b0)
3 | {
4 | float4x4 gMVP;
5 | float4x4 gInvPV;
6 | float3 gCamPos;
7 | }
8 | cbuffer LightData : register (b1)
9 | {
10 | float3 gLightPos;
11 | }
12 |
13 |
14 | struct vs_in {
15 | float4 position : POSITION;
16 | float2 texcoord : TEXCOORD;
17 | };
18 |
19 | struct vs_out {
20 | float4 position : SV_POSITION;
21 | float2 texcoord : TEXCOORD;
22 | };
23 |
24 | struct vs_gbuffer_in {
25 | float4 position : POSITION;
26 | float3 normal : NORMAL;
27 |
28 | };
29 | struct vs_gbuffer_out {
30 | float4 position : SV_POSITION;
31 | float3 normal : NORMAL;
32 | float4 worldPos :TEXCOORD;
33 | };
34 | struct SurfaceData
35 | {
36 | float3 positionView; // View space position
37 | float3 normal; // View space normal
38 | float4 albedo;
39 | float3 specular;
40 | float gloss;
41 | };
--------------------------------------------------------------------------------
/SimpleDeferredShadingD3D12.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.22823.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleDefferedRenderingD3D12", "clusteredShadingD3D12.vcxproj", "{F840468D-2DBB-4F40-B215-4232A0935A79}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x86 = Debug|x86
11 | Release|x86 = Release|x86
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {F840468D-2DBB-4F40-B215-4232A0935A79}.Debug|x86.ActiveCfg = Debug|Win32
15 | {F840468D-2DBB-4F40-B215-4232A0935A79}.Debug|x86.Build.0 = Debug|Win32
16 | {F840468D-2DBB-4F40-B215-4232A0935A79}.Release|x86.ActiveCfg = Release|Win32
17 | {F840468D-2DBB-4F40-B215-4232A0935A79}.Release|x86.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/LightPassPS.hlsl:
--------------------------------------------------------------------------------
1 | #include "DeferredRender.hlsli"
2 | #include "Lighting.hlsli"
3 |
4 | Texture2D gAlbedoTexture : register(t0);
5 | Texture2D gNormalTexture : register(t1);
6 | Texture2D gSpecularGlossTexture : register(t2);
7 | Texture2D gDepth: register(t3);
8 |
9 | sampler gLinearSample;
10 |
11 | float4 main(vs_out pIn) : SV_TARGET
12 | {
13 |
14 |
15 | float z = gDepth[pIn.position.xy];
16 | float4 vProjectedPos = float4(pIn.position.xy, z, 1.0f);
17 | // Transform by the inverse screen view projection matrix to world space
18 | float4 vPositionWS = mul(vProjectedPos, gInvPV);
19 | // Divide by w to get the view-space position
20 | vPositionWS= vPositionWS / vPositionWS.w;
21 | float3 albedo = gAlbedoTexture[pIn.position.xy].xyz;
22 | float3 normal = normalize(gNormalTexture[pIn.position.xy].xyz);
23 | float4 specGloss = gSpecularGlossTexture[pIn.position.xy].xyzw;
24 |
25 | float3 col=GGXBRDF(normalize(gLightPos.xyz- vPositionWS.xyz), gLightPos, albedo ,normal,
26 | normalize(gCamPos - vPositionWS), specGloss.xyz, specGloss.w);
27 | float d = length(gLightPos.xyz - vPositionWS.xyz);
28 | col = col*(1.0f / (1.0f + 0.1f*d + 0.01f*d));
29 |
30 | return float4(col,1.0f);
31 |
32 |
33 | }
--------------------------------------------------------------------------------
/Lighting.hlsli:
--------------------------------------------------------------------------------
1 | float G_Smith(float roughness, float NoV, float NoL)
2 | {
3 | float k = (roughness + 1) * (roughness + 1) / 8;
4 | return (NoV / (NoV * (1 - k) + k)) * (NoL / (NoL * (1 - k) + k));
5 | }
6 |
7 | float3 GGXBRDF(float3 lightDir,float3 lightPos,float3 albedo,float3 normal,float3 viewDir,float3 specular,float gloss)
8 | {
9 | const float pi = 3.14159;
10 | float3 h = normalize(viewDir + lightDir);
11 |
12 |
13 | float NdotL = max(0, dot(normal, lightDir));
14 | float NdotH = max(0, dot(normal, h));
15 | float LdotH = max(0, dot(lightDir, h));
16 | float VdotH = max(0, dot(viewDir, h));
17 | float NdotV = max(0, dot(normal, viewDir));
18 | float roughness = gloss;
19 |
20 | //D
21 | float alpha = roughness * roughness;
22 | float alphaSqr = alpha*alpha;
23 | float denom = ((NdotH * NdotH) * (alphaSqr - 1.0f) + 1.0f);
24 | float D = alphaSqr / (pi * denom* denom);
25 | float FV;
26 |
27 | //fersnel & V
28 | float F_b = pow((1 - VdotH), 5);
29 | float F_a = 1;
30 | float k = alpha / 2;
31 | float vis = G_Smith(roughness, NdotV, NdotL);
32 | float2 FV_helper = float2(F_a*vis, F_b*vis);
33 | float3 col = specular*FV_helper.x + (1 - specular)*FV_helper.y;
34 |
35 | col = (NdotL*D*col + NdotL*albedo);
36 |
37 | return float4(col,1);
38 | }
--------------------------------------------------------------------------------
/ScreenQuadRenderer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "ScreenQuadRenderer.h"
3 | #include "VertexStructures.h"
4 | #include "d3dx12.h"
5 | void ScreenQuadRenderer::Init()
6 | {
7 | ScreenQuadVertex QuadVerts[] =
8 | {
9 | { { -1.0f,1.0f, 0.0f,1.0f },{ 0.0f,0.0f } },
10 | { { 1.0f, 1.0f, 0.0f,1.0f }, {1.0f,0.0f } },
11 | { { -1.0f, -1.0f, 0.0f,1.0f },{ 0.0f,1.0f } },
12 | { { 1.0f, -1.0f, 0.0f,1.0f },{ 1.0f,1.0f } }
13 | };
14 |
15 | CD3DX12_HEAP_PROPERTIES heapProperty(D3D12_HEAP_TYPE_UPLOAD);
16 |
17 |
18 | D3D12_RESOURCE_DESC resourceDesc;
19 | ZeroMemory(&resourceDesc, sizeof(resourceDesc));
20 | resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
21 | resourceDesc.Alignment = 0;
22 | resourceDesc.SampleDesc.Count = 1;
23 | resourceDesc.SampleDesc.Quality = 0;
24 | resourceDesc.MipLevels = 1;
25 | resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
26 | resourceDesc.DepthOrArraySize = 1;
27 | resourceDesc.Width = sizeof(QuadVerts);
28 | resourceDesc.Height = 1;
29 | resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
30 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(mVB.GetAddressOf())));
31 |
32 | UINT8* dataBegin;
33 | ThrowIfFailed(mVB->Map(0, nullptr, reinterpret_cast(&dataBegin)));
34 | memcpy(dataBegin, QuadVerts, sizeof(QuadVerts));
35 | mVB->Unmap(0, nullptr);
36 |
37 | mVbView.BufferLocation = mVB->GetGPUVirtualAddress();
38 | mVbView.StrideInBytes = sizeof(ScreenQuadVertex);
39 | mVbView.SizeInBytes = sizeof(QuadVerts);
40 | }
41 |
42 | void ScreenQuadRenderer::Draw(ComPtr commandList)
43 | {
44 | commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
45 | commandList->IASetVertexBuffers(0, 1, &mVbView);
46 | commandList->DrawInstanced(4, 1, 0, 0);
47 | }
48 |
--------------------------------------------------------------------------------
/ShaderManager.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "ShaderManager.h"
3 | #include
4 | ShaderManager g_ShaderManager;
5 |
6 | BOOL ShaderManager::loadCompiledShader(std::string filename)
7 | {
8 | ShaderObject shaderObj;
9 | FILE* fpVS = nullptr;
10 | fopen_s(&fpVS, (filename).c_str(), "rb");
11 | if (!fpVS) { return FALSE; }
12 | fseek(fpVS, 0, SEEK_END);
13 | shaderObj.size = ftell(fpVS);
14 | rewind(fpVS);
15 | shaderObj.binaryPtr = malloc(shaderObj.size);
16 | fread(shaderObj.binaryPtr, 1, shaderObj.size, fpVS);
17 | fclose(fpVS);
18 | fpVS = nullptr;
19 | std::size_t strIdx = filename.find_last_of("/\\");
20 | std::size_t endIdx = filename.find_last_of(".");
21 | filename=filename.substr(strIdx +1, (endIdx- strIdx)-1);
22 |
23 | shaderObj.name = filename;
24 | mShaderList.push_back(shaderObj);
25 | return TRUE;
26 | }
27 |
28 | BOOL ShaderManager::LoadFolder(std::string foldername)
29 | {
30 | using namespace std;
31 | HANDLE dir;
32 | WIN32_FIND_DATA file_data;
33 |
34 | if ((dir = FindFirstFile((foldername + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
35 | return 0; /* No files found */
36 |
37 | do {
38 | const string file_name = file_data.cFileName;
39 | std::size_t idx= file_name.find_last_of(".");
40 | string extension = file_name.substr(idx);
41 | if (extension.compare(mExtensionName) == 0)
42 | {
43 | const string full_file_name = foldername + "/" + file_name;
44 |
45 |
46 | loadCompiledShader(full_file_name);
47 | const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
48 |
49 | if (file_name[0] == '.')
50 | continue;
51 |
52 | if (is_directory)
53 | continue;
54 | }
55 |
56 |
57 | } while (FindNextFile(dir, &file_data));
58 |
59 | FindClose(dir);
60 |
61 | return 0;
62 | }
63 |
64 | ShaderObject* ShaderManager::getShaderObj(std::string filename)
65 | {
66 | for (unsigned int i = 0;i < mShaderList.size();i++)
67 | {
68 | if (mShaderList[i].name.compare(filename) == 0)
69 | {
70 | return &mShaderList[i];
71 | }
72 | }
73 | return nullptr;
74 | }
75 |
--------------------------------------------------------------------------------
/DeferredRender.h:
--------------------------------------------------------------------------------
1 | #include"DirectxHelper.h"
2 | #include "ShaderManager.h"
3 | #include "ScreenQuadRenderer.h"
4 | #include "d3dx12.h"
5 |
6 | //To do: loading texture support
7 | //1.Improve G-buffer shader
8 | //2.Descriptor support
9 |
10 | struct CameraData{
11 | DirectX::XMFLOAT4X4 MVP;
12 | DirectX::XMFLOAT4X4 InvPV;
13 | DirectX::XMFLOAT3 CamPos;
14 | };
15 | struct LightData {
16 | DirectX::XMFLOAT3 pos;
17 |
18 | };
19 | class DeferredRender
20 | {
21 | public:
22 | void Init();
23 | void InitWindowSizeDependentResources();
24 | ID3D12PipelineState* getPSO() { return m_pipelineState.Get(); }
25 | ID3D12RootSignature* getSignaturet() { return m_rootSignature.Get(); }
26 | void ApplyGBufferPSO(ID3D12GraphicsCommandList* command,bool bSetPSO=false);
27 | void ApplyLightingPSO(ID3D12GraphicsCommandList* command, bool bSetPSO = false);
28 |
29 | void UpdateConstantBuffer(CameraData& camData,LightData& ligData);
30 | private:
31 | void CreateLightPassPSO();
32 | void CreateRootSignature();
33 | void CreatePso();
34 | void CreateCB();
35 | void CreateViews();
36 | void CreateDSV();
37 | void CreateRTV();
38 |
39 | void CreateSRV();
40 | ComPtr m_rootSignature;
41 | ComPtr m_pipelineState;
42 | ComPtr mLightPso;
43 | ComPtr mCbvSrvUavDescriptorHeap;
44 | ScreenQuadRenderer mQuadRender;
45 |
46 | D3D12_GPU_DESCRIPTOR_HANDLE mGpuHandle;
47 |
48 | //0: CBV-Camera data
49 | //1: CBV-Light data
50 | //2: SRV-Albedo(RTV->SRV)
51 | //3: SRV-Normal(RTV->SRV)
52 | //4: SRV-Specular&gloss(RTV->SRV)
53 | //5: SRV-Depth(DSV->SRV)
54 | CDescriptorHeapWrapper m_cbvsrvHeap;
55 |
56 | CDescriptorHeapWrapper m_dsvHeap;
57 | CDescriptorHeapWrapper m_rtvHeap;
58 | CDescriptorHeapWrapper m_srvHeap;
59 |
60 | ComPtr mViewCB;
61 | ComPtr mLightCB;
62 | ComPtr mDsTexture;
63 |
64 | float mClearColor[4] = { 0.0,0.0f,0.0f,1.0f };
65 | float mClearDepth = 1.0f;
66 | const static int numRTV = 3;
67 | ComPtr mRtvTexture[numRTV];
68 |
69 | DXGI_FORMAT mDsvFormat= DXGI_FORMAT_D24_UNORM_S8_UINT;
70 | DXGI_FORMAT mRtvFormat[3] = { DXGI_FORMAT_R11G11B10_FLOAT,DXGI_FORMAT_R8G8B8A8_SNORM,DXGI_FORMAT_R8G8B8A8_UNORM };
71 | struct ConstantBuffer
72 | {
73 | DirectX::XMMATRIX mat;
74 | float color;
75 | };
76 | };
--------------------------------------------------------------------------------
/windowsApp.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "windowsApp.h"
3 | #include
4 | windowsApp* appPointer;
5 |
6 | LRESULT CALLBACK windowsApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
7 | {
8 | PAINTSTRUCT ps;
9 | HDC hdc;
10 |
11 | switch (message)
12 | {
13 | case WM_PAINT:
14 | hdc = BeginPaint(hWnd, &ps);
15 | EndPaint(hWnd, &ps);
16 | break;
17 | case WM_DESTROY:
18 | PostQuitMessage(0);
19 | break;
20 | case WM_SIZE:
21 | appPointer->Resize(LOWORD(lParam), HIWORD(lParam));
22 | break;
23 | case WM_KEYDOWN:
24 | appPointer->KeyDown(wParam);
25 | case WM_KEYUP:
26 | //appPointer->KeyUp(wParam);
27 | case WM_LBUTTONDOWN:
28 | appPointer->MousePress(LOWORD(lParam), HIWORD(lParam));
29 | case WM_LBUTTONUP:
30 | appPointer->MouseRelease(wParam);
31 | case WM_MOUSEMOVE:
32 | if (wParam == MK_LBUTTON)
33 | {
34 | appPointer->MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
35 | }
36 |
37 | default:
38 | return DefWindowProc(hWnd, message, wParam, lParam);
39 | }
40 | return 0;
41 | }
42 |
43 |
44 | windowsApp::windowsApp()
45 | {
46 | mWidth=800;
47 | mHeight=600;
48 | }
49 |
50 | int windowsApp::Run(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
51 | {
52 | appPointer = this;
53 | UNREFERENCED_PARAMETER(hPrevInstance);
54 | UNREFERENCED_PARAMETER(lpCmdLine);
55 | MSG msg;
56 |
57 | WNDCLASSEX wc;
58 | ZeroMemory(&wc, sizeof(wc));
59 | ZeroMemory(&msg, sizeof(msg));
60 |
61 | wc.cbSize = sizeof(wc);
62 | wc.style = CS_HREDRAW | CS_VREDRAW;
63 | wc.lpfnWndProc = &windowsApp::WndProc;
64 | wc.hInstance = hInstance;
65 | wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
66 | wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
67 | wc.lpszClassName = "Deferred Shading";
68 | RegisterClassEx(&wc);
69 |
70 | RECT rect = { 0, 0, mWidth, mHeight };
71 | DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
72 | AdjustWindowRect(&rect, dwStyle, FALSE);
73 | mHwnd = CreateWindow(wc.lpszClassName,
74 | wc.lpszClassName,
75 | dwStyle,
76 | CW_USEDEFAULT, CW_USEDEFAULT,
77 | rect.right - rect.left, rect.bottom - rect.top,
78 | NULL, NULL, hInstance, NULL);
79 |
80 | ShowWindow(mHwnd, nCmdShow);
81 | UpdateWindow(mHwnd);
82 | Setup();
83 |
84 | while (msg.message != WM_QUIT) {
85 | if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
86 | TranslateMessage(&msg);
87 | DispatchMessage(&msg);
88 |
89 | }
90 | else {
91 | Update();
92 | Render();
93 |
94 | }
95 | }
96 |
97 |
98 |
99 | return (int)msg.wParam;
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # Build results
11 | [Dd]ebug/
12 | [Dd]ebugPublic/
13 | [Rr]elease/
14 | [Rr]eleases/
15 | x64/
16 | x86/
17 | build/
18 | bld/
19 | [Bb]in/
20 | [Oo]bj/
21 |
22 | # Roslyn cache directories
23 | *.ide/
24 |
25 | # MSTest test Results
26 | [Tt]est[Rr]esult*/
27 | [Bb]uild[Ll]og.*
28 |
29 | #NUNIT
30 | *.VisualState.xml
31 | TestResult.xml
32 |
33 | # Build Results of an ATL Project
34 | [Dd]ebugPS/
35 | [Rr]eleasePS/
36 | dlldata.c
37 |
38 | *_i.c
39 | *_p.c
40 | *_i.h
41 | *.ilk
42 | *.meta
43 | *.obj
44 | *.pch
45 | *.pdb
46 | *.pgc
47 | *.pgd
48 | *.rsp
49 | *.sbr
50 | *.tlb
51 | *.tli
52 | *.tlh
53 | *.tmp
54 | *.tmp_proj
55 | *.log
56 | *.vspscc
57 | *.vssscc
58 | .builds
59 | *.pidb
60 | *.svclog
61 | *.scc
62 |
63 | # Chutzpah Test files
64 | _Chutzpah*
65 |
66 | # Visual C++ cache files
67 | ipch/
68 | *.aps
69 | *.ncb
70 | *.opensdf
71 | *.sdf
72 | *.cachefile
73 |
74 | # Visual Studio profiler
75 | *.psess
76 | *.vsp
77 | *.vspx
78 |
79 | # TFS 2012 Local Workspace
80 | $tf/
81 |
82 | # Guidance Automation Toolkit
83 | *.gpState
84 |
85 | # ReSharper is a .NET coding add-in
86 | _ReSharper*/
87 | *.[Rr]e[Ss]harper
88 | *.DotSettings.user
89 |
90 | # JustCode is a .NET coding addin-in
91 | .JustCode
92 |
93 | # TeamCity is a build add-in
94 | _TeamCity*
95 |
96 | # DotCover is a Code Coverage Tool
97 | *.dotCover
98 |
99 | # NCrunch
100 | _NCrunch_*
101 | .*crunch*.local.xml
102 |
103 | # MightyMoose
104 | *.mm.*
105 | AutoTest.Net/
106 |
107 | # Web workbench (sass)
108 | .sass-cache/
109 |
110 | # Installshield output folder
111 | [Ee]xpress/
112 |
113 | # DocProject is a documentation generator add-in
114 | DocProject/buildhelp/
115 | DocProject/Help/*.HxT
116 | DocProject/Help/*.HxC
117 | DocProject/Help/*.hhc
118 | DocProject/Help/*.hhk
119 | DocProject/Help/*.hhp
120 | DocProject/Help/Html2
121 | DocProject/Help/html
122 |
123 | # Click-Once directory
124 | publish/
125 |
126 | # Publish Web Output
127 | *.[Pp]ublish.xml
128 | *.azurePubxml
129 | # TODO: Comment the next line if you want to checkin your web deploy settings
130 | # but database connection strings (with potential passwords) will be unencrypted
131 | *.pubxml
132 | *.publishproj
133 |
134 | # NuGet Packages
135 | *.nupkg
136 | # The packages folder can be ignored because of Package Restore
137 | **/packages/*
138 | # except build/, which is used as an MSBuild target.
139 | !**/packages/build/
140 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
141 | #!**/packages/repositories.config
142 |
143 | # Windows Azure Build Output
144 | csx/
145 | *.build.csdef
146 |
147 | # Windows Store app package directory
148 | AppPackages/
149 |
150 | # Others
151 | sql/
152 | *.Cache
153 | ClientBin/
154 | [Ss]tyle[Cc]op.*
155 | ~$*
156 | *~
157 | *.dbmdl
158 | *.dbproj.schemaview
159 | *.pfx
160 | *.publishsettings
161 | node_modules/
162 |
163 | # RIA/Silverlight projects
164 | Generated_Code/
165 |
166 | # Backup & report files from converting an old project file
167 | # to a newer Visual Studio version. Backup files are not needed,
168 | # because we have git ;-)
169 | _UpgradeReport_Files/
170 | Backup*/
171 | UpgradeLog*.XML
172 | UpgradeLog*.htm
173 |
174 | # SQL Server files
175 | *.mdf
176 | *.ldf
177 |
178 | # Business Intelligence projects
179 | *.rdl.data
180 | *.bim.layout
181 | *.bim_*.settings
182 |
183 | # Microsoft Fakes
184 | FakesAssemblies/
185 |
186 | # =========================
187 | # Operating System Files
188 | # =========================
189 |
190 | # OSX
191 | # =========================
192 |
193 | .DS_Store
194 | .AppleDouble
195 | .LSOverride
196 |
197 | # Thumbnails
198 | ._*
199 |
200 | # Files that might appear on external disk
201 | .Spotlight-V100
202 | .Trashes
203 |
204 | # Directories potentially created on remote AFP share
205 | .AppleDB
206 | .AppleDesktop
207 | Network Trash Folder
208 | Temporary Items
209 | .apdisk
210 |
211 | # Windows
212 | # =========================
213 |
214 | # Windows image file caches
215 | Thumbs.db
216 | ehthumbs.db
217 |
218 | # Folder config file
219 | Desktop.ini
220 |
221 | # Recycle Bin used on file shares
222 | $RECYCLE.BIN/
223 |
224 | # Windows Installer files
225 | *.cab
226 | *.msi
227 | *.msm
228 | *.msp
229 |
230 | # Windows shortcuts
231 | *.lnk
232 |
--------------------------------------------------------------------------------
/clusteredShadingD3D12.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {3dac389e-1ffc-49c8-9ad8-3881e06fe88c}
18 |
19 |
20 | {052d6356-759c-4a7d-af83-e673fd2037b3}
21 |
22 |
23 | {da869d46-9ceb-4b73-a856-0291a9a0f515}
24 |
25 |
26 | {d2fc8e7e-67eb-4fe8-bb3b-899a58113a3b}
27 |
28 |
29 | {5c23043e-e794-4d6c-a915-2a2521091ea6}
30 |
31 |
32 |
33 |
34 | Header Files
35 |
36 |
37 | Managers
38 |
39 |
40 | App
41 |
42 |
43 | Managers
44 |
45 |
46 | Renderer
47 |
48 |
49 | Managers
50 |
51 |
52 | Renderer
53 |
54 |
55 | Header Files
56 |
57 |
58 | Header Files
59 |
60 |
61 | Header Files
62 |
63 |
64 | App
65 |
66 |
67 | Techniques
68 |
69 |
70 |
71 |
72 | Source Files
73 |
74 |
75 | Managers
76 |
77 |
78 | Source Files
79 |
80 |
81 | App
82 |
83 |
84 | Managers
85 |
86 |
87 | Renderer
88 |
89 |
90 | Managers
91 |
92 |
93 | Renderer
94 |
95 |
96 | Techniques
97 |
98 |
99 |
100 |
101 | Shaders
102 |
103 |
104 | Shaders
105 |
106 |
107 | Shaders
108 |
109 |
110 | Shaders
111 |
112 |
113 |
114 |
115 | Shaders
116 |
117 |
118 | Shaders
119 |
120 |
121 |
--------------------------------------------------------------------------------
/SphereRenderer.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include "SphereRenderer.h"
4 | #include "VertexStructures.h"
5 | #include "DirectXMathConverter.h"
6 | #include
7 | #include
8 |
9 | using namespace DirectX;
10 | void SphereRenderer::Init(float radius,int slices, int segments)
11 | {
12 | mRadius = radius;
13 | mSlices=slices;
14 | mSegments=segments;
15 |
16 | resourceSetup();
17 | }
18 |
19 | void SphereRenderer::resourceSetup()
20 | {
21 |
22 |
23 | std::vector< NormalVertex > verts;
24 | verts.resize((mSegments+1)*mSlices+2);
25 |
26 | const float _pi = XM_PI;
27 | const float _2pi = XM_2PI;
28 |
29 | verts[0].position = XMFLOAT4(0, mRadius ,0,1) ;
30 | for (int lat = 0; lat < mSlices; lat++)
31 | {
32 | float a1 = _pi * (float)(lat + 1) / (mSlices + 1);
33 | float sin1 = sinf(a1);
34 | float cos1 = cosf(a1);
35 |
36 | for (int lon = 0; lon <= mSegments; lon++)
37 | {
38 | float a2 = _2pi * (float)(lon == mSegments ? 0 : lon) / mSegments;
39 | float sin2 = sinf(a2);
40 | float cos2 = cosf(a2);
41 |
42 | verts[lon + lat * (mSegments + 1) + 1].position = XMFLOAT4( sin1 * cos2* mRadius, cos1* mRadius, sin1 * sin2* mRadius,1) ;
43 | }
44 | }
45 | verts[verts.size() - 1].position = XMFLOAT4(0, -mRadius, 0, 1);
46 |
47 | for (int n = 0; n < verts.size(); n++)
48 | verts[n].normal = GMathVF(XMVector3Normalize( GMathFV(XMFLOAT3(verts[n].position.x, verts[n].position.y, verts[n].position.z))));
49 |
50 | int nbFaces = verts.size();
51 | int nbTriangles = nbFaces * 2;
52 | int nbIndexes = nbTriangles * 3;
53 | std::vector< int > triangles(nbIndexes);
54 | //int* triangles = new int[nbIndexes];
55 |
56 |
57 | int i = 0;
58 | for (int lon = 0; lon < mSegments; lon++)
59 | {
60 | triangles[i++] = lon + 2;
61 | triangles[i++] = lon + 1;
62 | triangles[i++] = 0;
63 | }
64 |
65 | //Middle
66 | for (int lat = 0; lat < mSlices - 1; lat++)
67 | {
68 | for (int lon = 0; lon < mSegments; lon++)
69 | {
70 | int current = lon + lat * (mSegments + 1) + 1;
71 | int next = current + mSegments + 1;
72 |
73 | triangles[i++] = current;
74 | triangles[i++] = current + 1;
75 | triangles[i++] = next + 1;
76 |
77 | triangles[i++] = current;
78 | triangles[i++] = next + 1;
79 | triangles[i++] = next;
80 | }
81 | }
82 |
83 | //Bottom Cap
84 | for (int lon = 0; lon < mSegments; lon++)
85 | {
86 | triangles[i++] = verts.size() - 1;
87 | triangles[i++] = verts.size() - (lon + 2) - 1;
88 | triangles[i++] = verts.size() - (lon + 1) - 1;
89 | }
90 | mTriangleSize= verts.size();
91 | mIndexSize= triangles.size();
92 | //Create D3D resources
93 | D3D12_HEAP_PROPERTIES heapProperty;
94 | ZeroMemory(&heapProperty, sizeof(heapProperty));
95 | heapProperty.Type = D3D12_HEAP_TYPE_UPLOAD;
96 |
97 | D3D12_RESOURCE_DESC resourceDesc;
98 | ZeroMemory(&resourceDesc, sizeof(resourceDesc));
99 | resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
100 | resourceDesc.Alignment = 0;
101 | resourceDesc.SampleDesc.Count = 1;
102 | resourceDesc.SampleDesc.Quality = 0;
103 | resourceDesc.MipLevels = 1;
104 | resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
105 | resourceDesc.DepthOrArraySize = 1;
106 | resourceDesc.Width = sizeof(NormalVertex)*verts.size();
107 | resourceDesc.Height = 1;
108 | resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
109 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(mVertexBuffer.GetAddressOf())));
110 |
111 | UINT8* dataBegin;
112 | ThrowIfFailed(mVertexBuffer->Map(0, nullptr, reinterpret_cast(&dataBegin)));
113 | memcpy(dataBegin, &verts[0], sizeof(NormalVertex)*verts.size());
114 | mVertexBuffer->Unmap(0, nullptr);
115 |
116 | mVertexView.BufferLocation = mVertexBuffer->GetGPUVirtualAddress();
117 | mVertexView.StrideInBytes = sizeof(NormalVertex);
118 | mVertexView.SizeInBytes = sizeof(NormalVertex)*verts.size();
119 |
120 | resourceDesc.Width = sizeof(int)*triangles.size();
121 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(mIndexBuffer.GetAddressOf())));
122 | ThrowIfFailed(mIndexBuffer->Map(0, nullptr, reinterpret_cast(&dataBegin)));
123 | memcpy(dataBegin, &triangles[0], sizeof(int)*triangles.size());
124 | mIndexBuffer->Unmap(0, nullptr);
125 |
126 |
127 | mIndexView.BufferLocation = mIndexBuffer->GetGPUVirtualAddress();
128 | mIndexView.Format = DXGI_FORMAT_R32_UINT;
129 | mIndexView.SizeInBytes= sizeof(int)*triangles.size();
130 | return;
131 | }
132 |
133 | void SphereRenderer::Render(ComPtr commandList)
134 | {
135 |
136 |
137 | commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
138 | commandList->IASetIndexBuffer(&mIndexView);
139 | commandList->IASetVertexBuffers(0, 1, &mVertexView);
140 | //commandList->DrawInstanced();
141 | commandList->DrawIndexedInstanced(mIndexSize,1, 0, 0,0);
142 |
143 | return;
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/DirectxApp.h:
--------------------------------------------------------------------------------
1 | #include "windowsApp.h"
2 | #include "DirectxHelper.h"
3 | #include
4 | #include "DeferredRender.h"
5 | #include "CameraManager.h"
6 | #include "SphereRenderer.h"
7 |
8 | class directxProcess :public windowsApp
9 | {
10 | ComPtr mCommandList;
11 |
12 | DeferredRender mDeferredTech;
13 | CameraData mCamData;
14 | LightData mLightData;
15 | GCamera mCamera;
16 | bool mInit = false;
17 | SphereRenderer mSphereRenderer;
18 |
19 | std::shared_ptr GetDeviceResources()
20 | {
21 | if (g_d3dObjects != nullptr && g_d3dObjects->IsDeviceRemoved())
22 | {
23 | // All references to the existing D3D device must be released before a new device
24 | // can be created.
25 |
26 | g_d3dObjects = nullptr;
27 | OnDeviceRemoved();
28 | }
29 |
30 | if (g_d3dObjects == nullptr)
31 | {
32 | g_d3dObjects = std::make_shared();
33 | g_d3dObjects->SetWindows(mHwnd, mWidth, mHeight);
34 | }
35 | return g_d3dObjects;
36 |
37 | };
38 |
39 | protected:
40 | void OnDeviceRemoved()
41 | {
42 |
43 | };
44 | void Setup()
45 | {
46 |
47 |
48 | auto commandQueue = GetDeviceResources()->GetCommandQueue();
49 |
50 | PIXBeginEvent(commandQueue, 0, L"Setup");
51 | {
52 | ThrowIfFailed(GetDeviceResources()->GetD3DDevice()->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_d3dObjects->GetCommandAllocator(), nullptr, IID_PPV_ARGS(mCommandList.GetAddressOf())));
53 |
54 | g_ShaderManager.LoadFolder("Shaders");
55 |
56 |
57 | mCamera.InitProjMatrix(3.14f*0.45f, mWidth, mHeight, 0.01f, 10000.0f);
58 | mCamera.Position(DirectX::XMFLOAT3(0,0.01f,-25.1f));
59 | mCamData.MVP = mCamera.ProjView();
60 | mCamData.InvPV = mCamera.InvScreenProjView();
61 | mCamData.CamPos = mCamera.Position();
62 |
63 | mLightData.pos = XMFLOAT3(0, 7, -15);
64 |
65 | mDeferredTech.Init();
66 | mDeferredTech.UpdateConstantBuffer(mCamData, mLightData);
67 |
68 | mSphereRenderer.Init(10, 20, 20);
69 |
70 | ThrowIfFailed(mCommandList->Close());
71 | ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
72 | GetDeviceResources()->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
73 |
74 | g_d3dObjects->WaitForGPU();
75 | }
76 | PIXEndEvent(commandQueue);
77 | mInit = true;
78 | }
79 | void Render()
80 | {
81 |
82 | auto commandQueue = GetDeviceResources()->GetCommandQueue();
83 | PIXBeginEvent(commandQueue, 0, L"Render");
84 | {
85 | ThrowIfFailed(g_d3dObjects->GetCommandAllocator()->Reset());
86 | ThrowIfFailed(mCommandList->Reset(g_d3dObjects->GetCommandAllocator(), mDeferredTech.getPSO()));
87 |
88 |
89 | AddResourceBarrier(mCommandList.Get(), g_d3dObjects->GetRenderTarget(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
90 |
91 | float clearColor[4]={ 0.0f,0.0f,0.0f,0.0f };
92 | mCommandList->ClearRenderTargetView(g_d3dObjects->GetRenderTargetView(), clearColor,0,nullptr);
93 | D3D12_RECT rect = { 0, 0, mWidth, mHeight };
94 |
95 |
96 |
97 | mCommandList->RSSetScissorRects(1, &rect);
98 | mCommandList->RSSetViewports(1, &g_d3dObjects->GetScreenViewport());
99 |
100 | mDeferredTech.ApplyGBufferPSO(mCommandList.Get());
101 | mSphereRenderer.Render(mCommandList);
102 |
103 |
104 | mCommandList->OMSetRenderTargets(1, &g_d3dObjects->GetRenderTargetView(),true, nullptr);
105 | mDeferredTech.ApplyLightingPSO(mCommandList.Get());
106 |
107 | AddResourceBarrier(mCommandList.Get(), g_d3dObjects->GetRenderTarget(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
108 |
109 | ThrowIfFailed(mCommandList->Close());
110 | ID3D12CommandList* ppCommandLists[1] = { mCommandList.Get() };
111 |
112 | commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
113 |
114 | g_d3dObjects->WaitForGPU();
115 |
116 | g_d3dObjects->Present();
117 |
118 | }
119 | PIXEndEvent(commandQueue);
120 | }
121 |
122 | void Update()
123 | {
124 | auto commandQueue = GetDeviceResources()->GetCommandQueue();
125 |
126 | PIXBeginEvent(commandQueue, 0, L"Update");
127 | {
128 | mCamera.Update();
129 | mCamData.MVP = mCamera.ProjView();
130 | mCamData.InvPV = mCamera.InvScreenProjView();
131 | mCamData.CamPos = mCamera.Position();
132 | mDeferredTech.UpdateConstantBuffer(mCamData, mLightData);
133 | }
134 | PIXEndEvent(commandQueue);
135 |
136 | }
137 | void Resize(UINT width, UINT height)
138 | {
139 | mWidth = width;
140 | mHeight = height;
141 | GetDeviceResources()->SetWindows(mHwnd,width,height);
142 | if (mInit)
143 | {
144 | mCamera.OnResize(mWidth, mHeight);
145 | mDeferredTech.InitWindowSizeDependentResources();
146 | }
147 |
148 | }
149 |
150 | void KeyDown(UINT key)
151 | {
152 | mCamera.KeyDown(key);
153 | return; }
154 |
155 | void MouseMove(UINT xpos, UINT ypos) {
156 | mCamera.InputMove(xpos, ypos);
157 | return; }
158 | void MousePress(UINT xpos, UINT ypos) {
159 | mCamera.InputPress(xpos,ypos);
160 | return; }
161 |
162 |
163 |
164 | };
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/DeviceResources.h:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 | #include
4 | #include "d3dx12.h"
5 | #pragma once
6 |
7 |
8 |
9 | namespace DX
10 | {
11 | // Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
12 | inline float ConvertDipsToPixels(float dips, float dpi)
13 | {
14 | static const float dipsPerInch = 96.0f;
15 | return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
16 | }
17 | inline void ThrowIfFailed(HRESULT hr)
18 | {
19 | if (FAILED(hr))
20 | {
21 | // Set a breakpoint on this line to catch Win32 API errors.
22 | throw _com_error(hr);
23 | }
24 | }
25 |
26 | class CDescriptorHeapWrapper
27 | {
28 | public:
29 | CDescriptorHeapWrapper() { memset(this, 0, sizeof(*this)); }
30 |
31 | HRESULT Create(
32 | ID3D12Device* pDevice,
33 | D3D12_DESCRIPTOR_HEAP_TYPE Type,
34 | UINT NumDescriptors,
35 | bool bShaderVisible = false)
36 | {
37 | Desc.Type = Type;
38 | Desc.NumDescriptors = NumDescriptors;
39 | Desc.Flags = (bShaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : (D3D12_DESCRIPTOR_HEAP_FLAGS)0);
40 |
41 | HRESULT hr = pDevice->CreateDescriptorHeap(&Desc,
42 | __uuidof(ID3D12DescriptorHeap),
43 | (void**)&pDH);
44 | if (FAILED(hr)) return hr;
45 |
46 | hCPUHeapStart = pDH->GetCPUDescriptorHandleForHeapStart();
47 | if (bShaderVisible)
48 | {
49 | hGPUHeapStart = pDH->GetGPUDescriptorHandleForHeapStart();
50 | }
51 | else
52 | {
53 | hGPUHeapStart.ptr = 0;
54 | }
55 | HandleIncrementSize = pDevice->GetDescriptorHandleIncrementSize(Desc.Type);
56 | return hr;
57 | }
58 | operator ID3D12DescriptorHeap*() { return pDH.Get(); }
59 |
60 | SIZE_T MakeOffsetted(SIZE_T ptr, UINT index)
61 | {
62 | SIZE_T offsetted;
63 | offsetted = ptr + index * HandleIncrementSize;
64 | return offsetted;
65 | }
66 | UINT64 MakeOffsetted(UINT64 ptr, UINT index)
67 | {
68 | UINT64 offsetted;
69 | offsetted = ptr + index * HandleIncrementSize;
70 | return offsetted;
71 | }
72 |
73 |
74 | D3D12_CPU_DESCRIPTOR_HANDLE hCPU(UINT index)
75 | {
76 | D3D12_CPU_DESCRIPTOR_HANDLE handle;
77 | handle.ptr = MakeOffsetted(hCPUHeapStart.ptr, index);
78 | return handle;
79 | }
80 | D3D12_GPU_DESCRIPTOR_HANDLE hGPU(UINT index)
81 | {
82 | assert(Desc.Flags&D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
83 | D3D12_GPU_DESCRIPTOR_HANDLE handle;
84 | handle.ptr = MakeOffsetted(hGPUHeapStart.ptr, index);
85 | return handle;
86 | }
87 | D3D12_DESCRIPTOR_HEAP_DESC Desc;
88 | Microsoft::WRL::ComPtr pDH;
89 | D3D12_CPU_DESCRIPTOR_HANDLE hCPUHeapStart;
90 | D3D12_GPU_DESCRIPTOR_HANDLE hGPUHeapStart;
91 | UINT HandleIncrementSize;
92 | };
93 |
94 | // Controls all the DirectX device resources.
95 | class DeviceResources
96 | {
97 | public:
98 | DeviceResources();
99 | void SetWindow(HWND hwnd,UINT width,UINT height);
100 | void SetLogicalSize(UINT width, UINT height);
101 |
102 |
103 | void ValidateDevice();
104 | void Present();
105 | void WaitForGpu();
106 |
107 |
108 | bool IsDeviceRemoved() const { return m_deviceRemoved; }
109 |
110 | // D3D Accessors.
111 | ID3D12Device* GetD3DDevice() const { return m_d3dDevice.Get(); }
112 | IDXGISwapChain* GetSwapChain() const { return m_swapChain.Get(); }
113 | ID3D12Resource* GetRenderTarget() const { return m_renderTargets[m_currentFrame].Get(); }
114 | ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
115 | ID3D12CommandAllocator* GetCommandAllocator() const { return m_commandAllocators[m_currentFrame].Get(); }
116 | D3D12_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
117 | DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
118 |
119 |
120 |
121 | private:
122 | void CreateDeviceIndependentResources();
123 | void CreateDeviceResources();
124 | void CreateWindowSizeDependentResources();
125 | void MoveToNextFrame();
126 |
127 |
128 | static const UINT c_frameCount = 3; // Use triple buffering.
129 | UINT m_currentFrame;
130 |
131 | // Direct3D objects.
132 | Microsoft::WRL::ComPtr m_d3dDevice;
133 | Microsoft::WRL::ComPtr m_dxgiFactory;
134 | Microsoft::WRL::ComPtr m_swapChain;
135 | Microsoft::WRL::ComPtr m_renderTargets[c_frameCount];
136 | Microsoft::WRL::ComPtr m_rtvHeap;
137 |
138 | Microsoft::WRL::ComPtr m_commandQueue;
139 | Microsoft::WRL::ComPtr m_commandAllocators[c_frameCount];
140 | D3D12_VIEWPORT m_screenViewport;
141 | bool m_deviceRemoved;
142 |
143 | // CPU/GPU Synchronization.
144 | Microsoft::WRL::ComPtr m_fence;
145 | UINT64 m_fenceValues[c_frameCount];
146 | HANDLE m_fenceEvent;
147 |
148 | // Cached reference to the Window.
149 | HWND m_hwnd;
150 |
151 | // Cached device properties.
152 | UINT m_renderTargetWidth;
153 | UINT m_renderTargetHeight;
154 | UINT m_outputWidth;
155 | UINT m_outputHeight;
156 | UINT m_logicalWidth;
157 | UINT m_logicalHeight;
158 | float m_dpi;
159 |
160 | // Transforms used for display orientation.
161 | DirectX::XMFLOAT4X4 m_orientationTransform3D;
162 | };
163 | }
164 |
--------------------------------------------------------------------------------
/CameraManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include "DirectXMathConverter.h"
4 | #include
5 |
6 | using namespace DirectX;
7 |
8 |
9 |
10 |
11 | //////////////////////////////////////////////////////
12 | // Stores View and Projection matrices used by shaders
13 | // to translate 3D world into 2D screen surface
14 | // Camera can be moved and rotated. Also, user can change
15 | // camera's target and position
16 | ////////////////////////////////////////////////////////
17 | class GCamera
18 | {
19 | public:
20 | // Constructs default camera looking at 0,0,0
21 | // placed at 0,0,-1 with up vector 0,1,0 (note that mUp is NOT a vector - it's vector's end)
22 | GCamera(void);
23 | // Create camera, based on another one
24 | GCamera(const GCamera& camera);
25 | // Copy all camera's parameters
26 | GCamera& operator=(const GCamera& camera);
27 | ~GCamera(void) {}
28 |
29 | private:
30 | // Initialize camera's View matrix from mPosition, mTarget and mUp coordinates
31 | void lookatViewMatrix();
32 | void buildViewMatrix();
33 | public:
34 | // Initialize camera's perspective Projection matrix
35 | void InitProjMatrix(const float angle, const float client_width, const float client_height,
36 | const float nearest, const float farthest);
37 | // Initialize camera's orthogonal projection
38 | void InitOrthoMatrix(const float client_width, const float client_height,
39 | const float near_plane, const float far_plane);
40 |
41 | // Resize matrices when window size changes
42 | void OnResize(uint32_t new_width, uint32_t new_height);
43 |
44 | ///////////////////////////////////////////////
45 | /*** View matrix transformation interfaces ***/
46 | ///////////////////////////////////////////////
47 |
48 | // Move camera
49 | void Move(XMFLOAT3 direction);
50 | // Rotate camera around `axis` by `degrees`. Camera's position is a
51 | // pivot point of rotation, so it doesn't change
52 | void Rotate(XMFLOAT3 axis, float degrees);
53 | // Set camera position coordinates
54 | void Position(XMFLOAT3& new_position);
55 | // Get camera position coordinates
56 | const XMFLOAT3& Position() const { return mPosition; }
57 | // Change camera target position
58 | void Target(XMFLOAT3 new_target);
59 | // Get camera's target position coordinates
60 | const XMFLOAT3& Target() const { return mTarget; }
61 | // Get camera's up vector
62 | const XMFLOAT3 Up() { return GMathVF(GMathFV(mUp) - GMathFV(mPosition)); }
63 | // Get camera's look at target vector
64 | XMFLOAT3 LookAtTarget() { return GMathVF(GMathFV(mTarget) - GMathFV(mPosition)); }
65 | // Returns transposed camera's View matrix
66 | const XMFLOAT4X4 View() { return GMathMF(XMMatrixTranspose(GMathFM(mView))); }
67 |
68 | /////////////////////////////////////////////////////
69 | /*** Projection matrix transformation interfaces ***/
70 | /////////////////////////////////////////////////////
71 |
72 | // Set view frustum's angle
73 | void Angle(float angle);
74 | // Get view frustum's angle
75 | const float& Angle() const { return mAngle; }
76 |
77 | // Set nearest culling plane distance from view frustum's projection plane
78 | void NearestPlane(float nearest);
79 | // Set farthest culling plane distance from view frustum's projection plane
80 | void FarthestPlane(float farthest);
81 |
82 | // Returns transposed camera's Projection matrix
83 | const XMFLOAT4X4 Proj() { return GMathMF(XMMatrixTranspose(GMathFM(mProj))); }
84 | // Returns transposed orthogonal camera matrix
85 | const XMFLOAT4X4 Ortho() { return GMathMF(XMMatrixTranspose(GMathFM(mOrtho))); }
86 |
87 | const XMFLOAT4X4 ProjView() {return GMathMF(XMMatrixTranspose(GMathFM(mView)*(GMathFM(mProj)))); }
88 |
89 |
90 | const XMFLOAT4X4 InvScreenProjView() {
91 |
92 |
93 | XMFLOAT4X4 matScreen = XMFLOAT4X4(2/mClientWidth,0,0,0,0, -2/ mClientHeight,0,0,0,0,1,0,-1,1,0,1);
94 | return GMathMF(XMMatrixTranspose(GMathFM(matScreen)*XMMatrixInverse(&XMMatrixDeterminant(GMathFM(mProj)), GMathFM(mProj))*
95 | XMMatrixInverse(&XMMatrixDeterminant(GMathFM(mView)), GMathFM(mView))));
96 | }
97 |
98 | void KeyDown(UINT key);
99 | void KeyUp(UINT key);
100 |
101 | void Update();
102 |
103 | void InputPress( float x, float y);
104 |
105 | void InputMove( float x, float y);
106 |
107 | void InputRelease();
108 |
109 | void SetSpeed(float speed) { mSpeed=speed; }
110 |
111 | private:
112 | const float ROTATION_GAIN = 0.004f;
113 | const float MOVEMENT_GAIN =0.1f;
114 | float mSpeed;
115 | float m_pitch, m_yaw; // orientation euler angles in radians
116 | /*** Input parameters ***/
117 | // properties of the Look control
118 | bool m_lookInUse; // specifies whether the look control is in use
119 | int m_lookPointerID; // id of the pointer in this control
120 | XMFLOAT2 m_lookLastPoint; // last point (from last frame)
121 | XMFLOAT2 m_lookLastDelta; // for smoothing
122 | bool m_forward;
123 | bool m_back;
124 | bool m_left;
125 | bool m_right;
126 |
127 |
128 |
129 | /*** Camera parameters ***/
130 | XMFLOAT3 mPosition; // Camera's coordinates
131 | XMFLOAT3 mTarget; // View target's coordinates
132 | XMFLOAT3 mUp; // Camera's up vector end coordinates
133 | XMFLOAT3 mLook;
134 | XMFLOAT3 mForward;
135 | XMFLOAT3 mRight;
136 | /*** Projection parameters ***/
137 | float mAngle; // Angle of view frustum
138 | float mClientWidth; // Window's width
139 | float mClientHeight; // Window's height
140 | float mNearest; // Nearest view frustum plane
141 | float mFarthest; // Farthest view frustum plane
142 |
143 |
144 |
145 |
146 | XMFLOAT4X4 mView; // View matrix
147 | XMFLOAT4X4 mProj; // Projection matrix
148 | XMFLOAT4X4 mOrtho; // Ortho matrix for drawing without tranformation
149 | };
150 |
151 |
--------------------------------------------------------------------------------
/DirectxHelper.h:
--------------------------------------------------------------------------------
1 |
2 | #include "stdafx.h"
3 | #include
4 | //To do:
5 | //Create a helper class to convert upload to default resources
6 | #pragma once
7 |
8 | using namespace Microsoft::WRL;
9 |
10 | class D3dDeviceManager
11 | {
12 |
13 | public:
14 | D3dDeviceManager();
15 | ~D3dDeviceManager();
16 | void CreateDeviceResources();
17 | void WaitForGPU();
18 | void CreateWindowSizeDependentResources();
19 | void SetWindows(HWND hwnd, UINT width, UINT height);
20 | void ValidateDevice();
21 | void Present();
22 | void MoveToNextFrame();
23 | bool IsDeviceRemoved() const { return m_deviceRemoved; }
24 | // D3D Accessors.
25 | ID3D12Device* GetD3DDevice() const { return m_d3dDevice.Get(); }
26 | IDXGISwapChain* GetSwapChain() const { return m_swapChain.Get(); }
27 | ID3D12Resource* GetRenderTarget() const { return m_renderTargets[m_currentFrame].Get(); }
28 | ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
29 | ID3D12CommandAllocator* GetCommandAllocator() const { return m_commandAllocators[m_currentFrame].Get(); }
30 | D3D12_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
31 | D3D12_CPU_DESCRIPTOR_HANDLE GetRenderTargetView() const
32 | {
33 | D3D12_CPU_DESCRIPTOR_HANDLE handle;
34 | handle.ptr = m_rtvHeap->GetCPUDescriptorHandleForHeapStart().ptr + m_rtvDescriptorSize*m_currentFrame;
35 | return handle;
36 | }
37 | private:
38 | // Cached reference to the Window.
39 | HWND m_hwnd;
40 | // Direct3D objects.
41 | ComPtr m_d3dDevice;
42 | ComPtr m_swapChain;
43 | ComPtr m_commandQueue;
44 | ComPtr m_dxgiFactory;
45 | WCHAR* m_sDeviceName;
46 | static const UINT c_frameCount = 3; // Use triple buffering.
47 | UINT m_currentFrame;
48 | ComPtr m_commandAllocators[c_frameCount];
49 | ComPtr m_renderTargets[c_frameCount];
50 | bool m_deviceRemoved;
51 | ComPtr m_rtvHeap;
52 | UINT m_rtvDescriptorSize;
53 | D3D12_VIEWPORT m_screenViewport;
54 |
55 | // CPU/GPU Synchronization.
56 | ComPtr m_fence;
57 | UINT64 m_fenceValues[c_frameCount];
58 | HANDLE m_fenceEvent;
59 | // Cached device properties.
60 | UINT m_renderTargetWidth;
61 | UINT m_renderTargetHeight;
62 | UINT m_outputWidth;
63 | UINT m_outputHeight;
64 |
65 |
66 |
67 |
68 |
69 | };
70 |
71 | extern std::shared_ptr g_d3dObjects;
72 |
73 | inline void ThrowIfFailed(HRESULT hr)
74 | {
75 | if (FAILED(hr))
76 | {
77 | // Set a breakpoint on this line to catch Win32 API errors.
78 | throw _com_error(hr);
79 | }
80 | }
81 |
82 | static void AddResourceBarrier(
83 | ID3D12GraphicsCommandList* command,
84 | ID3D12Resource* pResource,
85 | D3D12_RESOURCE_STATES before,
86 | D3D12_RESOURCE_STATES after
87 | )
88 | {
89 | D3D12_RESOURCE_BARRIER desc;
90 | ZeroMemory(&desc, sizeof(desc));
91 | desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
92 | desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
93 | desc.Transition.pResource = pResource;
94 | desc.Transition.StateBefore = before;
95 | desc.Transition.StateAfter = after;
96 | command->ResourceBarrier(1, &desc);
97 | };
98 |
99 | struct ShaderObject {
100 | void* binaryPtr;
101 | size_t size;
102 | std::string name;
103 | };
104 |
105 | struct DescriptorHandleObject
106 | {
107 | D3D12_CPU_DESCRIPTOR_HANDLE CPUHeapStart;
108 | D3D12_GPU_DESCRIPTOR_HANDLE GPUHeapStart;
109 | };
110 | static void SetVSShader(ShaderObject obj, D3D12_GRAPHICS_PIPELINE_STATE_DESC descPipelineState)
111 | {
112 | descPipelineState.VS.pShaderBytecode = obj.binaryPtr;
113 | descPipelineState.VS.BytecodeLength = obj.size;
114 | }
115 | static void SetFSShader(ShaderObject obj, D3D12_GRAPHICS_PIPELINE_STATE_DESC descPipelineState)
116 | {
117 | descPipelineState.PS.pShaderBytecode = obj.binaryPtr;
118 | descPipelineState.PS.BytecodeLength = obj.size;
119 | }
120 | class CDescriptorHeapWrapper
121 | {
122 | public:
123 | CDescriptorHeapWrapper() { memset(this, 0, sizeof(*this)); }
124 |
125 | HRESULT Create(
126 | ID3D12Device* pDevice,
127 | D3D12_DESCRIPTOR_HEAP_TYPE Type,
128 | UINT NumDescriptors,
129 | bool bShaderVisible = false)
130 | {
131 | Desc.Type = Type;
132 | Desc.NumDescriptors = NumDescriptors;
133 | Desc.Flags = (bShaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : (D3D12_DESCRIPTOR_HEAP_FLAGS)0);
134 |
135 | HRESULT hr = pDevice->CreateDescriptorHeap(&Desc,
136 | __uuidof(ID3D12DescriptorHeap),
137 | (void**)&pDH);
138 | if (FAILED(hr)) return hr;
139 |
140 | hCPUHeapStart = pDH->GetCPUDescriptorHandleForHeapStart();
141 | if (bShaderVisible)
142 | {
143 | hGPUHeapStart = pDH->GetGPUDescriptorHandleForHeapStart();
144 | }
145 | else
146 | {
147 | hGPUHeapStart.ptr = 0;
148 | }
149 | HandleIncrementSize = pDevice->GetDescriptorHandleIncrementSize(Desc.Type);
150 | return hr;
151 | }
152 | operator ID3D12DescriptorHeap*() { return pDH.Get(); }
153 |
154 | SIZE_T MakeOffsetted(SIZE_T ptr, UINT index)
155 | {
156 | SIZE_T offsetted;
157 | offsetted = ptr + static_cast(index * HandleIncrementSize);
158 | return offsetted;
159 | }
160 |
161 | UINT64 MakeOffsetted(UINT64 ptr, UINT index)
162 | {
163 | UINT64 offsetted;
164 | offsetted = ptr + static_cast(index * HandleIncrementSize);
165 | return offsetted;
166 | }
167 |
168 | D3D12_CPU_DESCRIPTOR_HANDLE hCPU(UINT index)
169 | {
170 | D3D12_CPU_DESCRIPTOR_HANDLE handle;
171 | handle.ptr = MakeOffsetted(hCPUHeapStart.ptr, index);
172 | return handle;
173 | }
174 | D3D12_GPU_DESCRIPTOR_HANDLE hGPU(UINT index)
175 | {
176 | assert(Desc.Flags&D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
177 | D3D12_GPU_DESCRIPTOR_HANDLE handle;
178 | handle.ptr = MakeOffsetted(hGPUHeapStart.ptr, index);
179 | return handle;
180 | }
181 | D3D12_DESCRIPTOR_HEAP_DESC Desc;
182 | Microsoft::WRL::ComPtr pDH;
183 | D3D12_CPU_DESCRIPTOR_HANDLE hCPUHeapStart;
184 | D3D12_GPU_DESCRIPTOR_HANDLE hGPUHeapStart;
185 | UINT HandleIncrementSize;
186 | };
187 |
188 | const UINT PIX_EVENT_UNICODE_VERSION = 0;
189 |
190 | inline void PIXBeginEvent(ID3D12CommandQueue* pCommandQueue, UINT64 /*metadata*/, PCWSTR pFormat)
191 | {
192 | pCommandQueue->BeginEvent(PIX_EVENT_UNICODE_VERSION, pFormat, (wcslen(pFormat) + 1) * sizeof(pFormat[0]));
193 | }
194 |
195 | inline void PIXBeginEvent(ID3D12GraphicsCommandList* pCommandList, UINT64 /*metadata*/, PCWSTR pFormat)
196 | {
197 |
198 | pCommandList->BeginEvent(PIX_EVENT_UNICODE_VERSION, pFormat, (wcslen(pFormat) + 1) * sizeof(pFormat[0]));
199 | }
200 | inline void PIXEndEvent(ID3D12CommandQueue* pCommandQueue)
201 | {
202 | pCommandQueue->EndEvent();
203 | }
204 | inline void PIXEndEvent(ID3D12GraphicsCommandList* pCommandList)
205 | {
206 | pCommandList->EndEvent();
207 | }
208 |
--------------------------------------------------------------------------------
/clusteredShadingD3D12.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {F840468D-2DBB-4F40-B215-4232A0935A79}
15 | SimpleDeferredShadingD3D12
16 | SAK
17 | SAK
18 | SAK
19 | SAK
20 | SimpleDeferredShadingD3D12
21 | 10.0.10240.0
22 |
23 |
24 |
25 | Application
26 | true
27 | v140
28 | MultiByte
29 |
30 |
31 | Application
32 | false
33 | v140
34 | true
35 | MultiByte
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Level3
51 | Disabled
52 | true
53 | NotUsing
54 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
55 | %(AdditionalIncludeDirectories)
56 | MultiThreadedDebugDLL
57 |
58 |
59 | true
60 | d3d12.lib;DXGI.lib;wininet.lib;%(AdditionalDependencies)
61 | Windows
62 | C:\Program Files\Autodesk\FBX\FBX SDK\2016.0\lib\vs2013\x86\debug;%(AdditionalLibraryDirectories)
63 | LIBMCT;%(IgnoreSpecificDefaultLibraries)
64 |
65 |
66 |
67 |
68 | Level3
69 | MaxSpeed
70 | true
71 | true
72 | true
73 | Create
74 |
75 |
76 | true
77 | true
78 | true
79 | d3d12.lib;DXGI.lib;wininet.lib;%(AdditionalDependencies)
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 | Pixel
110 | Pixel
111 | Shaders\%(Filename).cso
112 | 5.0
113 | 5.0
114 | Shaders\%(Filename).cso
115 |
116 |
117 | Vertex
118 | Vertex
119 | Shaders\%(Filename).cso
120 | 5.0
121 | 5.0
122 | Shaders\%(Filename).cso
123 |
124 |
125 | Pixel
126 | Pixel
127 | Shaders\%(Filename).cso
128 | 5.0
129 | 5.0
130 | Shaders\%(Filename).cso
131 |
132 |
133 | Vertex
134 | Vertex
135 | Shaders\%(Filename).cso
136 | 5.0
137 | Shaders\%(Filename).cso
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/CameraManager.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 |
3 | #include "CameraManager.h"
4 | GCamera::GCamera(void)
5 | {
6 | mPosition = XMFLOAT3(0.0f, 0.0f, -1.0f);
7 | mTarget = XMFLOAT3(0.0f, 0.0f, 0.0f);
8 | mUp = GMathVF(GMathFV(mPosition) + GMathFV(XMFLOAT3(0, 1, 0)));
9 | //this->lookatViewMatrix();
10 |
11 | mAngle = 0.5f;
12 | mClientWidth = 0.0f;
13 | mClientHeight = 0.0f;
14 | mNearest = 0.0f;
15 | mFarthest = 1000.0f;
16 | mSpeed = 0.5f;
17 |
18 | mRight = XMFLOAT3(1, 0, 0);
19 | mUp = XMFLOAT3(0, 1, 0);
20 | mLook = XMFLOAT3(0, 0, 1);
21 |
22 | XMStoreFloat4x4(&mView, XMMatrixIdentity());
23 | XMStoreFloat4x4(&mProj, XMMatrixIdentity());
24 | XMStoreFloat4x4(&mOrtho, XMMatrixIdentity());
25 |
26 | buildViewMatrix();
27 | }
28 |
29 | GCamera::GCamera(const GCamera& camera)
30 | {
31 | *this = camera;
32 | }
33 |
34 | GCamera& GCamera::operator=(const GCamera& camera)
35 | {
36 | mPosition = camera.mPosition;
37 | mTarget = camera.mTarget;
38 | mUp = camera.mUp;
39 |
40 | mAngle = camera.mAngle;
41 | mClientWidth = camera.mClientWidth;
42 | mClientHeight = camera.mClientHeight;
43 | mNearest = camera.mNearest;
44 | mFarthest = camera.mFarthest;
45 |
46 | mView = camera.mView;
47 | mProj = camera.mProj;
48 | mOrtho = camera.mOrtho;
49 | return *this;
50 | }
51 |
52 | void GCamera::lookatViewMatrix()
53 | {
54 | XMStoreFloat4x4(&mView, XMMatrixLookAtLH(XMLoadFloat3(&mPosition), XMLoadFloat3(&mTarget),
55 | XMLoadFloat3(&this->Up())));
56 | }
57 |
58 | void GCamera::buildViewMatrix()
59 | {
60 | XMVECTOR vecLookW = XMVector3Normalize(GMathFV(mLook));
61 | XMVECTOR vecRightW = XMVector3Normalize(XMVector3Cross(GMathFV(mUp), vecLookW));
62 | XMVECTOR vecUpW = XMVector3Normalize(XMVector3Cross(vecLookW, vecRightW));
63 | XMVECTOR vecPosW = GMathFV(mPosition);
64 |
65 |
66 |
67 |
68 |
69 | float x = -GMathVF(XMVector3Dot(vecPosW, vecRightW)).x;
70 | float y = -GMathVF(XMVector3Dot(vecPosW, vecUpW)).x;
71 | float z = -GMathVF(XMVector3Dot(vecPosW, vecLookW)).x;
72 | mRight = GMathVF(vecRightW);
73 | mUp = GMathVF(vecUpW);
74 | mLook = GMathVF(vecLookW);
75 |
76 | mView(0, 0) = mRight.x;
77 | mView(1, 0) = mRight.y;
78 | mView(2, 0) = mRight.z;
79 | mView(3, 0) = x;
80 |
81 | mView(0, 1) = mUp.x;
82 | mView(1, 1) = mUp.y;
83 | mView(2, 1) = mUp.z;
84 | mView(3, 1) = y;
85 |
86 | mView(0, 2) = mLook.x;
87 | mView(1, 2) = mLook.y;
88 | mView(2, 2) = mLook.z;
89 | mView(3, 2) = z;
90 |
91 | mView(0, 3) = 0.0f;
92 | mView(1, 3) = 0.0f;
93 | mView(2, 3) = 0.0f;
94 | mView(3, 3) = 1.0f;
95 |
96 |
97 |
98 | }
99 |
100 | void GCamera::InitProjMatrix(const float angle, const float client_width, const float client_height,
101 | const float near_plane, const float far_plane)
102 | {
103 | mAngle = angle;
104 | mClientWidth = client_width;
105 | mClientHeight = client_height;
106 | mNearest = near_plane;
107 | mFarthest = far_plane;
108 | float ration = client_width / client_height;
109 |
110 | XMStoreFloat4x4(&mProj, XMMatrixPerspectiveFovLH(angle,ration ,
111 | near_plane, far_plane));
112 |
113 |
114 | }
115 |
116 | void GCamera::Move(XMFLOAT3 direction)
117 | {
118 | mPosition = GMathVF(XMVector3Transform(GMathFV(mPosition),
119 | XMMatrixTranslation(direction.x, direction.y, direction.z)));
120 | mTarget = GMathVF(XMVector3Transform(GMathFV(mTarget),
121 | XMMatrixTranslation(direction.x, direction.y, direction.z)));
122 | mUp = GMathVF(XMVector3Transform(GMathFV(mUp),
123 | XMMatrixTranslation(direction.x, direction.y, direction.z)));
124 |
125 | this->lookatViewMatrix();
126 | }
127 |
128 | void GCamera::Rotate(XMFLOAT3 axis, float degrees)
129 | {
130 | if (XMVector3Equal(GMathFV(axis), XMVectorZero()) ||
131 | degrees == 0.0f)
132 | return;
133 |
134 | // rotate vectors
135 | XMFLOAT3 look_at_target = GMathVF(GMathFV(mTarget) - GMathFV(mPosition));
136 | XMFLOAT3 look_at_up = GMathVF(GMathFV(mUp) - GMathFV(mPosition));
137 | look_at_target = GMathVF(XMVector3Transform(GMathFV(look_at_target),
138 | XMMatrixRotationAxis(GMathFV(axis), XMConvertToRadians(degrees))));
139 | look_at_up = GMathVF(XMVector3Transform(GMathFV(look_at_up),
140 | XMMatrixRotationAxis(GMathFV(axis), XMConvertToRadians(degrees))));
141 |
142 | // restore vectors's end points mTarget and mUp from new rotated vectors
143 | mTarget = GMathVF(GMathFV(mPosition) + GMathFV(look_at_target));
144 | mUp = GMathVF(GMathFV(mPosition) + GMathFV(look_at_up));
145 |
146 | this->lookatViewMatrix();
147 | }
148 |
149 | void GCamera::Target(XMFLOAT3 new_target)
150 | {
151 | if (XMVector3Equal(GMathFV(new_target), GMathFV(mPosition)) ||
152 | XMVector3Equal(GMathFV(new_target), GMathFV(mTarget)))
153 | return;
154 |
155 | XMFLOAT3 old_look_at_target = GMathVF(GMathFV(mTarget) - GMathFV(mPosition));
156 | XMFLOAT3 new_look_at_target = GMathVF(GMathFV(new_target) - GMathFV(mPosition));
157 | float angle = XMConvertToDegrees(XMVectorGetX(
158 | XMVector3AngleBetweenNormals(XMVector3Normalize(GMathFV(old_look_at_target)),
159 | XMVector3Normalize(GMathFV(new_look_at_target)))));
160 | if (angle != 0.0f && angle != 360.0f && angle != 180.0f)
161 | {
162 | XMVECTOR axis = XMVector3Cross(GMathFV(old_look_at_target), GMathFV(new_look_at_target));
163 | Rotate(GMathVF(axis), angle);
164 | }
165 | mTarget = new_target;
166 | this->lookatViewMatrix();
167 | }
168 |
169 | // Set camera position
170 | void GCamera::Position(XMFLOAT3& new_position)
171 | {
172 | XMFLOAT3 move_vector = GMathVF(GMathFV(new_position) - GMathFV(mPosition));
173 | XMFLOAT3 target = mTarget;
174 | this->Move(move_vector);
175 | this->Target(target);
176 | }
177 |
178 | void GCamera::Angle(float angle)
179 | {
180 | mAngle = angle;
181 | InitProjMatrix(mAngle, mClientWidth, mClientHeight, mNearest, mFarthest);
182 | }
183 |
184 | void GCamera::NearestPlane(float nearest)
185 | {
186 | mNearest = nearest;
187 | OnResize(mClientWidth, mClientHeight);
188 | }
189 |
190 | void GCamera::FarthestPlane(float farthest)
191 | {
192 | mFarthest = farthest;
193 | OnResize(mClientWidth, mClientHeight);
194 | }
195 |
196 | void GCamera::KeyDown(UINT key)
197 | {
198 |
199 | if (key == 0x57)
200 | m_forward = true;
201 | if (key == 0x53)
202 | m_back = true;
203 | if (key == 0x44)
204 | m_right = true;
205 | if (key == 0x41)
206 | m_left = true;
207 |
208 |
209 | }
210 |
211 | void GCamera::KeyUp(UINT key)
212 | {
213 | if (key == 0x57)
214 | m_forward = false;
215 | if (key == 0x53)
216 | m_back = false;
217 | if (key == 0x44)
218 | m_right = false;
219 | if (key == 0x41)
220 | m_left = false;
221 | }
222 |
223 | void GCamera::Update()
224 | {
225 | XMVECTOR m_moveCommand= GMathFV(XMFLOAT3(0,0,0));
226 | XMVECTOR forward= GMathFV(mLook);
227 | XMVECTOR right= GMathFV(mRight);
228 | if (m_forward)
229 | m_moveCommand += forward;
230 | if (m_back)
231 | m_moveCommand -= forward;
232 |
233 | if (m_left)
234 | m_moveCommand -= right ;
235 | if (m_right)
236 | m_moveCommand += right ;
237 |
238 | XMMATRIX R = XMMatrixRotationAxis(GMathFV(mRight), m_pitch);
239 | XMVECTOR vecLookW = XMVector3TransformCoord(GMathFV(mLook), R);
240 | XMVECTOR vecUpW = XMVector3TransformCoord(GMathFV(mUp), R);
241 | R = XMMatrixRotationY(m_yaw);
242 | XMVECTOR vecRightW = XMVector3TransformCoord(GMathFV(mRight), R);
243 | vecUpW = XMVector3TransformCoord(vecUpW, R);
244 | vecLookW = XMVector3TransformCoord(vecLookW, R);
245 | mRight = GMathVF(vecRightW);
246 | mUp = GMathVF(vecUpW);
247 | mLook = GMathVF(vecLookW);
248 |
249 |
250 | // make sure that 45 degree cases are not faster
251 |
252 |
253 | buildViewMatrix();
254 | mPosition = GMathVF(m_moveCommand*mSpeed + GMathFV(mPosition));
255 |
256 | m_pitch = 0;
257 | m_yaw = 0;
258 | m_forward = false;
259 | m_back = false;
260 | m_right = false;
261 | m_left = false;
262 | }
263 |
264 | void GCamera::InputPress(float x,float y)
265 | {
266 | m_lookLastPoint = XMFLOAT2(x,y); // save point for later move
267 | //m_lookPointerID = pointerID; // store the id of pointer using this control
268 | m_lookLastDelta.x = m_lookLastDelta.y = 0; // these are for smoothing
269 | m_lookInUse = !m_lookInUse;
270 | }
271 |
272 | void GCamera::InputMove( float x, float y)
273 | {
274 | POINT p;
275 | if (GetCursorPos(&p))
276 | {
277 | x = p.x;
278 | y = p.y;
279 |
280 | XMFLOAT2 pointerDelta;
281 |
282 | pointerDelta = GMathVF2(GMathFV(XMFLOAT2(x, y)) - GMathFV(m_lookLastPoint)); // how far did pointer move
283 | if (pointerDelta.x < 100 && pointerDelta.y<100)
284 | {
285 |
286 |
287 |
288 | XMFLOAT2 rotationDelta;
289 | rotationDelta = GMathVF2(GMathFV(pointerDelta) * ROTATION_GAIN); // scale for control sensitivity
290 |
291 | // update our orientation based on the command
292 | m_pitch = rotationDelta.y; // mouse y increases down, but pitch increases up
293 | m_yaw = rotationDelta.x; // yaw defined as CCW around y-axis
294 | }
295 | m_lookLastPoint = XMFLOAT2(x, y); // save for next time through
296 |
297 | // Limit pitch to straight up or straight down
298 | //m_pitch = (float)XMMax(-XM_PI / 2.0f, m_pitch);
299 | //m_pitch = (float)XMMin(+XM_PI / 2.0f, m_pitch);
300 |
301 | }
302 |
303 |
304 | }
305 |
306 | void GCamera::InputRelease()
307 | {
308 | m_lookInUse = false;
309 | m_lookPointerID = 0;
310 | }
311 |
312 | void GCamera::InitOrthoMatrix(const float clientWidth, const float clientHeight,
313 | const float nearZ, const float fartherZ)
314 | {
315 | XMStoreFloat4x4(&mOrtho, XMMatrixOrthographicLH(clientWidth, clientHeight, nearZ, fartherZ));
316 | }
317 |
318 | void GCamera::OnResize(uint32_t new_width, uint32_t new_height)
319 | {
320 | if (new_width != 0 && new_width != 0)
321 | {
322 | mClientWidth = new_width;
323 | mClientHeight = new_height;
324 | InitProjMatrix(mAngle, static_cast(new_width), static_cast(new_height), mNearest, mFarthest);
325 | InitOrthoMatrix(static_cast(new_width), static_cast(new_height), 0.0f, mFarthest);
326 | }
327 | }
328 |
329 |
--------------------------------------------------------------------------------
/DirectxHelper.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "DirectxHelper.h"
3 |
4 | std::shared_ptr g_d3dObjects;
5 |
6 | D3dDeviceManager::D3dDeviceManager() :
7 | m_currentFrame(0),
8 | m_screenViewport(),
9 | m_rtvDescriptorSize(0),
10 | m_fenceEvent(0),
11 | m_deviceRemoved(false)
12 | {
13 | ZeroMemory(m_fenceValues, sizeof(m_fenceValues));
14 | CreateDeviceResources();
15 | }
16 |
17 | D3dDeviceManager::~D3dDeviceManager()
18 | {
19 | }
20 | void D3dDeviceManager::CreateDeviceResources()
21 | {
22 |
23 |
24 | ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(m_dxgiFactory.GetAddressOf())));
25 |
26 | #if defined(_DEBUG)
27 | // If the project is in a debug build, enable debugging via SDK Layers.
28 | {
29 | ComPtr debugController;
30 | ThrowIfFailed(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)));
31 | debugController->EnableDebugLayer();
32 | }
33 | #endif
34 |
35 | IDXGIAdapter* adapter;
36 | DXGI_ADAPTER_DESC desc;
37 | m_dxgiFactory->EnumAdapters(0,&adapter);
38 | adapter->GetDesc(&desc);
39 |
40 |
41 |
42 | // Create the Direct3D 12 API device object
43 | HRESULT hr = D3D12CreateDevice(
44 | adapter, // Specify nullptr to use the default adapter.
45 | D3D_FEATURE_LEVEL_12_0, // Feature levels this app can support.
46 | IID_PPV_ARGS(&m_d3dDevice) // Returns the Direct3D device created.
47 | );
48 |
49 | if (FAILED(hr))
50 | {
51 | // If the initialization fails, fall back to the WARP device.
52 | // For more information on WARP, see:
53 | // http://go.microsoft.com/fwlink/?LinkId=286690
54 |
55 | ComPtr warpAdapter;
56 | m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
57 |
58 | ThrowIfFailed(
59 | D3D12CreateDevice(
60 | warpAdapter.Get(),
61 | D3D_FEATURE_LEVEL_12_0,
62 | IID_PPV_ARGS(&m_d3dDevice)
63 | )
64 | );
65 | }
66 |
67 | // Create the command queue.
68 | D3D12_COMMAND_QUEUE_DESC queueDesc = {};
69 | queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
70 | queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
71 |
72 | ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
73 |
74 | for (UINT n = 0; n < c_frameCount; n++)
75 | {
76 | ThrowIfFailed(m_d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
77 | }
78 |
79 | // Create synchronization objects.
80 | ThrowIfFailed(m_d3dDevice->CreateFence(m_fenceValues[m_currentFrame], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
81 | m_fenceValues[m_currentFrame]++;
82 |
83 | m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
84 |
85 |
86 | }
87 |
88 |
89 |
90 | void D3dDeviceManager::CreateWindowSizeDependentResources()
91 | {
92 | // Wait until all previous GPU work is complete.
93 | WaitForGPU();
94 |
95 | // Clear the previous window size specific context.
96 | for (UINT n = 0; n < c_frameCount; n++)
97 | {
98 | m_renderTargets[n].Reset();
99 | }
100 | m_rtvHeap.Reset();
101 |
102 |
103 |
104 | // Prevent zero size DirectX content from being created.
105 | m_renderTargetWidth=m_outputWidth ;
106 | m_renderTargetHeight=m_outputHeight;
107 |
108 |
109 | if (m_swapChain != nullptr)
110 | {
111 | // If the swap chain already exists, resize it.
112 | HRESULT hr = m_swapChain->ResizeBuffers(
113 | c_frameCount,
114 | m_renderTargetWidth,
115 | m_renderTargetHeight,
116 | DXGI_FORMAT_R8G8B8A8_UNORM,
117 | 0
118 | );
119 |
120 | if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
121 | {
122 | // If the device was removed for any reason, a new device and swap chain will need to be created.
123 | m_deviceRemoved = true;
124 |
125 | // Do not continue execution of this method. DeviceResources will be destroyed and re-created.
126 | return;
127 | }
128 | else
129 | {
130 | ThrowIfFailed(hr);
131 | }
132 | }
133 | else
134 | {
135 | // Otherwise, create a new one using the same adapter as the existing Direct3D device.
136 | DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
137 |
138 | swapChainDesc.Width = m_renderTargetWidth; // Match the size of the window.
139 | swapChainDesc.Height = m_renderTargetHeight;
140 | swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // This is the most common swap chain format.
141 | swapChainDesc.Stereo = false;
142 | swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
143 | swapChainDesc.SampleDesc.Quality = 0;
144 | swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
145 | swapChainDesc.BufferCount = c_frameCount; // Use double-buffering to minimize latency.
146 | swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
147 | swapChainDesc.Flags = 0;
148 | swapChainDesc.Scaling = DXGI_SCALING_NONE;
149 | swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
150 |
151 | ThrowIfFailed(
152 | m_dxgiFactory->CreateSwapChainForHwnd(
153 | m_commandQueue.Get(),
154 | m_hwnd,
155 | &swapChainDesc,
156 | nullptr,
157 | nullptr,
158 | &m_swapChain
159 | )
160 | );
161 | }
162 |
163 |
164 |
165 |
166 | // Create a render target view of the swap chain back buffer.
167 | {
168 | D3D12_DESCRIPTOR_HEAP_DESC desc = {};
169 | desc.NumDescriptors = c_frameCount;
170 | desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
171 | desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
172 | ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_rtvHeap)));
173 | m_rtvHeap->SetName(L"Render Target View Descriptor Heap");
174 |
175 | // All pending GPU work was already finished. Update the tracked fence values
176 | // to the last value signaled.
177 | for (UINT n = 0; n < c_frameCount; n++)
178 | {
179 | m_fenceValues[n] = m_fenceValues[m_currentFrame];
180 | }
181 |
182 | m_currentFrame = 0;
183 | D3D12_CPU_DESCRIPTOR_HANDLE hCPUHeapHandle=m_rtvHeap->GetCPUDescriptorHandleForHeapStart();
184 | m_rtvDescriptorSize=m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
185 |
186 | for (UINT n = 0; n < c_frameCount; n++)
187 | {
188 | D3D12_CPU_DESCRIPTOR_HANDLE handle;
189 | handle.ptr = hCPUHeapHandle.ptr + m_rtvDescriptorSize*n;
190 | ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
191 | m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr,handle);
192 |
193 |
194 | WCHAR name[25];
195 | swprintf_s(name, L"Render Target %d", n);
196 | m_renderTargets[n]->SetName(name);
197 | }
198 | }
199 |
200 | // Set the 3D rendering viewport to target the entire window.
201 | m_screenViewport = { 0.0f, 0.0f,static_cast(m_renderTargetWidth),static_cast(m_renderTargetHeight), 0.0f, 1.0f };
202 | }
203 |
204 | void D3dDeviceManager::SetWindows(HWND hwnd, UINT width, UINT height)
205 | {
206 | m_hwnd = hwnd;
207 | m_outputWidth = width;
208 | m_outputHeight = height;
209 |
210 | //m_dpi = currentDisplayInformation->LogicalDpi;
211 |
212 | CreateWindowSizeDependentResources();
213 | }
214 |
215 | void D3dDeviceManager::
216 | ValidateDevice()
217 | {
218 | // The D3D Device is no longer valid if the default adapter changed since the device
219 | // was created or if the device has been removed.
220 |
221 | // First, get the information for the default adapter from when the device was created.
222 |
223 | ComPtr dxgiDevice;
224 | ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
225 |
226 | ComPtr deviceAdapter;
227 | ThrowIfFailed(dxgiDevice->GetAdapter(&deviceAdapter));
228 |
229 | ComPtr deviceFactory;
230 | ThrowIfFailed(deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)));
231 |
232 | ComPtr previousDefaultAdapter;
233 | ThrowIfFailed(deviceFactory->EnumAdapters1(0, &previousDefaultAdapter));
234 |
235 | DXGI_ADAPTER_DESC previousDesc;
236 | ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
237 |
238 | // Next, get the information for the current default adapter.
239 |
240 | ComPtr currentFactory;
241 | ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(¤tFactory)));
242 |
243 | ComPtr currentDefaultAdapter;
244 | ThrowIfFailed(currentFactory->EnumAdapters1(0, ¤tDefaultAdapter));
245 |
246 | DXGI_ADAPTER_DESC currentDesc;
247 | ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc));
248 |
249 | // If the adapter LUIDs don't match, or if the device reports that it has been removed,
250 | // a new D3D device must be created.
251 |
252 | if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart ||
253 | previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart ||
254 | FAILED(m_d3dDevice->GetDeviceRemovedReason()))
255 | {
256 | // Release references to resources related to the old device.
257 | dxgiDevice = nullptr;
258 | deviceAdapter = nullptr;
259 | deviceFactory = nullptr;
260 | previousDefaultAdapter = nullptr;
261 |
262 | m_deviceRemoved = true;
263 | }
264 | }
265 |
266 | void D3dDeviceManager::Present()
267 | {
268 | // The first argument instructs DXGI to block until VSync, putting the application
269 | // to sleep until the next VSync. This ensures we don't waste any cycles rendering
270 | // frames that will never be displayed to the screen.
271 | HRESULT hr = m_swapChain->Present(1, 0);
272 |
273 | // If the device was removed either by a disconnection or a driver upgrade, we
274 | // must recreate all device resources.
275 | if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
276 | {
277 | m_deviceRemoved = true;
278 | }
279 | else
280 | {
281 | ThrowIfFailed(hr);
282 |
283 | MoveToNextFrame();
284 | }
285 | }
286 |
287 |
288 | // Wait for pending GPU work to complete.
289 | void D3dDeviceManager::WaitForGPU()
290 | {
291 | // Schedule a Signal command in the queue.
292 | ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), m_fenceValues[m_currentFrame]));
293 |
294 | // Wait until the fence has been crossed.
295 | ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_currentFrame], m_fenceEvent));
296 | WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);
297 |
298 | // Increment the fence value for the current frame.
299 | m_fenceValues[m_currentFrame]++;
300 | }
301 |
302 | // Prepare to render the next frame.
303 | void D3dDeviceManager::MoveToNextFrame()
304 | {
305 | // Schedule a Signal command in the queue.
306 | const UINT64 currentFenceValue = m_fenceValues[m_currentFrame];
307 | ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));
308 |
309 | // Advance the frame index.
310 | m_currentFrame = (m_currentFrame + 1) % c_frameCount;
311 |
312 | // Check to see if the next frame is ready to start.
313 | if (m_fence->GetCompletedValue() < m_fenceValues[m_currentFrame])
314 | {
315 | ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_currentFrame], m_fenceEvent));
316 | WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);
317 | }
318 |
319 | // Set the fence value for the next frame.
320 | m_fenceValues[m_currentFrame] = currentFenceValue + 1;
321 | }
322 |
--------------------------------------------------------------------------------
/DeviceResources.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "DeviceResources.h"
3 |
4 | using namespace DirectX;
5 | using namespace Microsoft::WRL;
6 | using namespace Windows::Foundation;
7 |
8 |
9 |
10 |
11 | // Constructor for DeviceResources.
12 | DX::DeviceResources::DeviceResources() :
13 | m_currentFrame(0),
14 | m_screenViewport(),
15 | m_rtvDescriptorSize(0),
16 | m_fenceEvent(0),
17 | m_dpi(-1.0f),
18 | m_deviceRemoved(false)
19 | {
20 | ZeroMemory(m_fenceValues, sizeof(m_fenceValues));
21 | CreateDeviceIndependentResources();
22 | CreateDeviceResources();
23 | }
24 |
25 | // Configures resources that don't depend on the Direct3D device.
26 | void DX::DeviceResources::CreateDeviceIndependentResources()
27 | {
28 | }
29 |
30 | // Configures the Direct3D device, and stores handles to it and the device context.
31 | void DX::DeviceResources::CreateDeviceResources()
32 | {
33 | DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&m_dxgiFactory)));
34 |
35 | #if defined(_DEBUG)
36 | // If the project is in a debug build, enable debugging via SDK Layers.
37 | {
38 | ComPtr debugController;
39 | ThrowIfFailed(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)));
40 | debugController->EnableDebugLayer();
41 | }
42 | #endif
43 |
44 | // Create the Direct3D 12 API device object
45 | HRESULT hr = D3D12CreateDevice(
46 | nullptr, // Specify nullptr to use the default adapter.
47 | D3D_FEATURE_LEVEL_12_0, // Feature levels this app can support.
48 | IID_PPV_ARGS(&m_d3dDevice) // Returns the Direct3D device created.
49 | );
50 |
51 | if (FAILED(hr))
52 | {
53 | // If the initialization fails, fall back to the WARP device.
54 | // For more information on WARP, see:
55 | // http://go.microsoft.com/fwlink/?LinkId=286690
56 |
57 | ComPtr warpAdapter;
58 | m_dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
59 |
60 | DX::ThrowIfFailed(
61 | D3D12CreateDevice(
62 | warpAdapter.Get(),
63 | D3D_FEATURE_LEVEL_12_0,
64 | IID_PPV_ARGS(&m_d3dDevice)
65 | )
66 | );
67 | }
68 |
69 | // Create the command queue.
70 | D3D12_COMMAND_QUEUE_DESC queueDesc = {};
71 | queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
72 | queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
73 |
74 | DX::ThrowIfFailed(m_d3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
75 |
76 | for (UINT n = 0; n < c_frameCount; n++)
77 | {
78 | DX::ThrowIfFailed(m_d3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
79 | }
80 |
81 | // Create synchronization objects.
82 | DX::ThrowIfFailed(m_d3dDevice->CreateFence(m_fenceValues[m_currentFrame], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
83 | m_fenceValues[m_currentFrame]++;
84 |
85 | m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
86 | }
87 |
88 | // These resources need to be recreated every time the window size is changed.
89 | void DX::DeviceResources::CreateWindowSizeDependentResources()
90 | {
91 | // Wait until all previous GPU work is complete.
92 | WaitForGpu();
93 |
94 | // Clear the previous window size specific context.
95 | for (UINT n = 0; n < c_frameCount; n++)
96 | {
97 | m_renderTargets[n].Reset();
98 | }
99 | m_rtvHeap.Reset();
100 |
101 | // Calculate the necessary render target size in pixels.
102 | m_outputWidth = m_logicalWidth;
103 | m_outputHeight = m_logicalHeight;
104 |
105 | // Prevent zero size DirectX content from being created.
106 | m_outputWidth = max(m_outputWidth, 1);
107 | m_outputHeight = max(m_outputHeight, 1);
108 |
109 |
110 | if (m_swapChain != nullptr)
111 | {
112 | // If the swap chain already exists, resize it.
113 | HRESULT hr = m_swapChain->ResizeBuffers(
114 | c_frameCount,
115 | m_renderTargetWidth,
116 | m_renderTargetHeight,
117 | DXGI_FORMAT_B8G8R8A8_UNORM,
118 | 0
119 | );
120 |
121 | if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
122 | {
123 | // If the device was removed for any reason, a new device and swap chain will need to be created.
124 | m_deviceRemoved = true;
125 |
126 | // Do not continue execution of this method. DeviceResources will be destroyed and re-created.
127 | return;
128 | }
129 | else
130 | {
131 | DX::ThrowIfFailed(hr);
132 | }
133 | }
134 | else
135 | {
136 | // Otherwise, create a new one using the same adapter as the existing Direct3D device.
137 | DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
138 |
139 | swapChainDesc.Width = m_renderTargetWidth; // Match the size of the window.
140 | swapChainDesc.Height = m_renderTargetHeight;
141 | swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
142 | swapChainDesc.Stereo = false;
143 | swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
144 | swapChainDesc.SampleDesc.Quality = 0;
145 | swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
146 | swapChainDesc.BufferCount = c_frameCount; // Use double-buffering to minimize latency.
147 | swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
148 | swapChainDesc.Flags = 0;
149 | swapChainDesc.Scaling = DXGI_SCALING_NONE;
150 | swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
151 |
152 | DX::ThrowIfFailed(
153 | m_dxgiFactory->CreateSwapChainForHwnd(
154 | m_commandQueue.Get(),
155 | m_hwnd,
156 | &swapChainDesc,
157 | nullptr,
158 | nullptr,
159 | &m_swapChain
160 | )
161 | );
162 | }
163 |
164 |
165 |
166 |
167 | // Create a render target view of the swap chain back buffer.
168 | {
169 | D3D12_DESCRIPTOR_HEAP_DESC desc = {};
170 | desc.NumDescriptors = c_frameCount;
171 | desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
172 | desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
173 | ThrowIfFailed(m_d3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_rtvHeap)));
174 | m_rtvHeap->SetName(L"Render Target View Descriptor Heap");
175 |
176 | // All pending GPU work was already finished. Update the tracked fence values
177 | // to the last value signaled.
178 | for (UINT n = 0; n < c_frameCount; n++)
179 | {
180 | m_fenceValues[n] = m_fenceValues[m_currentFrame];
181 | }
182 |
183 | m_currentFrame = 0;
184 | CD3DX12_CPU_DESCRIPTOR_HANDLE rtvDescriptor(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
185 | m_rtvDescriptorSize = m_d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
186 | for (UINT n = 0; n < c_frameCount; n++)
187 | {
188 | DX::ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
189 | m_d3dDevice->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvDescriptor);
190 | rtvDescriptor.Offset(m_rtvDescriptorSize);
191 |
192 | WCHAR name[25];
193 | swprintf_s(name, L"Render Target %d", n);
194 | m_renderTargets[n]->SetName(name);
195 | }
196 | }
197 |
198 | // Set the 3D rendering viewport to target the entire window.
199 | m_screenViewport = { 0.0f, 0.0f,static_cast(m_renderTargetWidth),static_cast(m_renderTargetHeight), 0.0f, 1.0f };
200 | }
201 |
202 | // This method is called when the CoreWindow is created (or re-created).
203 | void DX::DeviceResources::SetWindow(HWND hwnd, UINT width, UINT height)
204 | {
205 |
206 | m_hwnd= hwnd;
207 | m_logicalWidth = width;
208 | m_logicalHeight = height;
209 |
210 | //m_dpi = currentDisplayInformation->LogicalDpi;
211 |
212 | CreateWindowSizeDependentResources();
213 | }
214 |
215 | // This method is called in the event handler for the SizeChanged event.
216 | void DX::DeviceResources::SetLogicalSize(UINT width, UINT height)
217 | {
218 | if (m_logicalWidth != width)
219 | {
220 | if (m_logicalHeight != height)
221 | {
222 | m_logicalWidth = width;
223 | m_logicalHeight = height;
224 | CreateWindowSizeDependentResources();
225 | }
226 | }
227 | }
228 |
229 |
230 |
231 | // This method is called in the event handler for the DisplayContentsInvalidated event.
232 | void DX::DeviceResources::ValidateDevice()
233 | {
234 | // The D3D Device is no longer valid if the default adapter changed since the device
235 | // was created or if the device has been removed.
236 |
237 | // First, get the information for the default adapter from when the device was created.
238 |
239 | ComPtr dxgiDevice;
240 | DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
241 |
242 | ComPtr deviceAdapter;
243 | DX::ThrowIfFailed(dxgiDevice->GetAdapter(&deviceAdapter));
244 |
245 | ComPtr deviceFactory;
246 | DX::ThrowIfFailed(deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)));
247 |
248 | ComPtr previousDefaultAdapter;
249 | DX::ThrowIfFailed(deviceFactory->EnumAdapters1(0, &previousDefaultAdapter));
250 |
251 | DXGI_ADAPTER_DESC previousDesc;
252 | DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
253 |
254 | // Next, get the information for the current default adapter.
255 |
256 | ComPtr currentFactory;
257 | DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(¤tFactory)));
258 |
259 | ComPtr currentDefaultAdapter;
260 | DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, ¤tDefaultAdapter));
261 |
262 | DXGI_ADAPTER_DESC currentDesc;
263 | DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(¤tDesc));
264 |
265 | // If the adapter LUIDs don't match, or if the device reports that it has been removed,
266 | // a new D3D device must be created.
267 |
268 | if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart ||
269 | previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart ||
270 | FAILED(m_d3dDevice->GetDeviceRemovedReason()))
271 | {
272 | // Release references to resources related to the old device.
273 | dxgiDevice = nullptr;
274 | deviceAdapter = nullptr;
275 | deviceFactory = nullptr;
276 | previousDefaultAdapter = nullptr;
277 |
278 | m_deviceRemoved = true;
279 | }
280 | }
281 |
282 | // Present the contents of the swap chain to the screen.
283 | void DX::DeviceResources::Present()
284 | {
285 | // The first argument instructs DXGI to block until VSync, putting the application
286 | // to sleep until the next VSync. This ensures we don't waste any cycles rendering
287 | // frames that will never be displayed to the screen.
288 | HRESULT hr = m_swapChain->Present(1, 0);
289 |
290 | // If the device was removed either by a disconnection or a driver upgrade, we
291 | // must recreate all device resources.
292 | if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
293 | {
294 | m_deviceRemoved = true;
295 | }
296 | else
297 | {
298 | DX::ThrowIfFailed(hr);
299 |
300 | MoveToNextFrame();
301 | }
302 | }
303 |
304 | // Wait for pending GPU work to complete.
305 | void DX::DeviceResources::WaitForGpu()
306 | {
307 | // Schedule a Signal command in the queue.
308 | DX::ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), m_fenceValues[m_currentFrame]));
309 |
310 | // Wait until the fence has been crossed.
311 | DX::ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_currentFrame], m_fenceEvent));
312 | WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);
313 |
314 | // Increment the fence value for the current frame.
315 | m_fenceValues[m_currentFrame]++;
316 | }
317 |
318 | // Prepare to render the next frame.
319 | void DX::DeviceResources::MoveToNextFrame()
320 | {
321 | // Schedule a Signal command in the queue.
322 | const UINT64 currentFenceValue = m_fenceValues[m_currentFrame];
323 | DX::ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));
324 |
325 | // Advance the frame index.
326 | m_currentFrame = (m_currentFrame + 1) % c_frameCount;
327 |
328 | // Check to see if the next frame is ready to start.
329 | if (m_fence->GetCompletedValue() < m_fenceValues[m_currentFrame])
330 | {
331 | DX::ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_currentFrame], m_fenceEvent));
332 | WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);
333 | }
334 |
335 | // Set the fence value for the next frame.
336 | m_fenceValues[m_currentFrame] = currentFenceValue + 1;
337 | }
338 |
339 |
--------------------------------------------------------------------------------
/DeferredRender.cpp:
--------------------------------------------------------------------------------
1 | #include "stdafx.h"
2 | #include "DeferredRender.h"
3 | #include "VertexStructures.h"
4 | void DeferredRender::Init()
5 | {
6 |
7 |
8 | //Create GPU resources
9 | CreateCB();
10 | mQuadRender.Init();
11 | //Create Resource views
12 | CreateViews();
13 |
14 | //Create binding data for PSO
15 | CreateRootSignature();
16 |
17 | //Creatre pipeline state object
18 | CreatePso();
19 | CreateLightPassPSO();
20 |
21 | InitWindowSizeDependentResources();
22 | }
23 |
24 | void DeferredRender::InitWindowSizeDependentResources()
25 | {
26 | CreateRTV();
27 | CreateDSV();
28 |
29 | }
30 |
31 | void DeferredRender::CreatePso()
32 | {
33 |
34 | D3D12_GRAPHICS_PIPELINE_STATE_DESC descPipelineState;
35 | ZeroMemory(&descPipelineState, sizeof(descPipelineState));
36 | ShaderObject* vs = g_ShaderManager.getShaderObj("BasicVS");
37 | ShaderObject* ps = g_ShaderManager.getShaderObj("BasicPS");
38 | descPipelineState.VS = { vs->binaryPtr,vs->size };
39 | descPipelineState.PS = { ps->binaryPtr,ps->size };
40 | descPipelineState.InputLayout.pInputElementDescs = desNormalVertex;
41 | descPipelineState.InputLayout.NumElements = _countof(desNormalVertex);
42 | descPipelineState.pRootSignature = m_rootSignature.Get();
43 | descPipelineState.DepthStencilState=CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
44 | descPipelineState.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
45 | descPipelineState.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
46 | descPipelineState.SampleMask = UINT_MAX;
47 | descPipelineState.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
48 | descPipelineState.NumRenderTargets = numRTV;
49 | descPipelineState.RTVFormats[0] = mRtvFormat[0];
50 | descPipelineState.RTVFormats[1] = mRtvFormat[1];
51 | descPipelineState.RTVFormats[2] = mRtvFormat[2];
52 | descPipelineState.DSVFormat = mDsvFormat;
53 | descPipelineState.SampleDesc.Count = 1;
54 |
55 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateGraphicsPipelineState(&descPipelineState, IID_PPV_ARGS(&m_pipelineState)));
56 |
57 | }
58 |
59 | void DeferredRender::CreateCB()
60 | {
61 | CD3DX12_HEAP_PROPERTIES heapProperty(D3D12_HEAP_TYPE_UPLOAD);
62 | D3D12_RESOURCE_DESC resourceDesc;
63 | ZeroMemory(&resourceDesc, sizeof(resourceDesc));
64 | resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
65 | resourceDesc.Alignment = 0;
66 | resourceDesc.SampleDesc.Count = 1;
67 | resourceDesc.SampleDesc.Quality = 0;
68 | resourceDesc.MipLevels = 1;
69 | resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
70 | resourceDesc.DepthOrArraySize = 1;
71 | resourceDesc.Width = sizeof(CameraData);
72 | resourceDesc.Height = 1;
73 | resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
74 |
75 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(mViewCB.GetAddressOf())));
76 |
77 | resourceDesc.Width = sizeof(LightData);
78 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(mLightCB.GetAddressOf())));
79 |
80 | }
81 |
82 | void DeferredRender::CreateViews()
83 | {
84 |
85 | m_cbvsrvHeap.Create(g_d3dObjects->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10, true);
86 | //Camera CBV
87 | D3D12_CONSTANT_BUFFER_VIEW_DESC descBuffer;
88 | descBuffer.BufferLocation = mViewCB->GetGPUVirtualAddress();
89 | //Constant buffer must be larger than 256 bytes
90 | descBuffer.SizeInBytes = (sizeof(CameraData) + 255) & ~255;
91 | g_d3dObjects->GetD3DDevice()->CreateConstantBufferView(&descBuffer, m_cbvsrvHeap.hCPU(0));
92 | //Light CBV
93 | descBuffer.BufferLocation = mLightCB->GetGPUVirtualAddress();
94 | descBuffer.SizeInBytes = (sizeof(LightData) + 255) & ~255;
95 | g_d3dObjects->GetD3DDevice()->CreateConstantBufferView(&descBuffer, m_cbvsrvHeap.hCPU(1));
96 | }
97 |
98 | void DeferredRender::CreateDSV()
99 | {
100 | //Create DSV
101 | m_dsvHeap.Create(g_d3dObjects->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_DSV,1);
102 |
103 | CD3DX12_HEAP_PROPERTIES heapProperty(D3D12_HEAP_TYPE_DEFAULT);
104 |
105 | D3D12_RESOURCE_DESC resourceDesc;
106 | ZeroMemory(&resourceDesc, sizeof(resourceDesc));
107 | resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
108 | resourceDesc.Alignment = 0;
109 | resourceDesc.SampleDesc.Count = 1;
110 | resourceDesc.SampleDesc.Quality = 0;
111 | resourceDesc.MipLevels = 1;
112 | resourceDesc.Format = mDsvFormat;
113 | resourceDesc.DepthOrArraySize = 1;
114 | resourceDesc.Width = (UINT)g_d3dObjects->GetScreenViewport().Width;
115 | resourceDesc.Height = (UINT)g_d3dObjects->GetScreenViewport().Height;
116 | resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
117 | resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
118 |
119 | D3D12_CLEAR_VALUE clearVal;
120 | clearVal = { mDsvFormat , mClearDepth };
121 |
122 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE , &clearVal, IID_PPV_ARGS(mDsTexture.GetAddressOf())));
123 | D3D12_DEPTH_STENCIL_VIEW_DESC desc;
124 | ZeroMemory(&desc, sizeof(desc));
125 | desc.Texture2D.MipSlice = 0;
126 | desc.Format = resourceDesc.Format;
127 | desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
128 | desc.Flags = D3D12_DSV_FLAG_NONE;
129 |
130 | g_d3dObjects->GetD3DDevice()->CreateDepthStencilView(mDsTexture.Get(),&desc,m_dsvHeap.hCPU(0));
131 |
132 | D3D12_SHADER_RESOURCE_VIEW_DESC descSRV;
133 |
134 | ZeroMemory(&descSRV, sizeof(descSRV));
135 | descSRV.Texture2D.MipLevels = resourceDesc.MipLevels;
136 | descSRV.Texture2D.MostDetailedMip = 0;
137 | descSRV.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
138 | descSRV.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
139 | descSRV.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
140 |
141 |
142 | g_d3dObjects->GetD3DDevice()->CreateShaderResourceView(mDsTexture.Get(), &descSRV, m_cbvsrvHeap.hCPU(5));
143 |
144 |
145 | }
146 |
147 | void DeferredRender::CreateRTV()
148 | {
149 | //Create deferred buffers
150 | //1.Albedo
151 | //2.Normal
152 | //3.Specular + Gloss
153 | m_rtvHeap.Create(g_d3dObjects->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 3);
154 | CD3DX12_HEAP_PROPERTIES heapProperty(D3D12_HEAP_TYPE_DEFAULT);
155 |
156 | D3D12_RESOURCE_DESC resourceDesc;
157 | ZeroMemory(&resourceDesc, sizeof(resourceDesc));
158 | resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
159 | resourceDesc.Alignment = 0;
160 | resourceDesc.SampleDesc.Count = 1;
161 | resourceDesc.SampleDesc.Quality = 0;
162 | resourceDesc.MipLevels = 1;
163 |
164 | resourceDesc.DepthOrArraySize = 1;
165 | resourceDesc.Width = (UINT)g_d3dObjects->GetScreenViewport().Width;
166 | resourceDesc.Height = (UINT)g_d3dObjects->GetScreenViewport().Height;
167 | resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
168 | resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
169 |
170 | D3D12_CLEAR_VALUE clearVal;
171 | clearVal.Color[0] = mClearColor[0];
172 | clearVal.Color[1] = mClearColor[1];
173 | clearVal.Color[2] = mClearColor[2];
174 | clearVal.Color[3] = mClearColor[3];
175 |
176 |
177 |
178 |
179 | for (int i = 0; i < numRTV; i++) {
180 | resourceDesc.Format = mRtvFormat[i];
181 | clearVal.Format = mRtvFormat[i];
182 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateCommittedResource(&heapProperty, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clearVal, IID_PPV_ARGS(mRtvTexture[i].GetAddressOf())));
183 | }
184 |
185 | D3D12_RENDER_TARGET_VIEW_DESC desc;
186 | ZeroMemory(&desc, sizeof(desc));
187 | desc.Texture2D.MipSlice = 0;
188 | desc.Texture2D.PlaneSlice = 0;
189 |
190 | desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
191 |
192 | for (int i = 0; i < numRTV; i++) {
193 | desc.Format = mRtvFormat[i];
194 | g_d3dObjects->GetD3DDevice()->CreateRenderTargetView(mRtvTexture[i].Get(), &desc, m_rtvHeap.hCPU(i));
195 | }
196 |
197 |
198 | //Create SRV for RTs
199 |
200 | D3D12_SHADER_RESOURCE_VIEW_DESC descSRV;
201 |
202 | ZeroMemory(&descSRV, sizeof(descSRV));
203 | descSRV.Texture2D.MipLevels = resourceDesc.MipLevels;
204 | descSRV.Texture2D.MostDetailedMip = 0;
205 | descSRV.Format = resourceDesc.Format;
206 | descSRV.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
207 | descSRV.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
208 |
209 | m_srvHeap.Create(g_d3dObjects->GetD3DDevice(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 3,true);
210 |
211 | for (int i = 0; i < numRTV; i++) {
212 | descSRV.Format = mRtvFormat[i];
213 | g_d3dObjects->GetD3DDevice()->CreateShaderResourceView(mRtvTexture[i].Get(), &descSRV, m_cbvsrvHeap.hCPU(i + 2));
214 | }
215 |
216 |
217 | }
218 |
219 |
220 |
221 | void DeferredRender::ApplyGBufferPSO(ID3D12GraphicsCommandList * command,bool bSetPSO)
222 | {
223 | ID3D12DescriptorHeap* ppHeaps[1] = { m_cbvsrvHeap.pDH.Get() };
224 | if (bSetPSO)
225 | {
226 | command->SetPipelineState(m_pipelineState.Get());
227 | }
228 |
229 |
230 | for (int i = 0; i < numRTV; i++)
231 | command->ClearRenderTargetView(m_rtvHeap.hCPU(i), mClearColor, 0, nullptr);
232 |
233 | command->ClearDepthStencilView(m_dsvHeap.hCPUHeapStart, D3D12_CLEAR_FLAG_DEPTH, mClearDepth, 0xff, 0, nullptr);
234 |
235 | command->OMSetRenderTargets(numRTV, &m_rtvHeap.hCPUHeapStart,true, &m_dsvHeap.hCPUHeapStart);
236 | command->SetDescriptorHeaps(1, ppHeaps);
237 | command->SetGraphicsRootSignature(m_rootSignature.Get());
238 | command->SetGraphicsRootDescriptorTable(0, m_cbvsrvHeap.hGPU(0));
239 | command->SetGraphicsRootDescriptorTable(1, m_cbvsrvHeap.hGPU(1));
240 | command->SetGraphicsRootDescriptorTable(2, m_cbvsrvHeap.hGPU(2));
241 |
242 | }
243 |
244 | void DeferredRender::ApplyLightingPSO(ID3D12GraphicsCommandList * command, bool bSetPSO)
245 | {
246 |
247 | for (int i = 0; i < numRTV; i++)
248 | AddResourceBarrier(command, mRtvTexture[i].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_GENERIC_READ);
249 |
250 | AddResourceBarrier(command, mDsTexture.Get(), D3D12_RESOURCE_STATE_DEPTH_READ, D3D12_RESOURCE_STATE_GENERIC_READ);
251 |
252 | command->SetPipelineState(mLightPso.Get());
253 |
254 | mQuadRender.Draw(command);
255 |
256 |
257 | }
258 |
259 | void DeferredRender::UpdateConstantBuffer(CameraData& camData, LightData& ligData)
260 | {
261 | void* mapped = nullptr;
262 | mViewCB->Map(0, nullptr, &mapped);
263 | memcpy(mapped, &camData, sizeof(CameraData));
264 | mViewCB->Unmap(0, nullptr);
265 |
266 | mLightCB->Map(0, nullptr, &mapped);
267 | memcpy(mapped, &ligData, sizeof(LightData));
268 | mLightCB->Unmap(0, nullptr);
269 | }
270 |
271 | void DeferredRender::CreateLightPassPSO()
272 | {
273 | D3D12_GRAPHICS_PIPELINE_STATE_DESC descPipelineState;
274 | ZeroMemory(&descPipelineState, sizeof(descPipelineState));
275 | ShaderObject* vs = g_ShaderManager.getShaderObj("ScreenQuadVS");
276 | ShaderObject* ps = g_ShaderManager.getShaderObj("LightPassPS");
277 | descPipelineState.VS = { vs->binaryPtr,vs->size };
278 | descPipelineState.PS = { ps->binaryPtr,ps->size };
279 | descPipelineState.InputLayout.pInputElementDescs = desScreenQuadVertex;
280 | descPipelineState.InputLayout.NumElements = _countof(desScreenQuadVertex);
281 | descPipelineState.pRootSignature = m_rootSignature.Get();
282 | descPipelineState.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
283 | descPipelineState.DepthStencilState.DepthEnable = false;
284 | descPipelineState.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
285 | descPipelineState.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
286 | descPipelineState.RasterizerState.DepthClipEnable = false;
287 | descPipelineState.SampleMask = UINT_MAX;
288 | descPipelineState.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
289 | descPipelineState.NumRenderTargets = 1;
290 | //descPipelineState.RTVFormats[0] = mRtvFormat[0];
291 | descPipelineState.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
292 | descPipelineState.SampleDesc.Count = 1;
293 |
294 |
295 |
296 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateGraphicsPipelineState(&descPipelineState, IID_PPV_ARGS(&mLightPso)));
297 | }
298 |
299 | void DeferredRender::CreateRootSignature()
300 | {
301 | //Init descriptor tables
302 | CD3DX12_DESCRIPTOR_RANGE range[3];
303 | //view dependent CBV
304 | range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
305 | //light dependent CBV
306 | range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
307 | //G-Buffer inputs
308 | range[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 4, 0);
309 |
310 | CD3DX12_ROOT_PARAMETER rootParameters[3];
311 | rootParameters[0].InitAsDescriptorTable(1, &range[0], D3D12_SHADER_VISIBILITY_ALL);
312 | rootParameters[1].InitAsDescriptorTable(1, &range[1], D3D12_SHADER_VISIBILITY_ALL);
313 | rootParameters[2].InitAsDescriptorTable(1, &range[2], D3D12_SHADER_VISIBILITY_ALL);
314 |
315 | CD3DX12_ROOT_SIGNATURE_DESC descRootSignature;
316 | descRootSignature.Init(3, rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
317 |
318 | CD3DX12_STATIC_SAMPLER_DESC StaticSamplers[1];
319 | StaticSamplers[0].Init(0, D3D12_FILTER_MIN_MAG_MIP_LINEAR);
320 | descRootSignature.NumStaticSamplers = 1;
321 | descRootSignature.pStaticSamplers = StaticSamplers;
322 |
323 |
324 | ComPtr rootSigBlob, errorBlob;
325 |
326 | ThrowIfFailed(D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, rootSigBlob.GetAddressOf(), errorBlob.GetAddressOf()));
327 |
328 | ThrowIfFailed(g_d3dObjects->GetD3DDevice()->CreateRootSignature(0, rootSigBlob->GetBufferPointer(), rootSigBlob->GetBufferSize(), IID_PPV_ARGS(m_rootSignature.GetAddressOf())));
329 | }
330 |
--------------------------------------------------------------------------------
/d3dx12.h:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////
2 | //
3 | // Copyright (C) Microsoft Corporation. All Rights Reserved.
4 | //
5 | // File: d3dx12.h
6 | // Content: D3DX12 utility library
7 | //
8 | //////////////////////////////////////////////////////////////////////////////
9 |
10 | #ifndef __D3DX12_H__
11 | #define __D3DX12_H__
12 |
13 | #include "d3d12.h"
14 |
15 | #if defined( __cplusplus )
16 |
17 | struct CD3DX12_DEFAULT {};
18 | extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT;
19 |
20 | //------------------------------------------------------------------------------------------------
21 | inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r )
22 | {
23 | return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width &&
24 | l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth;
25 | }
26 |
27 | //------------------------------------------------------------------------------------------------
28 | inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r )
29 | { return !( l == r ); }
30 |
31 | //------------------------------------------------------------------------------------------------
32 | struct CD3DX12_RECT : public D3D12_RECT
33 | {
34 | CD3DX12_RECT()
35 | {}
36 | explicit CD3DX12_RECT( const D3D12_RECT& o ) :
37 | D3D12_RECT( o )
38 | {}
39 | explicit CD3DX12_RECT(
40 | LONG Left,
41 | LONG Top,
42 | LONG Right,
43 | LONG Bottom )
44 | {
45 | left = Left;
46 | top = Top;
47 | right = Right;
48 | bottom = Bottom;
49 | }
50 | ~CD3DX12_RECT() {}
51 | operator const D3D12_RECT&() const { return *this; }
52 | };
53 |
54 | //------------------------------------------------------------------------------------------------
55 | struct CD3DX12_BOX : public D3D12_BOX
56 | {
57 | CD3DX12_BOX()
58 | {}
59 | explicit CD3DX12_BOX( const D3D12_BOX& o ) :
60 | D3D12_BOX( o )
61 | {}
62 | explicit CD3DX12_BOX(
63 | LONG Left,
64 | LONG Right )
65 | {
66 | left = Left;
67 | top = 0;
68 | front = 0;
69 | right = Right;
70 | bottom = 1;
71 | back = 1;
72 | }
73 | explicit CD3DX12_BOX(
74 | LONG Left,
75 | LONG Top,
76 | LONG Right,
77 | LONG Bottom )
78 | {
79 | left = Left;
80 | top = Top;
81 | front = 0;
82 | right = Right;
83 | bottom = Bottom;
84 | back = 1;
85 | }
86 | explicit CD3DX12_BOX(
87 | LONG Left,
88 | LONG Top,
89 | LONG Front,
90 | LONG Right,
91 | LONG Bottom,
92 | LONG Back )
93 | {
94 | left = Left;
95 | top = Top;
96 | front = Front;
97 | right = Right;
98 | bottom = Bottom;
99 | back = Back;
100 | }
101 | ~CD3DX12_BOX() {}
102 | operator const D3D12_BOX&() const { return *this; }
103 | };
104 | inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r )
105 | {
106 | return l.left == r.left && l.top == r.top && l.front == r.front &&
107 | l.right == r.right && l.bottom == r.bottom && l.back == r.back;
108 | }
109 | inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r )
110 | { return !( l == r ); }
111 |
112 | //------------------------------------------------------------------------------------------------
113 | struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC
114 | {
115 | CD3DX12_DEPTH_STENCIL_DESC()
116 | {}
117 | explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) :
118 | D3D12_DEPTH_STENCIL_DESC( o )
119 | {}
120 | explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT )
121 | {
122 | DepthEnable = TRUE;
123 | DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
124 | DepthFunc = D3D12_COMPARISON_FUNC_LESS;
125 | StencilEnable = FALSE;
126 | StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
127 | StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
128 | const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp =
129 | { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS };
130 | FrontFace = defaultStencilOp;
131 | BackFace = defaultStencilOp;
132 | }
133 | explicit CD3DX12_DEPTH_STENCIL_DESC(
134 | BOOL depthEnable,
135 | D3D12_DEPTH_WRITE_MASK depthWriteMask,
136 | D3D12_COMPARISON_FUNC depthFunc,
137 | BOOL stencilEnable,
138 | UINT8 stencilReadMask,
139 | UINT8 stencilWriteMask,
140 | D3D12_STENCIL_OP frontStencilFailOp,
141 | D3D12_STENCIL_OP frontStencilDepthFailOp,
142 | D3D12_STENCIL_OP frontStencilPassOp,
143 | D3D12_COMPARISON_FUNC frontStencilFunc,
144 | D3D12_STENCIL_OP backStencilFailOp,
145 | D3D12_STENCIL_OP backStencilDepthFailOp,
146 | D3D12_STENCIL_OP backStencilPassOp,
147 | D3D12_COMPARISON_FUNC backStencilFunc )
148 | {
149 | DepthEnable = depthEnable;
150 | DepthWriteMask = depthWriteMask;
151 | DepthFunc = depthFunc;
152 | StencilEnable = stencilEnable;
153 | StencilReadMask = stencilReadMask;
154 | StencilWriteMask = stencilWriteMask;
155 | FrontFace.StencilFailOp = frontStencilFailOp;
156 | FrontFace.StencilDepthFailOp = frontStencilDepthFailOp;
157 | FrontFace.StencilPassOp = frontStencilPassOp;
158 | FrontFace.StencilFunc = frontStencilFunc;
159 | BackFace.StencilFailOp = backStencilFailOp;
160 | BackFace.StencilDepthFailOp = backStencilDepthFailOp;
161 | BackFace.StencilPassOp = backStencilPassOp;
162 | BackFace.StencilFunc = backStencilFunc;
163 | }
164 | ~CD3DX12_DEPTH_STENCIL_DESC() {}
165 | operator const D3D12_DEPTH_STENCIL_DESC&() const { return *this; }
166 | };
167 |
168 | //------------------------------------------------------------------------------------------------
169 | struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC
170 | {
171 | CD3DX12_BLEND_DESC()
172 | {}
173 | explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) :
174 | D3D12_BLEND_DESC( o )
175 | {}
176 | explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT )
177 | {
178 | AlphaToCoverageEnable = FALSE;
179 | IndependentBlendEnable = FALSE;
180 | const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
181 | {
182 | FALSE,FALSE,
183 | D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
184 | D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
185 | D3D12_LOGIC_OP_NOOP,
186 | D3D12_COLOR_WRITE_ENABLE_ALL,
187 | };
188 | for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
189 | RenderTarget[ i ] = defaultRenderTargetBlendDesc;
190 | }
191 | ~CD3DX12_BLEND_DESC() {}
192 | operator const D3D12_BLEND_DESC&() const { return *this; }
193 | };
194 |
195 | //------------------------------------------------------------------------------------------------
196 | struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC
197 | {
198 | CD3DX12_RASTERIZER_DESC()
199 | {}
200 | explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) :
201 | D3D12_RASTERIZER_DESC( o )
202 | {}
203 | explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT )
204 | {
205 | FillMode = D3D12_FILL_MODE_SOLID;
206 | CullMode = D3D12_CULL_MODE_BACK;
207 | FrontCounterClockwise = FALSE;
208 | DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
209 | DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
210 | SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
211 | DepthClipEnable = TRUE;
212 | MultisampleEnable = FALSE;
213 | AntialiasedLineEnable = FALSE;
214 | ForcedSampleCount = 0;
215 | ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
216 | }
217 | explicit CD3DX12_RASTERIZER_DESC(
218 | D3D12_FILL_MODE fillMode,
219 | D3D12_CULL_MODE cullMode,
220 | BOOL frontCounterClockwise,
221 | INT depthBias,
222 | FLOAT depthBiasClamp,
223 | FLOAT slopeScaledDepthBias,
224 | BOOL depthClipEnable,
225 | BOOL multisampleEnable,
226 | BOOL antialiasedLineEnable,
227 | UINT forcedSampleCount,
228 | D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster)
229 | {
230 | FillMode = fillMode;
231 | CullMode = cullMode;
232 | FrontCounterClockwise = frontCounterClockwise;
233 | DepthBias = depthBias;
234 | DepthBiasClamp = depthBiasClamp;
235 | SlopeScaledDepthBias = slopeScaledDepthBias;
236 | DepthClipEnable = depthClipEnable;
237 | MultisampleEnable = multisampleEnable;
238 | AntialiasedLineEnable = antialiasedLineEnable;
239 | ForcedSampleCount = forcedSampleCount;
240 | ConservativeRaster = conservativeRaster;
241 | }
242 | ~CD3DX12_RASTERIZER_DESC() {}
243 | operator const D3D12_RASTERIZER_DESC&() const { return *this; }
244 | };
245 |
246 | //------------------------------------------------------------------------------------------------
247 | struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO
248 | {
249 | CD3DX12_RESOURCE_ALLOCATION_INFO()
250 | {}
251 | explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) :
252 | D3D12_RESOURCE_ALLOCATION_INFO( o )
253 | {}
254 | CD3DX12_RESOURCE_ALLOCATION_INFO(
255 | UINT64 size,
256 | UINT64 alignment )
257 | {
258 | SizeInBytes = size;
259 | Alignment = alignment;
260 | }
261 | operator const D3D12_RESOURCE_ALLOCATION_INFO&() const { return *this; }
262 | };
263 |
264 | //------------------------------------------------------------------------------------------------
265 | struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES
266 | {
267 | CD3DX12_HEAP_PROPERTIES()
268 | {}
269 | explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) :
270 | D3D12_HEAP_PROPERTIES(o)
271 | {}
272 | CD3DX12_HEAP_PROPERTIES(
273 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
274 | D3D12_MEMORY_POOL memoryPoolPreference,
275 | UINT creationNodeMask = 1,
276 | UINT nodeMask = 1 )
277 | {
278 | Type = D3D12_HEAP_TYPE_CUSTOM;
279 | CPUPageProperty = cpuPageProperty;
280 | MemoryPoolPreference = memoryPoolPreference;
281 | CreationNodeMask = creationNodeMask;
282 | VisibleNodeMask = nodeMask;
283 | }
284 | explicit CD3DX12_HEAP_PROPERTIES(
285 | D3D12_HEAP_TYPE type,
286 | UINT creationNodeMask = 1,
287 | UINT nodeMask = 1 )
288 | {
289 | Type = type;
290 | CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
291 | MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
292 | CreationNodeMask = creationNodeMask;
293 | VisibleNodeMask = nodeMask;
294 | }
295 | operator const D3D12_HEAP_PROPERTIES&() const { return *this; }
296 | bool IsCPUAccessible() const
297 | {
298 | return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM &&
299 | (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK));
300 | }
301 | };
302 | inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r )
303 | {
304 | return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty &&
305 | l.MemoryPoolPreference == r.MemoryPoolPreference &&
306 | l.CreationNodeMask == r.CreationNodeMask &&
307 | l.VisibleNodeMask == r.VisibleNodeMask;
308 | }
309 | inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r )
310 | { return !( l == r ); }
311 |
312 | //------------------------------------------------------------------------------------------------
313 | struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC
314 | {
315 | CD3DX12_HEAP_DESC()
316 | {}
317 | explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) :
318 | D3D12_HEAP_DESC(o)
319 | {}
320 | CD3DX12_HEAP_DESC(
321 | UINT64 size,
322 | D3D12_HEAP_PROPERTIES properties,
323 | UINT64 alignment = 0,
324 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
325 | {
326 | SizeInBytes = size;
327 | Properties = properties;
328 | Alignment = alignment;
329 | Flags = flags;
330 | }
331 | CD3DX12_HEAP_DESC(
332 | UINT64 size,
333 | D3D12_HEAP_TYPE type,
334 | UINT64 alignment = 0,
335 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
336 | {
337 | SizeInBytes = size;
338 | Properties = CD3DX12_HEAP_PROPERTIES( type );
339 | Alignment = alignment;
340 | Flags = flags;
341 | }
342 | CD3DX12_HEAP_DESC(
343 | UINT64 size,
344 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
345 | D3D12_MEMORY_POOL memoryPoolPreference,
346 | UINT64 alignment = 0,
347 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
348 | {
349 | SizeInBytes = size;
350 | Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference );
351 | Alignment = alignment;
352 | Flags = flags;
353 | }
354 | CD3DX12_HEAP_DESC(
355 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
356 | D3D12_HEAP_PROPERTIES properties,
357 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
358 | {
359 | SizeInBytes = resAllocInfo.SizeInBytes;
360 | Properties = properties;
361 | Alignment = resAllocInfo.Alignment;
362 | Flags = flags;
363 | }
364 | CD3DX12_HEAP_DESC(
365 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
366 | D3D12_HEAP_TYPE type,
367 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
368 | {
369 | SizeInBytes = resAllocInfo.SizeInBytes;
370 | Properties = CD3DX12_HEAP_PROPERTIES( type );
371 | Alignment = resAllocInfo.Alignment;
372 | Flags = flags;
373 | }
374 | CD3DX12_HEAP_DESC(
375 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
376 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty,
377 | D3D12_MEMORY_POOL memoryPoolPreference,
378 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE )
379 | {
380 | SizeInBytes = resAllocInfo.SizeInBytes;
381 | Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference );
382 | Alignment = resAllocInfo.Alignment;
383 | Flags = flags;
384 | }
385 | operator const D3D12_HEAP_DESC&() const { return *this; }
386 | bool IsCPUAccessible() const
387 | { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); }
388 | };
389 |
390 | //------------------------------------------------------------------------------------------------
391 | struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE
392 | {
393 | CD3DX12_CLEAR_VALUE()
394 | {}
395 | explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) :
396 | D3D12_CLEAR_VALUE(o)
397 | {}
398 | CD3DX12_CLEAR_VALUE(
399 | DXGI_FORMAT format,
400 | const FLOAT color[4] )
401 | {
402 | Format = format;
403 | memcpy( Color, color, sizeof( Color ) );
404 | }
405 | CD3DX12_CLEAR_VALUE(
406 | DXGI_FORMAT format,
407 | FLOAT depth,
408 | UINT8 stencil )
409 | {
410 | Format = format;
411 | /* Use memcpy to preserve NAN values */
412 | memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) );
413 | DepthStencil.Stencil = stencil;
414 | }
415 | operator const D3D12_CLEAR_VALUE&() const { return *this; }
416 | };
417 |
418 | //------------------------------------------------------------------------------------------------
419 | struct CD3DX12_RANGE : public D3D12_RANGE
420 | {
421 | CD3DX12_RANGE()
422 | {}
423 | explicit CD3DX12_RANGE(const D3D12_RANGE &o) :
424 | D3D12_RANGE(o)
425 | {}
426 | CD3DX12_RANGE(
427 | SIZE_T begin,
428 | SIZE_T end )
429 | {
430 | Begin = begin;
431 | End = end;
432 | }
433 | operator const D3D12_RANGE&() const { return *this; }
434 | };
435 |
436 | //------------------------------------------------------------------------------------------------
437 | struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE
438 | {
439 | CD3DX12_TILED_RESOURCE_COORDINATE()
440 | {}
441 | explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) :
442 | D3D12_TILED_RESOURCE_COORDINATE(o)
443 | {}
444 | CD3DX12_TILED_RESOURCE_COORDINATE(
445 | UINT x,
446 | UINT y,
447 | UINT z,
448 | UINT subresource )
449 | {
450 | X = x;
451 | Y = y;
452 | Z = z;
453 | Subresource = subresource;
454 | }
455 | operator const D3D12_TILED_RESOURCE_COORDINATE&() const { return *this; }
456 | };
457 |
458 | //------------------------------------------------------------------------------------------------
459 | struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE
460 | {
461 | CD3DX12_TILE_REGION_SIZE()
462 | {}
463 | explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) :
464 | D3D12_TILE_REGION_SIZE(o)
465 | {}
466 | CD3DX12_TILE_REGION_SIZE(
467 | UINT numTiles,
468 | BOOL useBox,
469 | UINT width,
470 | UINT16 height,
471 | UINT16 depth )
472 | {
473 | NumTiles = numTiles;
474 | UseBox = useBox;
475 | Width = width;
476 | Height = height;
477 | Depth = depth;
478 | }
479 | operator const D3D12_TILE_REGION_SIZE&() const { return *this; }
480 | };
481 |
482 | //------------------------------------------------------------------------------------------------
483 | struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING
484 | {
485 | CD3DX12_SUBRESOURCE_TILING()
486 | {}
487 | explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) :
488 | D3D12_SUBRESOURCE_TILING(o)
489 | {}
490 | CD3DX12_SUBRESOURCE_TILING(
491 | UINT widthInTiles,
492 | UINT16 heightInTiles,
493 | UINT16 depthInTiles,
494 | UINT startTileIndexInOverallResource )
495 | {
496 | WidthInTiles = widthInTiles;
497 | HeightInTiles = heightInTiles;
498 | DepthInTiles = depthInTiles;
499 | StartTileIndexInOverallResource = startTileIndexInOverallResource;
500 | }
501 | operator const D3D12_SUBRESOURCE_TILING&() const { return *this; }
502 | };
503 |
504 | //------------------------------------------------------------------------------------------------
505 | struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE
506 | {
507 | CD3DX12_TILE_SHAPE()
508 | {}
509 | explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) :
510 | D3D12_TILE_SHAPE(o)
511 | {}
512 | CD3DX12_TILE_SHAPE(
513 | UINT widthInTexels,
514 | UINT heightInTexels,
515 | UINT depthInTexels )
516 | {
517 | WidthInTexels = widthInTexels;
518 | HeightInTexels = heightInTexels;
519 | DepthInTexels = depthInTexels;
520 | }
521 | operator const D3D12_TILE_SHAPE&() const { return *this; }
522 | };
523 |
524 | //------------------------------------------------------------------------------------------------
525 | struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
526 | {
527 | CD3DX12_RESOURCE_BARRIER()
528 | {}
529 | explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) :
530 | D3D12_RESOURCE_BARRIER(o)
531 | {}
532 | static inline CD3DX12_RESOURCE_BARRIER Transition(
533 | _In_ ID3D12Resource* pResource,
534 | D3D12_RESOURCE_STATES stateBefore,
535 | D3D12_RESOURCE_STATES stateAfter,
536 | UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
537 | D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE)
538 | {
539 | CD3DX12_RESOURCE_BARRIER result = {};
540 | D3D12_RESOURCE_BARRIER &barrier = result;
541 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
542 | result.Flags = flags;
543 | barrier.Transition.pResource = pResource;
544 | barrier.Transition.StateBefore = stateBefore;
545 | barrier.Transition.StateAfter = stateAfter;
546 | barrier.Transition.Subresource = subresource;
547 | return result;
548 | }
549 | static inline CD3DX12_RESOURCE_BARRIER Aliasing(
550 | _In_ ID3D12Resource* pResourceBefore,
551 | _In_ ID3D12Resource* pResourceAfter)
552 | {
553 | CD3DX12_RESOURCE_BARRIER result = {};
554 | D3D12_RESOURCE_BARRIER &barrier = result;
555 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
556 | barrier.Aliasing.pResourceBefore = pResourceBefore;
557 | barrier.Aliasing.pResourceAfter = pResourceAfter;
558 | return result;
559 | }
560 | static inline CD3DX12_RESOURCE_BARRIER UAV(
561 | _In_ ID3D12Resource* pResource)
562 | {
563 | CD3DX12_RESOURCE_BARRIER result = {};
564 | D3D12_RESOURCE_BARRIER &barrier = result;
565 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
566 | barrier.UAV.pResource = pResource;
567 | return result;
568 | }
569 | operator const D3D12_RESOURCE_BARRIER&() const { return *this; }
570 | };
571 |
572 | //------------------------------------------------------------------------------------------------
573 | struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO
574 | {
575 | CD3DX12_PACKED_MIP_INFO()
576 | {}
577 | explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) :
578 | D3D12_PACKED_MIP_INFO(o)
579 | {}
580 | CD3DX12_PACKED_MIP_INFO(
581 | UINT8 numStandardMips,
582 | UINT8 numPackedMips,
583 | UINT numTilesForPackedMips,
584 | UINT startTileIndexInOverallResource )
585 | {
586 | NumStandardMips = numStandardMips;
587 | NumPackedMips = numPackedMips;
588 | NumTilesForPackedMips = numTilesForPackedMips;
589 | StartTileIndexInOverallResource = startTileIndexInOverallResource;
590 | }
591 | operator const D3D12_PACKED_MIP_INFO&() const { return *this; }
592 | };
593 |
594 | //------------------------------------------------------------------------------------------------
595 | struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT
596 | {
597 | CD3DX12_SUBRESOURCE_FOOTPRINT()
598 | {}
599 | explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) :
600 | D3D12_SUBRESOURCE_FOOTPRINT(o)
601 | {}
602 | CD3DX12_SUBRESOURCE_FOOTPRINT(
603 | DXGI_FORMAT format,
604 | UINT width,
605 | UINT height,
606 | UINT depth,
607 | UINT rowPitch )
608 | {
609 | Format = format;
610 | Width = width;
611 | Height = height;
612 | Depth = depth;
613 | RowPitch = rowPitch;
614 | }
615 | explicit CD3DX12_SUBRESOURCE_FOOTPRINT(
616 | const D3D12_RESOURCE_DESC& resDesc,
617 | UINT rowPitch )
618 | {
619 | Format = resDesc.Format;
620 | Width = UINT( resDesc.Width );
621 | Height = resDesc.Height;
622 | Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1);
623 | RowPitch = rowPitch;
624 | }
625 | operator const D3D12_SUBRESOURCE_FOOTPRINT&() const { return *this; }
626 | };
627 |
628 | //------------------------------------------------------------------------------------------------
629 | struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION
630 | {
631 | CD3DX12_TEXTURE_COPY_LOCATION()
632 | {}
633 | explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) :
634 | D3D12_TEXTURE_COPY_LOCATION(o)
635 | {}
636 | CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes) { pResource = pRes; }
637 | CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint)
638 | {
639 | pResource = pRes;
640 | Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
641 | PlacedFootprint = Footprint;
642 | }
643 | CD3DX12_TEXTURE_COPY_LOCATION(ID3D12Resource* pRes, UINT Sub)
644 | {
645 | pResource = pRes;
646 | Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
647 | SubresourceIndex = Sub;
648 | }
649 | };
650 |
651 | //------------------------------------------------------------------------------------------------
652 | struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE
653 | {
654 | CD3DX12_DESCRIPTOR_RANGE() { }
655 | explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) :
656 | D3D12_DESCRIPTOR_RANGE(o)
657 | {}
658 | CD3DX12_DESCRIPTOR_RANGE(
659 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
660 | UINT numDescriptors,
661 | UINT baseShaderRegister,
662 | UINT registerSpace = 0,
663 | UINT offsetInDescriptorsFromTableStart =
664 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
665 | {
666 | Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
667 | }
668 |
669 | inline void Init(
670 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
671 | UINT numDescriptors,
672 | UINT baseShaderRegister,
673 | UINT registerSpace = 0,
674 | UINT offsetInDescriptorsFromTableStart =
675 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
676 | {
677 | Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart);
678 | }
679 |
680 | static inline void Init(
681 | _Out_ D3D12_DESCRIPTOR_RANGE &range,
682 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType,
683 | UINT numDescriptors,
684 | UINT baseShaderRegister,
685 | UINT registerSpace = 0,
686 | UINT offsetInDescriptorsFromTableStart =
687 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
688 | {
689 | range.RangeType = rangeType;
690 | range.NumDescriptors = numDescriptors;
691 | range.BaseShaderRegister = baseShaderRegister;
692 | range.RegisterSpace = registerSpace;
693 | range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart;
694 | }
695 | };
696 |
697 | //------------------------------------------------------------------------------------------------
698 | struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE
699 | {
700 | CD3DX12_ROOT_DESCRIPTOR_TABLE() {}
701 | explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) :
702 | D3D12_ROOT_DESCRIPTOR_TABLE(o)
703 | {}
704 | CD3DX12_ROOT_DESCRIPTOR_TABLE(
705 | UINT numDescriptorRanges,
706 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
707 | {
708 | Init(numDescriptorRanges, _pDescriptorRanges);
709 | }
710 |
711 | inline void Init(
712 | UINT numDescriptorRanges,
713 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
714 | {
715 | Init(*this, numDescriptorRanges, _pDescriptorRanges);
716 | }
717 |
718 | static inline void Init(
719 | _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable,
720 | UINT numDescriptorRanges,
721 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges)
722 | {
723 | rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges;
724 | rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges;
725 | }
726 | };
727 |
728 | //------------------------------------------------------------------------------------------------
729 | struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS
730 | {
731 | CD3DX12_ROOT_CONSTANTS() {}
732 | explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) :
733 | D3D12_ROOT_CONSTANTS(o)
734 | {}
735 | CD3DX12_ROOT_CONSTANTS(
736 | UINT num32BitValues,
737 | UINT shaderRegister,
738 | UINT registerSpace = 0)
739 | {
740 | Init(num32BitValues, shaderRegister, registerSpace);
741 | }
742 |
743 | inline void Init(
744 | UINT num32BitValues,
745 | UINT shaderRegister,
746 | UINT registerSpace = 0)
747 | {
748 | Init(*this, num32BitValues, shaderRegister, registerSpace);
749 | }
750 |
751 | static inline void Init(
752 | _Out_ D3D12_ROOT_CONSTANTS &rootConstants,
753 | UINT num32BitValues,
754 | UINT shaderRegister,
755 | UINT registerSpace = 0)
756 | {
757 | rootConstants.Num32BitValues = num32BitValues;
758 | rootConstants.ShaderRegister = shaderRegister;
759 | rootConstants.RegisterSpace = registerSpace;
760 | }
761 | };
762 |
763 | //------------------------------------------------------------------------------------------------
764 | struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR
765 | {
766 | CD3DX12_ROOT_DESCRIPTOR() {}
767 | explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) :
768 | D3D12_ROOT_DESCRIPTOR(o)
769 | {}
770 | CD3DX12_ROOT_DESCRIPTOR(
771 | UINT shaderRegister,
772 | UINT registerSpace = 0)
773 | {
774 | Init(shaderRegister, registerSpace);
775 | }
776 |
777 | inline void Init(
778 | UINT shaderRegister,
779 | UINT registerSpace = 0)
780 | {
781 | Init(*this, shaderRegister, registerSpace);
782 | }
783 |
784 | static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0)
785 | {
786 | table.ShaderRegister = shaderRegister;
787 | table.RegisterSpace = registerSpace;
788 | }
789 | };
790 |
791 | //------------------------------------------------------------------------------------------------
792 | struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER
793 | {
794 | CD3DX12_ROOT_PARAMETER() {}
795 | explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) :
796 | D3D12_ROOT_PARAMETER(o)
797 | {}
798 |
799 | static inline void InitAsDescriptorTable(
800 | _Out_ D3D12_ROOT_PARAMETER &rootParam,
801 | UINT numDescriptorRanges,
802 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
803 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
804 | {
805 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
806 | rootParam.ShaderVisibility = visibility;
807 | CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges);
808 | }
809 |
810 | static inline void InitAsConstants(
811 | _Out_ D3D12_ROOT_PARAMETER &rootParam,
812 | UINT num32BitValues,
813 | UINT shaderRegister,
814 | UINT registerSpace = 0,
815 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
816 | {
817 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
818 | rootParam.ShaderVisibility = visibility;
819 | CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace);
820 | }
821 |
822 | static inline void InitAsConstantBufferView(
823 | _Out_ D3D12_ROOT_PARAMETER &rootParam,
824 | UINT shaderRegister,
825 | UINT registerSpace = 0,
826 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
827 | {
828 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
829 | rootParam.ShaderVisibility = visibility;
830 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
831 | }
832 |
833 | static inline void InitAsShaderResourceView(
834 | _Out_ D3D12_ROOT_PARAMETER &rootParam,
835 | UINT shaderRegister,
836 | UINT registerSpace = 0,
837 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
838 | {
839 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
840 | rootParam.ShaderVisibility = visibility;
841 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
842 | }
843 |
844 | static inline void InitAsUnorderedAccessView(
845 | _Out_ D3D12_ROOT_PARAMETER &rootParam,
846 | UINT shaderRegister,
847 | UINT registerSpace = 0,
848 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
849 | {
850 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
851 | rootParam.ShaderVisibility = visibility;
852 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace);
853 | }
854 |
855 | inline void InitAsDescriptorTable(
856 | UINT numDescriptorRanges,
857 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges,
858 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
859 | {
860 | InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility);
861 | }
862 |
863 | inline void InitAsConstants(
864 | UINT num32BitValues,
865 | UINT shaderRegister,
866 | UINT registerSpace = 0,
867 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
868 | {
869 | InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility);
870 | }
871 |
872 | inline void InitAsConstantBufferView(
873 | UINT shaderRegister,
874 | UINT registerSpace = 0,
875 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
876 | {
877 | InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility);
878 | }
879 |
880 | inline void InitAsShaderResourceView(
881 | UINT shaderRegister,
882 | UINT registerSpace = 0,
883 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
884 | {
885 | InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility);
886 | }
887 |
888 | inline void InitAsUnorderedAccessView(
889 | UINT shaderRegister,
890 | UINT registerSpace = 0,
891 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL)
892 | {
893 | InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility);
894 | }
895 | };
896 |
897 | //------------------------------------------------------------------------------------------------
898 | struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC
899 | {
900 | CD3DX12_STATIC_SAMPLER_DESC() {}
901 | explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) :
902 | D3D12_STATIC_SAMPLER_DESC(o)
903 | {}
904 | CD3DX12_STATIC_SAMPLER_DESC(
905 | UINT shaderRegister,
906 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
907 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
908 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
909 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
910 | FLOAT mipLODBias = 0,
911 | UINT maxAnisotropy = 16,
912 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
913 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
914 | FLOAT minLOD = 0.f,
915 | FLOAT maxLOD = D3D12_FLOAT32_MAX,
916 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
917 | UINT registerSpace = 0)
918 | {
919 | Init(
920 | shaderRegister,
921 | filter,
922 | addressU,
923 | addressV,
924 | addressW,
925 | mipLODBias,
926 | maxAnisotropy,
927 | comparisonFunc,
928 | borderColor,
929 | minLOD,
930 | maxLOD,
931 | shaderVisibility,
932 | registerSpace);
933 | }
934 |
935 | static inline void Init(
936 | _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc,
937 | UINT shaderRegister,
938 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
939 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
940 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
941 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
942 | FLOAT mipLODBias = 0,
943 | UINT maxAnisotropy = 16,
944 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
945 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
946 | FLOAT minLOD = 0.f,
947 | FLOAT maxLOD = D3D12_FLOAT32_MAX,
948 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
949 | UINT registerSpace = 0)
950 | {
951 | samplerDesc.ShaderRegister = shaderRegister;
952 | samplerDesc.Filter = filter;
953 | samplerDesc.AddressU = addressU;
954 | samplerDesc.AddressV = addressV;
955 | samplerDesc.AddressW = addressW;
956 | samplerDesc.MipLODBias = mipLODBias;
957 | samplerDesc.MaxAnisotropy = maxAnisotropy;
958 | samplerDesc.ComparisonFunc = comparisonFunc;
959 | samplerDesc.BorderColor = borderColor;
960 | samplerDesc.MinLOD = minLOD;
961 | samplerDesc.MaxLOD = maxLOD;
962 | samplerDesc.ShaderVisibility = shaderVisibility;
963 | samplerDesc.RegisterSpace = registerSpace;
964 | }
965 | inline void Init(
966 | UINT shaderRegister,
967 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC,
968 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
969 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
970 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
971 | FLOAT mipLODBias = 0,
972 | UINT maxAnisotropy = 16,
973 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
974 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
975 | FLOAT minLOD = 0.f,
976 | FLOAT maxLOD = D3D12_FLOAT32_MAX,
977 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
978 | UINT registerSpace = 0)
979 | {
980 | Init(
981 | *this,
982 | shaderRegister,
983 | filter,
984 | addressU,
985 | addressV,
986 | addressW,
987 | mipLODBias,
988 | maxAnisotropy,
989 | comparisonFunc,
990 | borderColor,
991 | minLOD,
992 | maxLOD,
993 | shaderVisibility,
994 | registerSpace);
995 | }
996 |
997 | };
998 |
999 | //------------------------------------------------------------------------------------------------
1000 | struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC
1001 | {
1002 | CD3DX12_ROOT_SIGNATURE_DESC() {}
1003 | explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) :
1004 | D3D12_ROOT_SIGNATURE_DESC(o)
1005 | {}
1006 | CD3DX12_ROOT_SIGNATURE_DESC(
1007 | UINT numParameters,
1008 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
1009 | UINT numStaticSamplers = 0,
1010 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
1011 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
1012 | {
1013 | Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
1014 | }
1015 |
1016 | inline void Init(
1017 | UINT numParameters,
1018 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
1019 | UINT numStaticSamplers = 0,
1020 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
1021 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
1022 | {
1023 | Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags);
1024 | }
1025 |
1026 | static inline void Init(
1027 | _Out_ D3D12_ROOT_SIGNATURE_DESC &desc,
1028 | UINT numParameters,
1029 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters,
1030 | UINT numStaticSamplers = 0,
1031 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = NULL,
1032 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE)
1033 | {
1034 | desc.NumParameters = numParameters;
1035 | desc.pParameters = _pParameters;
1036 | desc.NumStaticSamplers = numStaticSamplers;
1037 | desc.pStaticSamplers = _pStaticSamplers;
1038 | desc.Flags = flags;
1039 | }
1040 |
1041 | CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) : CD3DX12_ROOT_SIGNATURE_DESC(0,NULL,0,NULL,D3D12_ROOT_SIGNATURE_FLAG_NONE) {}
1042 | };
1043 |
1044 | //------------------------------------------------------------------------------------------------
1045 | struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE
1046 | {
1047 | CD3DX12_CPU_DESCRIPTOR_HANDLE() {}
1048 | explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) :
1049 | D3D12_CPU_DESCRIPTOR_HANDLE(o)
1050 | {}
1051 | CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
1052 | CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize)
1053 | {
1054 | InitOffsetted(other, offsetScaledByIncrementSize);
1055 | }
1056 | CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize)
1057 | {
1058 | InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
1059 | }
1060 | CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
1061 | {
1062 | ptr += offsetInDescriptors * descriptorIncrementSize;
1063 | return *this;
1064 | }
1065 | CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
1066 | {
1067 | ptr += offsetScaledByIncrementSize;
1068 | return *this;
1069 | }
1070 | bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
1071 | {
1072 | return (ptr == other.ptr);
1073 | }
1074 | bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other)
1075 | {
1076 | return (ptr != other.ptr);
1077 | }
1078 | CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other)
1079 | {
1080 | ptr = other.ptr;
1081 | return *this;
1082 | }
1083 |
1084 | inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
1085 | {
1086 | InitOffsetted(*this, base, offsetScaledByIncrementSize);
1087 | }
1088 |
1089 | inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
1090 | {
1091 | InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
1092 | }
1093 |
1094 | static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
1095 | {
1096 | handle.ptr = base.ptr + offsetScaledByIncrementSize;
1097 | }
1098 |
1099 | static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
1100 | {
1101 | handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
1102 | }
1103 | };
1104 |
1105 | //------------------------------------------------------------------------------------------------
1106 | struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE
1107 | {
1108 | CD3DX12_GPU_DESCRIPTOR_HANDLE() {}
1109 | explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) :
1110 | D3D12_GPU_DESCRIPTOR_HANDLE(o)
1111 | {}
1112 | CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; }
1113 | CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize)
1114 | {
1115 | InitOffsetted(other, offsetScaledByIncrementSize);
1116 | }
1117 | CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize)
1118 | {
1119 | InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize);
1120 | }
1121 | CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize)
1122 | {
1123 | ptr += offsetInDescriptors * descriptorIncrementSize;
1124 | return *this;
1125 | }
1126 | CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize)
1127 | {
1128 | ptr += offsetScaledByIncrementSize;
1129 | return *this;
1130 | }
1131 | inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
1132 | {
1133 | return (ptr == other.ptr);
1134 | }
1135 | inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other)
1136 | {
1137 | return (ptr != other.ptr);
1138 | }
1139 | CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other)
1140 | {
1141 | ptr = other.ptr;
1142 | return *this;
1143 | }
1144 |
1145 | inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
1146 | {
1147 | InitOffsetted(*this, base, offsetScaledByIncrementSize);
1148 | }
1149 |
1150 | inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
1151 | {
1152 | InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize);
1153 | }
1154 |
1155 | static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize)
1156 | {
1157 | handle.ptr = base.ptr + offsetScaledByIncrementSize;
1158 | }
1159 |
1160 | static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize)
1161 | {
1162 | handle.ptr = base.ptr + offsetInDescriptors * descriptorIncrementSize;
1163 | }
1164 | };
1165 |
1166 | //------------------------------------------------------------------------------------------------
1167 | inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize )
1168 | {
1169 | return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize;
1170 | }
1171 |
1172 | //------------------------------------------------------------------------------------------------
1173 | template
1174 | inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice )
1175 | {
1176 | MipSlice = static_cast(Subresource % MipLevels);
1177 | ArraySlice = static_cast((Subresource / MipLevels) % ArraySize);
1178 | PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize));
1179 | }
1180 |
1181 | //------------------------------------------------------------------------------------------------
1182 | inline UINT8 D3D12GetFormatPlaneCount(
1183 | _In_ ID3D12Device* pDevice,
1184 | DXGI_FORMAT Format
1185 | )
1186 | {
1187 | D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = {Format};
1188 | if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo))))
1189 | {
1190 | return 0;
1191 | }
1192 | return formatInfo.PlaneCount;
1193 | }
1194 |
1195 | //------------------------------------------------------------------------------------------------
1196 | struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC
1197 | {
1198 | CD3DX12_RESOURCE_DESC()
1199 | {}
1200 | explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) :
1201 | D3D12_RESOURCE_DESC( o )
1202 | {}
1203 | CD3DX12_RESOURCE_DESC(
1204 | D3D12_RESOURCE_DIMENSION dimension,
1205 | UINT64 alignment,
1206 | UINT64 width,
1207 | UINT height,
1208 | UINT16 depthOrArraySize,
1209 | UINT16 mipLevels,
1210 | DXGI_FORMAT format,
1211 | UINT sampleCount,
1212 | UINT sampleQuality,
1213 | D3D12_TEXTURE_LAYOUT layout,
1214 | D3D12_RESOURCE_FLAGS flags )
1215 | {
1216 | Dimension = dimension;
1217 | Alignment = alignment;
1218 | Width = width;
1219 | Height = height;
1220 | DepthOrArraySize = depthOrArraySize;
1221 | MipLevels = mipLevels;
1222 | Format = format;
1223 | SampleDesc.Count = sampleCount;
1224 | SampleDesc.Quality = sampleQuality;
1225 | Layout = layout;
1226 | Flags = flags;
1227 | }
1228 | static inline CD3DX12_RESOURCE_DESC Buffer(
1229 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo,
1230 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE )
1231 | {
1232 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes,
1233 | 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags );
1234 | }
1235 | static inline CD3DX12_RESOURCE_DESC Buffer(
1236 | UINT64 width,
1237 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
1238 | UINT64 alignment = 0 )
1239 | {
1240 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1,
1241 | DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags );
1242 | }
1243 | static inline CD3DX12_RESOURCE_DESC Tex1D(
1244 | DXGI_FORMAT format,
1245 | UINT64 width,
1246 | UINT16 arraySize = 1,
1247 | UINT16 mipLevels = 0,
1248 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
1249 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
1250 | UINT64 alignment = 0 )
1251 | {
1252 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize,
1253 | mipLevels, format, 1, 0, layout, flags );
1254 | }
1255 | static inline CD3DX12_RESOURCE_DESC Tex2D(
1256 | DXGI_FORMAT format,
1257 | UINT64 width,
1258 | UINT height,
1259 | UINT16 arraySize = 1,
1260 | UINT16 mipLevels = 0,
1261 | UINT sampleCount = 1,
1262 | UINT sampleQuality = 0,
1263 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
1264 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
1265 | UINT64 alignment = 0 )
1266 | {
1267 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize,
1268 | mipLevels, format, sampleCount, sampleQuality, layout, flags );
1269 | }
1270 | static inline CD3DX12_RESOURCE_DESC Tex3D(
1271 | DXGI_FORMAT format,
1272 | UINT64 width,
1273 | UINT height,
1274 | UINT16 depth,
1275 | UINT16 mipLevels = 0,
1276 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE,
1277 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,
1278 | UINT64 alignment = 0 )
1279 | {
1280 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth,
1281 | mipLevels, format, 1, 0, layout, flags );
1282 | }
1283 | inline UINT16 Depth() const
1284 | { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); }
1285 | inline UINT16 ArraySize() const
1286 | { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); }
1287 | inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const
1288 | { return D3D12GetFormatPlaneCount(pDevice, Format); }
1289 | inline UINT Subresources(_In_ ID3D12Device* pDevice) const
1290 | { return MipLevels * ArraySize() * PlaneCount(pDevice); }
1291 | inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice)
1292 | { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); }
1293 | operator const D3D12_RESOURCE_DESC&() const { return *this; }
1294 | };
1295 |
1296 | //------------------------------------------------------------------------------------------------
1297 | // Row-by-row memcpy
1298 | inline void MemcpySubresource(
1299 | _In_ const D3D12_MEMCPY_DEST* pDest,
1300 | _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
1301 | SIZE_T RowSizeInBytes,
1302 | UINT NumRows,
1303 | UINT NumSlices)
1304 | {
1305 | for (UINT z = 0; z < NumSlices; ++z)
1306 | {
1307 | BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z;
1308 | const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z;
1309 | for (UINT y = 0; y < NumRows; ++y)
1310 | {
1311 | memcpy(pDestSlice + pDest->RowPitch * y,
1312 | pSrcSlice + pSrc->RowPitch * y,
1313 | RowSizeInBytes);
1314 | }
1315 | }
1316 | }
1317 |
1318 | //------------------------------------------------------------------------------------------------
1319 | // Returns required size of a buffer to be used for data upload
1320 | inline UINT64 GetRequiredIntermediateSize(
1321 | _In_ ID3D12Resource* pDestinationResource,
1322 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
1323 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources)
1324 | {
1325 | D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
1326 | UINT64 RequiredSize = 0;
1327 |
1328 | ID3D12Device* pDevice;
1329 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice));
1330 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
1331 | pDevice->Release();
1332 |
1333 | return RequiredSize;
1334 | }
1335 |
1336 | //------------------------------------------------------------------------------------------------
1337 | // All arrays must be populated (e.g. by calling GetCopyableFootprints)
1338 | inline UINT64 UpdateSubresources(
1339 | _In_ ID3D12GraphicsCommandList* pCmdList,
1340 | _In_ ID3D12Resource* pDestinationResource,
1341 | _In_ ID3D12Resource* pIntermediate,
1342 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
1343 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
1344 | UINT64 RequiredSize,
1345 | _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
1346 | _In_reads_(NumSubresources) const UINT* pNumRows,
1347 | _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
1348 | _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData)
1349 | {
1350 | // Minor validation
1351 | D3D12_RESOURCE_DESC IntermediateDesc = pIntermediate->GetDesc();
1352 | D3D12_RESOURCE_DESC DestinationDesc = pDestinationResource->GetDesc();
1353 | if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
1354 | IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
1355 | RequiredSize > (SIZE_T)-1 ||
1356 | (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
1357 | (FirstSubresource != 0 || NumSubresources != 1)))
1358 | {
1359 | return 0;
1360 | }
1361 |
1362 | BYTE* pData;
1363 | HRESULT hr = pIntermediate->Map(0, NULL, reinterpret_cast(&pData));
1364 | if (FAILED(hr))
1365 | {
1366 | return 0;
1367 | }
1368 |
1369 | for (UINT i = 0; i < NumSubresources; ++i)
1370 | {
1371 | if (pRowSizesInBytes[i] > (SIZE_T)-1) return 0;
1372 | D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, pLayouts[i].Footprint.RowPitch * pNumRows[i] };
1373 | MemcpySubresource(&DestData, &pSrcData[i], (SIZE_T)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth);
1374 | }
1375 | pIntermediate->Unmap(0, NULL);
1376 |
1377 | if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
1378 | {
1379 | CD3DX12_BOX SrcBox( UINT( pLayouts[0].Offset ), UINT( pLayouts[0].Offset + pLayouts[0].Footprint.Width ) );
1380 | pCmdList->CopyBufferRegion(
1381 | pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
1382 | }
1383 | else
1384 | {
1385 | for (UINT i = 0; i < NumSubresources; ++i)
1386 | {
1387 | CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
1388 | CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
1389 | pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
1390 | }
1391 | }
1392 | return RequiredSize;
1393 | }
1394 |
1395 | //------------------------------------------------------------------------------------------------
1396 | // Heap-allocating UpdateSubresources implementation
1397 | inline UINT64 UpdateSubresources(
1398 | _In_ ID3D12GraphicsCommandList* pCmdList,
1399 | _In_ ID3D12Resource* pDestinationResource,
1400 | _In_ ID3D12Resource* pIntermediate,
1401 | UINT64 IntermediateOffset,
1402 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
1403 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
1404 | _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
1405 | {
1406 | UINT64 RequiredSize = 0;
1407 | UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
1408 | if (MemToAlloc > SIZE_MAX)
1409 | {
1410 | return 0;
1411 | }
1412 | void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc));
1413 | if (pMem == NULL)
1414 | {
1415 | return 0;
1416 | }
1417 | D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts = reinterpret_cast(pMem);
1418 | UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources);
1419 | UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources);
1420 |
1421 | D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
1422 | ID3D12Device* pDevice;
1423 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice));
1424 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
1425 | pDevice->Release();
1426 |
1427 | UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
1428 | HeapFree(GetProcessHeap(), 0, pMem);
1429 | return Result;
1430 | }
1431 |
1432 | //------------------------------------------------------------------------------------------------
1433 | // Stack-allocating UpdateSubresources implementation
1434 | template
1435 | inline UINT64 UpdateSubresources(
1436 | _In_ ID3D12GraphicsCommandList* pCmdList,
1437 | _In_ ID3D12Resource* pDestinationResource,
1438 | _In_ ID3D12Resource* pIntermediate,
1439 | UINT64 IntermediateOffset,
1440 | _In_range_(0, MaxSubresources) UINT FirstSubresource,
1441 | _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources,
1442 | _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData)
1443 | {
1444 | UINT64 RequiredSize = 0;
1445 | D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
1446 | UINT NumRows[MaxSubresources];
1447 | UINT64 RowSizesInBytes[MaxSubresources];
1448 |
1449 | D3D12_RESOURCE_DESC Desc = pDestinationResource->GetDesc();
1450 | ID3D12Device* pDevice;
1451 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice));
1452 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
1453 | pDevice->Release();
1454 |
1455 | return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
1456 | }
1457 |
1458 | //------------------------------------------------------------------------------------------------
1459 | inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout )
1460 | { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; }
1461 |
1462 | //------------------------------------------------------------------------------------------------
1463 | inline ID3D12CommandList * const * CommandListCast(ID3D12GraphicsCommandList * const * pp)
1464 | {
1465 | // This cast is useful for passing strongly typed command list pointers into
1466 | // ExecuteCommandLists.
1467 | // This cast is valid as long as the const-ness is respected. D3D12 APIs do
1468 | // respect the const-ness of their arguments.
1469 | return reinterpret_cast(pp);
1470 | }
1471 |
1472 |
1473 | #endif // defined( __cplusplus )
1474 |
1475 | #endif //__D3DX12_H__
1476 |
1477 |
1478 |
1479 |
--------------------------------------------------------------------------------