├── 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 | --------------------------------------------------------------------------------