core: Define VK_USE_PLATFORM_XCB_KHR before including vkd3d_utils.h.
[vkmodelviewer.git] / Core / TemporalEffects.cpp
blobff1414e5e10768578bb309d516c7f53d9c2f15fb
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // This code is licensed under the MIT License (MIT).
4 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8 //
9 // Developed by Minigraph
11 // Author: James Stanard
14 #include "pch.h"
15 #include "TemporalEffects.h"
16 #include "BufferManager.h"
17 #include "GraphicsCore.h"
18 #include "CommandContext.h"
19 #include "SystemTime.h"
20 #include "PostEffects.h"
22 #include "compiled_shaders/TemporalBlendCS.h"
23 #include "compiled_shaders/BoundNeighborhoodCS.h"
24 #include "compiled_shaders/ResolveTAACS.h"
25 #include "compiled_shaders/SharpenTAACS.h"
27 using namespace Graphics;
28 using namespace Math;
29 using namespace TemporalEffects;
31 namespace TemporalEffects
33 BoolVar EnableTAA("Graphics/AA/TAA/Enable", false);
34 NumVar Sharpness("Graphics/AA/TAA/Sharpness", 0.5f, 0.0f, 1.0f, 0.25f);
35 NumVar TemporalMaxLerp("Graphics/AA/TAA/Blend Factor", 1.0f, 0.0f, 1.0f, 0.01f);
36 ExpVar TemporalSpeedLimit("Graphics/AA/TAA/Speed Limit", 64.0f, 1.0f, 1024.0f, 1.0f);
37 BoolVar TriggerReset("Graphics/AA/TAA/Reset", false);
39 RootSignature s_RootSignature;
41 ComputePSO s_TemporalBlendCS;
42 ComputePSO s_BoundNeighborhoodCS;
43 ComputePSO s_SharpenTAACS;
44 ComputePSO s_ResolveTAACS;
46 uint32_t s_FrameIndex = 0;
47 uint32_t s_FrameIndexMod2 = 0;
48 float s_JitterX = 0.5f;
49 float s_JitterY = 0.5f;
50 float s_JitterDeltaX = 0.0f;
51 float s_JitterDeltaY = 0.0f;
53 void ApplyTemporalAA(ComputeContext& Context);
54 void SharpenImage(ComputeContext& Context, ColorBuffer& TemporalColor);
57 void TemporalEffects::Initialize( void )
59 s_RootSignature.Reset(4, 2);
60 s_RootSignature[0].InitAsConstants(0, 4);
61 s_RootSignature[1].InitAsDescriptorRange(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, 10);
62 s_RootSignature[2].InitAsDescriptorRange(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 10);
63 s_RootSignature[3].InitAsConstantBuffer(1);
64 s_RootSignature.InitStaticSampler(0, SamplerLinearBorderDesc);
65 s_RootSignature.InitStaticSampler(1, SamplerPointBorderDesc);
66 s_RootSignature.Finalize(L"Temporal RS");
68 #define CreatePSO( ObjName, ShaderByteCode ) \
69 ObjName.SetRootSignature(s_RootSignature); \
70 ObjName.SetComputeShader(ShaderByteCode, sizeof(ShaderByteCode) ); \
71 ObjName.Finalize();
73 CreatePSO( s_TemporalBlendCS, g_pTemporalBlendCS );
74 CreatePSO( s_BoundNeighborhoodCS, g_pBoundNeighborhoodCS );
75 CreatePSO( s_SharpenTAACS, g_pSharpenTAACS );
76 CreatePSO( s_ResolveTAACS, g_pResolveTAACS );
78 #undef CreatePSO
81 void TemporalEffects::Shutdown( void )
85 void TemporalEffects::Update( uint64_t FrameIndex )
87 s_FrameIndex = (uint32_t)FrameIndex;
88 s_FrameIndexMod2 = s_FrameIndex % 2;
90 if (EnableTAA)// && !DepthOfField::Enable)
92 static const float Halton23[8][2] =
94 { 0.0f / 8.0f, 0.0f / 9.0f }, { 4.0f / 8.0f, 3.0f / 9.0f },
95 { 2.0f / 8.0f, 6.0f / 9.0f }, { 6.0f / 8.0f, 1.0f / 9.0f },
96 { 1.0f / 8.0f, 4.0f / 9.0f }, { 5.0f / 8.0f, 7.0f / 9.0f },
97 { 3.0f / 8.0f, 2.0f / 9.0f }, { 7.0f / 8.0f, 5.0f / 9.0f }
100 const float* Offset = Halton23[s_FrameIndex % 8];
102 s_JitterDeltaX = s_JitterX - Offset[0];
103 s_JitterDeltaY = s_JitterY - Offset[1];
104 s_JitterX = Offset[0];
105 s_JitterY = Offset[1];
107 else
109 s_JitterDeltaX = s_JitterX - 0.5f;
110 s_JitterDeltaY = s_JitterY - 0.5f;
111 s_JitterX = 0.5f;
112 s_JitterY = 0.5f;
117 uint32_t TemporalEffects::GetFrameIndexMod2( void )
119 return s_FrameIndexMod2;
122 void TemporalEffects::GetJitterOffset( float& JitterX, float& JitterY )
124 JitterX = s_JitterX;
125 JitterY = s_JitterY;
128 void TemporalEffects::ClearHistory( CommandContext& Context )
130 GraphicsContext& gfxContext = Context.GetGraphicsContext();
132 if (EnableTAA)
134 gfxContext.TransitionResource(g_TemporalColor[0], D3D12_RESOURCE_STATE_RENDER_TARGET);
135 gfxContext.TransitionResource(g_TemporalColor[1], D3D12_RESOURCE_STATE_RENDER_TARGET, true);
136 gfxContext.ClearColor(g_TemporalColor[0]);
137 gfxContext.ClearColor(g_TemporalColor[1]);
141 void TemporalEffects::ResolveImage( CommandContext& BaseContext )
143 ScopedTimer _prof(L"Temporal Resolve", BaseContext);
145 ComputeContext& Context = BaseContext.GetComputeContext();
147 static bool s_EnableTAA = false;
149 if (EnableTAA != s_EnableTAA || TriggerReset)
151 ClearHistory(Context);
152 s_EnableTAA = EnableTAA;
153 TriggerReset = false;
156 uint32_t Src = s_FrameIndexMod2;
157 uint32_t Dst = Src ^ 1;
159 if (EnableTAA)
161 ApplyTemporalAA(Context);
162 SharpenImage(Context, g_TemporalColor[Dst]);
166 void TemporalEffects::ApplyTemporalAA(ComputeContext& Context)
168 ScopedTimer _prof(L"Resolve Image", Context);
170 uint32_t Src = s_FrameIndexMod2;
171 uint32_t Dst = Src ^ 1;
173 Context.SetRootSignature(s_RootSignature);
174 Context.SetPipelineState(s_TemporalBlendCS);
176 struct DECLSPEC_ALIGN(16) ConstantBuffer
178 float RcpBufferDim[2];
179 float TemporalBlendFactor;
180 float RcpSeedLimiter;
181 float CombinedJitter[2];
183 ConstantBuffer cbv = {
184 1.0f / g_SceneColorBuffer.GetWidth(), 1.0f / g_SceneColorBuffer.GetHeight(),
185 (float)TemporalMaxLerp, 1.0f / TemporalSpeedLimit,
186 s_JitterDeltaX, s_JitterDeltaY
189 Context.SetDynamicConstantBufferView(3, sizeof(cbv), &cbv);
191 Context.TransitionResource(g_VelocityBuffer, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
192 Context.TransitionResource(g_SceneColorBuffer, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
193 Context.TransitionResource(g_TemporalColor[Src], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
194 Context.TransitionResource(g_TemporalColor[Dst], D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
195 Context.TransitionResource(g_LinearDepth[Src], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
196 Context.TransitionResource(g_LinearDepth[Dst], D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
197 Context.SetDynamicDescriptor(1, 0, g_VelocityBuffer.GetSRV());
198 Context.SetDynamicDescriptor(1, 1, g_SceneColorBuffer.GetSRV());
199 Context.SetDynamicDescriptor(1, 2, g_TemporalColor[Src].GetSRV());
200 Context.SetDynamicDescriptor(1, 3, g_LinearDepth[Src].GetSRV());
201 Context.SetDynamicDescriptor(1, 4, g_LinearDepth[Dst].GetSRV());
202 Context.SetDynamicDescriptor(2, 0, g_TemporalColor[Dst].GetUAV());
204 Context.Dispatch2D(g_SceneColorBuffer.GetWidth(), g_SceneColorBuffer.GetHeight(), 16, 8);
207 void TemporalEffects::SharpenImage(ComputeContext& Context, ColorBuffer& TemporalColor)
209 ScopedTimer _prof(L"Sharpen or Copy Image", Context);
211 Context.TransitionResource(g_SceneColorBuffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
212 Context.TransitionResource(TemporalColor, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
214 Context.SetPipelineState(Sharpness >= 0.001f ? s_SharpenTAACS : s_ResolveTAACS);
215 Context.SetConstants(0, 1.0f + Sharpness, 0.25f * Sharpness);
216 Context.SetDynamicDescriptor(1, 0, TemporalColor.GetSRV());
217 Context.SetDynamicDescriptor(2, 0, g_SceneColorBuffer.GetUAV());
218 Context.Dispatch2D(g_SceneColorBuffer.GetWidth(), g_SceneColorBuffer.GetHeight());