diff --git a/Apps/App.Base/App.Base.vcxproj b/Apps/App.Base/App.Base.vcxproj
index c9c83e3..ae09fae 100644
--- a/Apps/App.Base/App.Base.vcxproj
+++ b/Apps/App.Base/App.Base.vcxproj
@@ -39,7 +39,6 @@
-
@@ -171,4 +170,4 @@
-
+
\ No newline at end of file
diff --git a/Apps/App.Base/App.Base.vcxproj.filters b/Apps/App.Base/App.Base.vcxproj.filters
index d6943b5..2791261 100644
--- a/Apps/App.Base/App.Base.vcxproj.filters
+++ b/Apps/App.Base/App.Base.vcxproj.filters
@@ -42,9 +42,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -117,4 +114,4 @@
Source Files\ECS
-
+
\ No newline at end of file
diff --git a/Apps/App.Base/Include/App.Base/ECS/Components/CameraComponent.h b/Apps/App.Base/Include/App.Base/ECS/Components/CameraComponent.h
index e28e780..251af57 100644
--- a/Apps/App.Base/Include/App.Base/ECS/Components/CameraComponent.h
+++ b/Apps/App.Base/Include/App.Base/ECS/Components/CameraComponent.h
@@ -2,18 +2,21 @@
#include "Engine.Core/ECS/Component.h"
#include
+#include "Engine.RendererDX12/D3DHelpers.h"
struct CameraComponent : ComponentTag
{
float FOV;
float NearPlane;
float FarPlane;
+ Matrix ViewProj;
+ Matrix PrevViewProjNoJitter;
bool DirtyFlag;
CameraComponent()
: DirtyFlag(true), _numFramesDirty(0), _CBufferIndex(0),
- FOV(60.0f), NearPlane(0.1f), FarPlane(10000.f)
+ FOV(60.0f), NearPlane(0.1f), FarPlane(10000.f), ViewProj(Identity4x4()), PrevViewProjNoJitter(Identity4x4())
{
}
diff --git a/Apps/App.Base/Include/App.Base/Modules/RenderModule.h b/Apps/App.Base/Include/App.Base/Modules/RenderModule.h
index 5cf3cad..bd7cc1b 100644
--- a/Apps/App.Base/Include/App.Base/Modules/RenderModule.h
+++ b/Apps/App.Base/Include/App.Base/Modules/RenderModule.h
@@ -2,23 +2,14 @@
#include "Common/GameTimer.h"
#include "Common/Module.h"
-#include "Engine.RendererDX12/D3DHelpers.h"
-#include "Engine.RendererDX12/GDX12Device.h"
-#include "Engine.RendererDX12/GDX12DescriptorHeap.h"
-#include "Engine.RendererDX12/GDX12FrameConstants.h"
-#include "Engine.RendererDX12/GDX12RootSignature.h"
-#include "Engine.RendererDX12/GDX12SwapChain.h"
-#include "Engine.RendererDX12/GDX12Texture.h"
-#include "Engine.RendererDX12/GDX12Material.h"
-#include "Engine.RendererDX12/GDX12GeometryBuffer.h"
-#include "Engine.RendererDX12/GDX12RenderCommandRecorder.h"
-
-#include "Engine.Core/Types/TextureTypes.h"
+
+#include "Engine.RendererDX12/RenderPasses/GDX12RenderPass.h"
#include "Engine.Core/ECS/Entity.h"
#include "Engine.Core/ECS/Event.h"
class SceneManagerModule;
class World;
+class GDX12SwapChain;
struct TransformComponent;
struct CameraComponent;
@@ -30,9 +21,10 @@ using namespace Engine::Core;
struct TransformCompGPUData
{
- UINT CBufferIndex;
- UINT NumFramesDirty;
- Matrix World;
+ UINT CBufferIndex = -1;
+ UINT NumFramesDirty = -1;
+ Matrix World = Identity4x4();
+ Matrix PrevWorld = Identity4x4();
};
class RenderModule final : public Module
@@ -44,19 +36,21 @@ class RenderModule final : public Module
void Initialize() override;
void Uninitialize() override;
- void OnResize() const;
+ void OnResize();
GDX12Material* GetMaterialByName(const std::string& name);
//returns a pointer to a fully initialized structure that you can specify in components
GDX12Material* CreateMaterial(const std::string& name);
- GDX12Texture* GetTextureByName(const std::string& name);
+ GPUTexture* GetTextureByName(const std::string& name);
//returns a pointer to a fully initialized structure that you can specify in materials
- GDX12Texture* CreateTexture(const std::string& name, const Texture* texture);
+ GPUTexture* CreateTexture(const std::string& name, const Texture* texture);
//Uploads Mesh geometry to GPU
void SubmitMesh(const Mesh* mesh, MeshHandle handle);
+
+ void SetActiveCamera(CameraComponent* camera);
struct WorldRenderSubscriptions
{
@@ -96,10 +90,18 @@ class RenderModule final : public Module
void OnRenderComponentUpdated(World& world, Entity entity, StaticMeshRenderComponent& component);
const float GetAspectRatio();
- GDX12RenderCommandRecorder* GetCommandRecorder();
- GDX12FrameConstants* GetCurrentFrameConstants();
- const GPUMesh* GetGPUMesh(MeshHandle handle);
- GDX12UploadBuffer* GetIndirectCommandsCache();
+ GDX12FrameConstants* GetCurrentPrimaryFrameConstants();
+ GDX12FrameConstants* GetCurrentSecondaryFrameConstants();
+ const GPUMesh* GetPrimaryGPUMesh(MeshHandle handle);
+ const GPUMesh* GetSecondaryGPUMesh(MeshHandle handle);
+ GDX12UploadBuffer* GetPrimaryIndirectCommandsCache();
+ GDX12UploadBuffer* GetSecondaryIndirectCommandsCache();
+
+ uint32_t GetPrimaryPipelineFlags();
+ uint32_t GetSecondaryPipelineFlags();
+ RenderPipelineCommonData* GetRenderPipelineCommonData();
+ bool PrimaryPipelineHasFlag(uint32_t flag);
+ bool SecondaryPipelineHasFlag(uint32_t flag);
protected:
void OnUpdate() override;
@@ -109,19 +111,18 @@ class RenderModule final : public Module
bool ShouldRender() override;
private:
- void BuildDescHeapsAndBackBuffer();
- void BuildRootSignatures();
- void BuildShaders();
- void BuildPSOs();
- void BuildFrameConstants();
-
- void UpdateMainCB();
- void UpdateMaterialCB();
+ void BuildBackBuffer();
+ void ShareFences();
+ void ConfigureRenderPipeline();
+ void SetupRenderPasses();
+ void InitializeRenderPasses();
void SubscribeToSceneManager();
void UnsubscribeFromSceneManager();
void UnsubscribeFromAllWorlds();
+ GDX12Texture* CreateDX12Texture(const std::string& name, GDX12DeviceResources* resources, const Texture* texture);
+
GameTimer* _timer;
Window* _window;
@@ -130,42 +131,27 @@ class RenderModule final : public Module
std::unordered_map _transformGPUData;
std::unordered_map _worldSubscriptions;
-
- GDX12RenderCommandRecorder _commandRecorder;
+ RenderPipelineCommonData _RPcommonData;
std::unique_ptr _primaryDevice;
std::unique_ptr _secondaryDevice;
bool _dualGPUMode;
- std::unordered_map> _inputLayouts;
+ GDX12DeviceResources _primaryResources;
+ GDX12DeviceResources _secondaryResources;
+ std::unordered_map> _textures;
std::unordered_map> _materials;
- // All of class members below should probably be put into DeviceResources class, and made for each device
- // Since all of these resources are currently existing on _primaryDevice only
- std::unique_ptr _geometryBuffer;
-
- // All heaps created in one high-capacity instance
- std::unique_ptr _rtvHeap;
- std::unique_ptr _srvuavHeap;
- std::unique_ptr _dsvHeap;
-
- std::vector> _frameConstants;
- UINT _currFrameConstantsIndex;
-
- std::unique_ptr> _IndirectCommandsCache;
-
- std::unordered_map> _shaders;
- std::unordered_map> _PSOs;
- std::unordered_map> _rootSignatures;
- std::unordered_map > _commandSignatures;
-
- std::unordered_map> _textures;
-
// These two resources are made on _primaryDevice only
std::unique_ptr _backBuffer;
std::unique_ptr _depthStencil;
-
- std::unique_ptr _opaqueAccumTexture;
- std::unique_ptr _transparencyAccumTexture;
- std::unique_ptr _transparencyRevealageTexture;
+
+ // Sorted in execution order
+ std::vector> _primaryRenderPassExecutionList;
+ std::vector> _secondaryRenderPassExecutionList;
+
+ // Flags that are accumulated from every active RenderPass on the device
+ // Defines which resources should be uploaded onto respective GPU
+ uint32_t _primaryPipelineFlags;
+ uint32_t _secondaryPipelineFlags;
};
\ No newline at end of file
diff --git a/Apps/App.Base/Include/App.Base/Systems/GPUDataUpdateSystem.h b/Apps/App.Base/Include/App.Base/Systems/GPUDataUpdateSystem.h
index 066e49c..fc1b204 100644
--- a/Apps/App.Base/Include/App.Base/Systems/GPUDataUpdateSystem.h
+++ b/Apps/App.Base/Include/App.Base/Systems/GPUDataUpdateSystem.h
@@ -25,6 +25,11 @@ class GPUDataUpdateSystem final : public System
ecs.ForEach(
[&ecs, &renderModule, &numFrames](Entity entity, TransformComponent& transform, CameraComponent& camera)
{
+ // Active camera requires constant update due to jittering
+ auto pipelineCommonData = renderModule->GetRenderPipelineCommonData();
+ bool isActiveCamera = pipelineCommonData->ActiveCameraCBufferIndex == camera._CBufferIndex;
+ if (isActiveCamera) { camera.DirtyFlag = true; }
+
if (camera.DirtyFlag || transform.DirtyFlag)
{
camera.DirtyFlag = false;
@@ -33,6 +38,8 @@ class GPUDataUpdateSystem final : public System
if (camera._numFramesDirty > 0)
{
+ GDX12CameraConstants objConstants;
+
Vector3 CameraLocation = transform.Location;
Vector3 CameraRotation = transform.Rotation;
float FOV = DirectX::XMConvertToRadians(camera.FOV);
@@ -49,21 +56,62 @@ class GPUDataUpdateSystem final : public System
Matrix view = Matrix::CreateLookAt(CameraLocation, CameraTarget, Vector3::Up);
//reserved-Z proj matrix
- Matrix proj = Matrix::CreatePerspectiveFieldOfView(FOV, renderModule->GetAspectRatio(),
+ Matrix proj = Matrix::CreatePerspectiveFieldOfView(FOV, renderModule->GetAspectRatio(),
camera.NearPlane, camera.FarPlane);
const float range = camera.NearPlane / (camera.FarPlane - camera.NearPlane);
proj._33 = range;
proj._43 = range * camera.FarPlane;
- GDX12CameraConstants objConstants;
+ Matrix unjitteredViewProj = view * proj;
+
+ XMStoreFloat4x4(&objConstants.ViewProjNoJitter, XMMatrixTranspose(unjitteredViewProj));
+ objConstants.PrevViewProjNoJitter = camera.PrevViewProjNoJitter;
+ XMStoreFloat4x4(&camera.PrevViewProjNoJitter, XMMatrixTranspose(unjitteredViewProj));
+
+
+ pipelineCommonData->CameraViewToClip = unjitteredViewProj;
+ pipelineCommonData->ClipToCameraView = pipelineCommonData->CameraViewToClip.Invert();
+
+ pipelineCommonData->ClipToPrevClip = unjitteredViewProj.Invert() * camera.PrevViewProjNoJitter;
+ pipelineCommonData->PrevClipToClip = pipelineCommonData->ClipToPrevClip.Invert();
+
+ // Jitter current camera proj matrix if it is needed
+ if (isActiveCamera &&
+ (renderModule->PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_JITTER) ||
+ renderModule->SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_JITTER)))
+ {
+ static uint32_t frameIndex = 0;
+ frameIndex++;
+
+ float jitterX = HaltonSequence(frameIndex, 2) - 0.5f;
+ float jitterY = HaltonSequence(frameIndex, 3) - 0.5f;
+ float inputWidth = static_cast(pipelineCommonData->DownscaledWidth);
+ float inputHeight = static_cast(pipelineCommonData->DownscaledHeight);
+ proj._31 += jitterX * 2.0f / inputWidth;
+ proj._32 -= jitterY * 2.0f / inputHeight;
+ pipelineCommonData->ActiveCameraJitterOffsetX = jitterX;
+ pipelineCommonData->ActiveCameraJitterOffsetY = jitterY;
+ }
+
+ camera.ViewProj = view * proj;
+
XMStoreFloat4x4(&objConstants.ViewProj, XMMatrixTranspose(view * proj));
XMStoreFloat4x4(&objConstants.View, XMMatrixTranspose(view));
objConstants.CameraLocation = transform.Location;
objConstants.NearPlane = camera.NearPlane;
objConstants.FarPlane = camera.FarPlane;
- auto& CBuffer = renderModule->GetCurrentFrameConstants()->CameraCB;
- CBuffer->CopyData(camera._CBufferIndex, objConstants);
+ if (renderModule->PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_CAMERAS))
+ {
+ auto& CBuffer = renderModule->GetCurrentPrimaryFrameConstants()->CameraCB;
+ CBuffer->CopyData(camera._CBufferIndex, objConstants);
+ }
+
+ if (renderModule->SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_CAMERAS))
+ {
+ auto& CBuffer = renderModule->GetCurrentSecondaryFrameConstants()->CameraCB;
+ CBuffer->CopyData(camera._CBufferIndex, objConstants);
+ }
camera._numFramesDirty--;
}
@@ -92,9 +140,20 @@ class GPUDataUpdateSystem final : public System
GDX12TransformConstants objConstants;
XMStoreFloat4x4(&objConstants.WorldMatrix, XMMatrixTranspose(world));
+ XMStoreFloat4x4(&objConstants.PrevWorldMatrix, XMMatrixTranspose(GPUData.PrevWorld));
- auto& CBuffer = renderModule->GetCurrentFrameConstants()->TransformCache;
- CBuffer->CopyData(GPUData.CBufferIndex, objConstants);
+ XMStoreFloat4x4(&GPUData.PrevWorld, world);
+
+ if (renderModule->PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ auto& CBuffer = renderModule->GetCurrentPrimaryFrameConstants()->TransformCache;
+ CBuffer->CopyData(GPUData.CBufferIndex, objConstants);
+ }
+ if (renderModule->SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ auto& CBuffer = renderModule->GetCurrentSecondaryFrameConstants()->TransformCache;
+ CBuffer->CopyData(GPUData.CBufferIndex, objConstants);
+ }
GPUData.NumFramesDirty--;
}
@@ -103,9 +162,6 @@ class GPUDataUpdateSystem final : public System
ecs.ForEach(
[&ecs, &renderModule, &numFrames](Entity entity, TransformComponent& transform, StaticMeshRenderComponent& renderer)
{
- auto& instanceCache = renderModule->GetCurrentFrameConstants()->InstanceCache;
- auto indirectCommandsCache = renderModule->GetIndirectCommandsCache();
- auto gpuMesh = renderModule->GetGPUMesh(renderer.MeshHandler);
auto& transformGPUData = renderModule->GetTransformGPUData(entity);
if (renderer.DirtyFlag || transform.DirtyFlag)
@@ -113,45 +169,113 @@ class GPUDataUpdateSystem final : public System
renderer.DirtyFlag = false;
renderer._numFramesDirty = numFrames;
- gpuMesh->CPUMesh->GetBounds().Transform(renderer.Bounds, XMLoadFloat4x4(&transformGPUData.World));
-
- for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ if (renderModule->GetPrimaryPipelineFlags() & RENDER_PASS_FLAG_USE_INSTANCES)
{
- const auto& subMesh = gpuMesh->SubMeshes[i];
-
- GDX12IndirectDrawArgs drawCommand;
- drawCommand.IndexCountPerInstance = subMesh.IndexCount;
- drawCommand.InstanceCount = 1;
- drawCommand.StartIndexLocation = subMesh.StartIndexLocation;
- drawCommand.BaseVertexLocation = subMesh.StartVertexLocation;
- drawCommand.StartInstanceLocation = renderer._CBufferIndices[i];
- drawCommand.InstanceID = renderer._CBufferIndices[i];
+ auto gpuMesh = renderModule->GetPrimaryGPUMesh(renderer.MeshHandler);
+ gpuMesh->CPUMesh->GetBounds().Transform(renderer.Bounds, XMLoadFloat4x4(&transformGPUData.World));
+ auto indirectCommandsCache = renderModule->GetPrimaryIndirectCommandsCache();
+ for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ {
+ const auto& subMesh = gpuMesh->SubMeshes[i];
+
+ GDX12IndirectDrawArgs drawCommand;
+ drawCommand.IndexCountPerInstance = subMesh.IndexCount;
+ drawCommand.InstanceCount = 1;
+ drawCommand.StartIndexLocation = subMesh.StartIndexLocation;
+ drawCommand.BaseVertexLocation = subMesh.StartVertexLocation;
+ drawCommand.StartInstanceLocation = renderer._CBufferIndices[i];
+ drawCommand.InstanceID = renderer._CBufferIndices[i];
+
+ indirectCommandsCache->CopyData(renderer._CBufferIndices[i], drawCommand);
+ }
+ }
- indirectCommandsCache->CopyData(renderer._CBufferIndices[i], drawCommand);
+ if (renderModule->SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ auto gpuMesh = renderModule->GetSecondaryGPUMesh(renderer.MeshHandler);
+ gpuMesh->CPUMesh->GetBounds().Transform(renderer.Bounds, XMLoadFloat4x4(&transformGPUData.World));
+ auto indirectCommandsCache = renderModule->GetSecondaryIndirectCommandsCache();
+ for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ {
+ const auto& subMesh = gpuMesh->SubMeshes[i];
+
+ GDX12IndirectDrawArgs drawCommand;
+ drawCommand.IndexCountPerInstance = subMesh.IndexCount;
+ drawCommand.InstanceCount = 1;
+ drawCommand.StartIndexLocation = subMesh.StartIndexLocation;
+ drawCommand.BaseVertexLocation = subMesh.StartVertexLocation;
+ drawCommand.StartInstanceLocation = renderer._CBufferIndices[i];
+ drawCommand.InstanceID = renderer._CBufferIndices[i];
+
+ indirectCommandsCache->CopyData(renderer._CBufferIndices[i], drawCommand);
+ }
}
}
if (renderer._numFramesDirty > 0)
{
- for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ if (renderModule->PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
{
- const auto& subMesh = gpuMesh->SubMeshes[i];
- const auto& subMeshBounds = gpuMesh->CPUMesh->GetSubMesh(i).Bounds;
-
- BoundingBox bounds;
- subMeshBounds.Transform(bounds, XMLoadFloat4x4(&transformGPUData.World));
-
- GDX12InstanceData instanceData;
- instanceData.TransformIndex = transformGPUData.CBufferIndex;
- instanceData.MaterialIndex = renderer.Materials[subMesh.MaterialIndex]->_CBufferIndex;
- instanceData.BoundingBoxCenter = bounds.Center;
- instanceData.BoundingBoxExtents = bounds.Extents;
-
- instanceCache->CopyData(renderer._CBufferIndices[i], instanceData);
+ auto& instanceCache = renderModule->GetCurrentPrimaryFrameConstants()->InstanceCache;
+ auto gpuMesh = renderModule->GetPrimaryGPUMesh(renderer.MeshHandler);
+ for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ {
+ const auto& subMesh = gpuMesh->SubMeshes[i];
+ const auto& subMeshBounds = gpuMesh->CPUMesh->GetSubMesh(i).Bounds;
+
+ BoundingBox bounds;
+ subMeshBounds.Transform(bounds, XMLoadFloat4x4(&transformGPUData.World));
+
+ GDX12InstanceData instanceData;
+ instanceData.TransformIndex = transformGPUData.CBufferIndex;
+ instanceData.MaterialIndex = renderer.Materials[subMesh.MaterialIndex]->_CBufferIndex;
+ instanceData.BoundingBoxCenter = bounds.Center;
+ instanceData.BoundingBoxExtents = bounds.Extents;
+
+ instanceCache->CopyData(renderer._CBufferIndices[i], instanceData);
+ }
}
+ if (renderModule->SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ auto& instanceCache = renderModule->GetCurrentSecondaryFrameConstants()->InstanceCache;
+ auto gpuMesh = renderModule->GetSecondaryGPUMesh(renderer.MeshHandler);
+ for (int i = 0; i < gpuMesh->SubMeshes.size(); i++)
+ {
+ const auto& subMesh = gpuMesh->SubMeshes[i];
+ const auto& subMeshBounds = gpuMesh->CPUMesh->GetSubMesh(i).Bounds;
+
+ BoundingBox bounds;
+ subMeshBounds.Transform(bounds, XMLoadFloat4x4(&transformGPUData.World));
+
+ GDX12InstanceData instanceData;
+ instanceData.TransformIndex = transformGPUData.CBufferIndex;
+ instanceData.MaterialIndex = renderer.Materials[subMesh.MaterialIndex]->_CBufferIndex;
+ instanceData.BoundingBoxCenter = bounds.Center;
+ instanceData.BoundingBoxExtents = bounds.Extents;
+
+ instanceCache->CopyData(renderer._CBufferIndices[i], instanceData);
+ }
+ }
+
renderer._numFramesDirty--;
}
});
}
+
+private:
+ static float HaltonSequence(uint32_t index, uint32_t base)
+ {
+ float f = 1.0f;
+ float result = 0.0f;
+
+ while (index > 0)
+ {
+ f /= static_cast(base);
+ result += f * static_cast(index % base);
+ index = static_cast(floorf(static_cast(index) / static_cast(base)));
+ }
+
+ return result;
+ }
};
diff --git a/Apps/App.Base/Include/App.Base/Systems/RenderSubmitSystem.h b/Apps/App.Base/Include/App.Base/Systems/RenderSubmitSystem.h
deleted file mode 100644
index 001d241..0000000
--- a/Apps/App.Base/Include/App.Base/Systems/RenderSubmitSystem.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include "Engine.Core/System.h"
-#include "App.Base/ECS/World.h"
-
-#include "Engine.Core/BenchmarkEngine.h"
-#include "App.Base/Modules/RenderModule.h"
-
-class RenderSubmitSystem final : public System
-{
-public:
- void Tick(World& world, float dt) override
- {
- WorldECS& ecs = world.GetECS();
- auto renderModule = BenchmarkEngine::GetLocator().GetModule();
-
- CameraComponent* activeCamera = &ecs.Get(world.ActiveCamera);
-
- auto commandRecorder = renderModule->GetCommandRecorder();
-
- commandRecorder->DrawFromCamera(activeCamera->_CBufferIndex);
- }
-};
diff --git a/Apps/App.Base/src/App.cpp b/Apps/App.Base/src/App.cpp
index ec8f6ab..dd382b4 100644
--- a/Apps/App.Base/src/App.cpp
+++ b/Apps/App.Base/src/App.cpp
@@ -3,6 +3,8 @@
#include
#include
+#include "Engine.RendererDX12/GDX12StreamlineSDK.h"
+
using Microsoft::WRL::ComPtr;
using namespace std;
using namespace DirectX;
@@ -60,7 +62,15 @@ App::App(HINSTANCE hInstance)
Instance = this;
}
-App::~App() = default;
+App::~App()
+{
+ //ordering is important
+ Locator.UnregisterModule();
+ Locator.UnregisterModule();
+ // can't be put into RenderModule since it is required
+ // to call it after all module entities are destroyed
+ GDX12StreamlineSDK::Get().Shutdown();
+}
HINSTANCE App::GetAppHandler() const
{
diff --git a/Apps/App.Base/src/ECS/WorldLoader.cpp b/Apps/App.Base/src/ECS/WorldLoader.cpp
index 3c336fe..9eaa8e2 100644
--- a/Apps/App.Base/src/ECS/WorldLoader.cpp
+++ b/Apps/App.Base/src/ECS/WorldLoader.cpp
@@ -154,7 +154,7 @@ namespace
}
/// Creates or retrieves a GPU texture backed by a generated solid-color CPU texture.
- GDX12Texture* CreateSolidGpuTexture(
+ GPUTexture* CreateSolidGpuTexture(
RenderModule& renderModule,
const std::string& textureName,
const std::uint8_t red,
@@ -165,7 +165,7 @@ namespace
{
Engine::Core::Texture texture = CreateSingleColorTexture(red, green, blue, alpha, textureType);
- GDX12Texture* gpuTexture = renderModule.CreateTexture(textureName, &texture);
+ GPUTexture* gpuTexture = renderModule.CreateTexture(textureName, &texture);
if (gpuTexture == nullptr)
{
gpuTexture = renderModule.GetTextureByName(textureName);
@@ -182,7 +182,7 @@ namespace
}
/// Creates or retrieves a generated diffuse texture from the imported material diffuse color.
- GDX12Texture* CreateDiffuseColorTexture(
+ GPUTexture* CreateDiffuseColorTexture(
RenderModule& renderModule,
const std::string& sceneName,
const Engine::Core::MeshMaterial& material)
@@ -198,9 +198,9 @@ namespace
struct SceneDefaultMaterialTextures
{
- GDX12Texture* FlatNormal = nullptr;
- GDX12Texture* White = nullptr;
- GDX12Texture* Black = nullptr;
+ GPUTexture* FlatNormal = nullptr;
+ GPUTexture* White = nullptr;
+ GPUTexture* Black = nullptr;
[[nodiscard]] bool IsValid() const
{
@@ -221,11 +221,11 @@ namespace
struct MaterialTextureSet
{
- GDX12Texture* Diffuse = nullptr;
- GDX12Texture* Normal = nullptr;
- GDX12Texture* Specular = nullptr;
- GDX12Texture* Roughness = nullptr;
- GDX12Texture* Emissive = nullptr;
+ GPUTexture* Diffuse = nullptr;
+ GPUTexture* Normal = nullptr;
+ GPUTexture* Specular = nullptr;
+ GPUTexture* Roughness = nullptr;
+ GPUTexture* Emissive = nullptr;
bool HasNormalMap = false;
bool HasSpecularMap = false;
bool HasRoughnessMap = false;
@@ -348,13 +348,13 @@ namespace
/// Loads a texture through AssetManager, creates the corresponding GPU texture and caches it by normalized path and semantic type.
/// Returns an already created GPU texture when the same source texture is requested again.
- GDX12Texture* LoadSceneGpuTexture(
+ GPUTexture* LoadSceneGpuTexture(
RenderModule& renderModule,
Engine::Core::AssetManager& assetManager,
const std::filesystem::path& texturePath,
const Engine::Core::ETextureType textureType,
const std::string& sceneName,
- std::unordered_map& gpuTexturesByPath)
+ std::unordered_map& gpuTexturesByPath)
{
if (texturePath.empty())
{
@@ -376,7 +376,7 @@ namespace
const std::string textureName = sceneName + "_Texture_" + std::to_string(gpuTexturesByPath.size());
const Engine::Core::Texture typedTexture = texture->WithType(textureType);
- GDX12Texture* gpuTexture = renderModule.CreateTexture(textureName, &typedTexture);
+ GPUTexture* gpuTexture = renderModule.CreateTexture(textureName, &typedTexture);
if (gpuTexture == nullptr)
{
gpuTexture = renderModule.GetTextureByName(textureName);
@@ -392,13 +392,13 @@ namespace
/// Loads a diffuse texture and packs an optional opacity mask into its alpha channel before GPU upload.
/// Falls back to the original diffuse texture if the opacity texture is missing or cannot be merged.
- GDX12Texture* LoadSceneDiffuseGpuTexture(
+ GPUTexture* LoadSceneDiffuseGpuTexture(
RenderModule& renderModule,
Engine::Core::AssetManager& assetManager,
const std::filesystem::path& diffuseTexturePath,
const std::filesystem::path& opacityTexturePath,
const std::string& sceneName,
- std::unordered_map& gpuTexturesByPath)
+ std::unordered_map& gpuTexturesByPath)
{
if (diffuseTexturePath.empty())
{
@@ -431,7 +431,7 @@ namespace
}
const std::string textureName = sceneName + "_Texture_" + std::to_string(gpuTexturesByPath.size());
- GDX12Texture* gpuTexture = renderModule.CreateTexture(textureName, mergedTexture.get());
+ GPUTexture* gpuTexture = renderModule.CreateTexture(textureName, mergedTexture.get());
if (gpuTexture == nullptr)
{
gpuTexture = renderModule.GetTextureByName(textureName);
@@ -461,7 +461,7 @@ namespace
const std::string textureName = sceneName + "_FallbackTexture";
const std::string materialName = sceneName + "_FallbackMaterial";
- GDX12Texture* gpuTexture = renderModule.CreateTexture(textureName, fallbackTexture);
+ GPUTexture* gpuTexture = renderModule.CreateTexture(textureName, fallbackTexture);
if (gpuTexture == nullptr)
{
gpuTexture = renderModule.GetTextureByName(textureName);
@@ -566,7 +566,7 @@ namespace
const std::string& sceneName,
GDX12Material* fallbackMaterial,
const SceneDefaultMaterialTextures& defaultTextures,
- std::unordered_map& gpuTexturesByPath)
+ std::unordered_map& gpuTexturesByPath)
{
std::vector materialSlots = BuildFallbackMaterialSlots(mesh, fallbackMaterial);
const std::vector& materials = mesh.GetMaterials();
@@ -598,28 +598,28 @@ namespace
textures.Roughness = defaultTextures.White;
textures.Emissive = defaultTextures.Black;
- GDX12Texture* normalTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].NormalTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
+ GPUTexture* normalTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].NormalTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
if (normalTexture != nullptr)
{
textures.Normal = normalTexture;
textures.HasNormalMap = true;
}
- GDX12Texture* specularTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].SpecularTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
+ GPUTexture* specularTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].SpecularTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
if (specularTexture != nullptr)
{
textures.Specular = specularTexture;
textures.HasSpecularMap = true;
}
- GDX12Texture* roughnessTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].RoughnessTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
+ GPUTexture* roughnessTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].RoughnessTexturePath, Engine::Core::ETextureType::Data, sceneName, gpuTexturesByPath);
if (roughnessTexture != nullptr)
{
textures.Roughness = roughnessTexture;
textures.HasRoughnessMap = true;
}
- GDX12Texture* emissiveTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].EmissiveTexturePath, Engine::Core::ETextureType::Color, sceneName, gpuTexturesByPath);
+ GPUTexture* emissiveTexture = LoadSceneGpuTexture(renderModule, assetManager, materials[materialIndex].EmissiveTexturePath, Engine::Core::ETextureType::Color, sceneName, gpuTexturesByPath);
if (emissiveTexture != nullptr)
{
textures.Emissive = emissiveTexture;
@@ -649,7 +649,7 @@ namespace
Engine::Core::AssetManager& assetManager,
const std::filesystem::path& objPath,
const std::string& sceneName,
- std::unordered_map& gpuTexturesByPath,
+ std::unordered_map& gpuTexturesByPath,
DirectX::BoundingBox& outBounds)
{
Engine::Core::MeshHandle sceneMeshHandle = {};
@@ -748,7 +748,7 @@ namespace
bool loadedAnyObject = false;
DirectX::BoundingBox sceneBounds = {};
- std::unordered_map gpuTexturesByPath;
+ std::unordered_map gpuTexturesByPath;
for (const std::filesystem::path& objPath : objPaths)
{
@@ -808,7 +808,7 @@ bool WorldLoader::LoadFromFile(World& world, const std::filesystem::path& path)
if (IsObjPath(path))
{
DirectX::BoundingBox sceneBounds = {};
- std::unordered_map gpuTexturesByPath;
+ std::unordered_map gpuTexturesByPath;
if (!LoadObjSceneEntity(
world,
*renderModule,
@@ -1048,6 +1048,7 @@ bool WorldLoader::LoadFromFile(World& world, const std::filesystem::path& path)
);
world.ActiveCamera = camera;
+ renderModule->SetActiveCamera(&camera.GetComponent());
return true;
}
diff --git a/Apps/App.Base/src/RenderModule.cpp b/Apps/App.Base/src/RenderModule.cpp
index 50f4331..8271d05 100644
--- a/Apps/App.Base/src/RenderModule.cpp
+++ b/Apps/App.Base/src/RenderModule.cpp
@@ -2,53 +2,50 @@
#include "App.Base/Window.h"
#include "App.Base/App.h"
-#include "Common/ConsoleVariables.h"
-#include "Engine.RendererDX12/GDX12CommandList.h"
-#include "Engine.RendererDX12/GDX12CommandQueue.h"
-#include "Engine.RendererDX12/GDX12DeviceFactory.h"
-#include "Engine.RendererDX12/GDX12ShaderCompiler.h"
-#include "Engine.RendererDX12/GDX12TextureResource.h"
-#include "Engine.RendererDX12/GDX12Descriptor.h"
-#include "App.Base/Modules/SceneManagerModule.h"
-
-static UINT _numFrameConstants = 3;
-static AutoConsoleVariableRef NumFrameConstantVariable(
- L"Render.NumFrames",
- _numFrameConstants,
- L"How many deferred frames was rendered");
+#include "App.Base/Modules/SceneManagerModule.h"
+#include "Common/ConsoleVariables.h"
-namespace
-{
- ETextureSemantic ConvertTextureSemantic(const Engine::Core::ETextureType textureType)
- {
- switch (textureType)
- {
- case Engine::Core::ETextureType::Color:
- return ETextureSemantic::Color;
- case Engine::Core::ETextureType::Data:
- return ETextureSemantic::Data;
- default:
- return ETextureSemantic::Unknown;
- }
- }
-}
+#include "Engine.RendererDX12/GDX12SwapChain.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12TextureClearPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12GPUCullingPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12OpaquePass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12WBOITTransparencyPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12WBOITCompositionPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12TextureCopyFromSharedMemoryPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12TextureCopyToSharedMemoryPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12OutputToScreenPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12FSRUpscalePass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12SyncPass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12XeSSUpscalePass.h"
+#include "Engine.RendererDX12/RenderPasses/GDX12DLSSUpscalePass.h"
RenderModule::RenderModule(Window* window, GameTimer* timer) :
- _dualGPUMode(false), _window(window),
- _currFrameConstantsIndex(0), _timer(timer)
+ _dualGPUMode(false), _window(window), _timer(timer),
+ _primaryPipelineFlags(0), _secondaryPipelineFlags(0)
{
+ _RPcommonData.GameTimer = _timer;
}
RenderModule::~RenderModule()
{
_primaryDevice->GetCommandQueue()->Flush();
+ if (_dualGPUMode) { _secondaryDevice->GetCommandQueue()->Flush(); }
+
+ for (auto& renderpass : _primaryRenderPassExecutionList) { renderpass->ClearDenendencies(); }
+ for (auto& renderpass : _secondaryRenderPassExecutionList) { renderpass->ClearDenendencies(); }
GDX12ShaderCompiler::Shutdown();
+ GDX12DeviceFactory::Reset();
}
void RenderModule::Initialize()
{
+ // This value will be later provided by external pipeline config
+ bool useStreamlineSDK = false;
+ // Streamline is initialized on the primary device only
+ if (useStreamlineSDK) { GDX12StreamlineSDK::Get().Initialize(); }
+
#if defined(DEBUG) || defined(_DEBUG)
// Enable the D3D12 debug layer.
ComPtr debugController;
@@ -57,32 +54,23 @@ void RenderModule::Initialize()
#endif
_primaryDevice = std::make_unique();
+ _primaryDevice->Role = DEVICE_ROLE_PRIMARY;
_primaryDevice->Initialize(GDX12DeviceFactory::GetMostPerformantAdapter().Get());
+ _primaryResources.Initialize(_primaryDevice.get());
- // TODO: Add find other adapter and use cvar
- // if (secondaryDeviceAdapter)
- // {
- // _secondaryDevice = std::make_unique();
- // _secondaryDevice->Initialize(secondaryDeviceAdapter.Get());
- //
- // _dualGPUMode = true;
- // }
-
- _inputLayouts["Default"] =
+ if (false)
{
- { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
- { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
- { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
- { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
- };
-
- BuildDescHeapsAndBackBuffer();
- BuildRootSignatures();
- BuildShaders();
- BuildPSOs();
- BuildFrameConstants();
-
- _geometryBuffer = std::make_unique(_primaryDevice.get());
+ _secondaryDevice = std::make_unique();
+ _secondaryDevice->Role = DEVICE_ROLE_SECONDARY;
+ _secondaryDevice->Initialize(GDX12DeviceFactory::GetDeviceDescriptors()[1].Adapter.Get());
+ _secondaryResources.Initialize(_secondaryDevice.get());
+ _dualGPUMode = true;
+ }
+
+ BuildBackBuffer();
+ if (_dualGPUMode) { ShareFences(); }
+ ConfigureRenderPipeline();
+
SubscribeToSceneManager();
}
@@ -91,7 +79,7 @@ void RenderModule::Uninitialize()
UnsubscribeFromSceneManager();
}
-void RenderModule::OnResize() const
+void RenderModule::OnResize()
{
_primaryDevice->GetCommandQueue()->Flush();
@@ -101,9 +89,12 @@ void RenderModule::OnResize() const
_backBuffer->Resize(width, height);
_depthStencil->Resize(width, height);
- _opaqueAccumTexture->Resize(width, height);
- _transparencyAccumTexture->Resize(width, height);
- _transparencyRevealageTexture->Resize(width, height);
+ _RPcommonData.WindowWidth = width;
+ _RPcommonData.WindowHeight = height;
+ if (_RPcommonData.Upscaler) { _RPcommonData.Upscaler->QueryRenderTargetResolution(); }
+
+ for (auto& renderPass : _primaryRenderPassExecutionList) { renderPass->Resize(); }
+ for (auto& renderPass : _secondaryRenderPassExecutionList) { renderPass->Resize(); }
}
GDX12Material* RenderModule::GetMaterialByName(const std::string& name)
@@ -128,18 +119,32 @@ GDX12Material* RenderModule::CreateMaterial(const std::string& name)
_materials[name] = std::unique_ptr(new GDX12Material());
_materials[name]->Name = name;
- _materials[name]->_CBufferIndex = _frameConstants[0]->MaterialCache->GetElementCount();
+
+ if (_primaryPipelineFlags & RENDER_PASS_FLAG_USE_MATERIALS)
+ {
+ _materials[name]->_CBufferIndex = _primaryResources.FrameConstants[0]->MaterialCache->GetElementCount();
- for (auto& constants : _frameConstants)
+ for (auto& constants : _primaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->MaterialCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ }
+ }
+ if (_secondaryPipelineFlags & RENDER_PASS_FLAG_USE_MATERIALS)
{
- auto& CBuffer = constants->MaterialCache;
- CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ _materials[name]->_CBufferIndex = _secondaryResources.FrameConstants[0]->MaterialCache->GetElementCount();
+
+ for (auto& constants : _secondaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->MaterialCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ }
}
return _materials[name].get();
}
-GDX12Texture* RenderModule::GetTextureByName(const std::string& name)
+GPUTexture* RenderModule::GetTextureByName(const std::string& name)
{
auto it = _textures.find(name);
if (it != _textures.end()) { return it->second.get(); }
@@ -149,17 +154,29 @@ GDX12Texture* RenderModule::GetTextureByName(const std::string& name)
return nullptr;
}
-GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture* texture)
+GPUTexture* RenderModule::CreateTexture(const std::string& name, const Texture* texture)
{
if (_textures.find(name) != _textures.end())
{
- std::string errorMsg = "ERROR: Texture with name " + name + " already exists in Textures directory.\n";
+ std::string errorMsg = "WARNING: Texture with name " + name + " already exists in Textures directory. Texture creation Skipped\n";
OutputDebugStringA(errorMsg.c_str());
return nullptr;
}
+ _textures[name] = std::make_unique();
+ _textures[name]->Name = name;
+ if (_primaryPipelineFlags & RENDER_PASS_FLAG_USE_MATERIALS)
+ { _textures[name]->PrimaryDeviceTexture = CreateDX12Texture(name, &_primaryResources, texture); }
+ if (_secondaryPipelineFlags & RENDER_PASS_FLAG_USE_MATERIALS)
+ { _textures[name]->SecondaryDeviceTexture = CreateDX12Texture(name, &_secondaryResources, texture); }
+
+ return _textures[name].get();
+}
+
+GDX12Texture* RenderModule::CreateDX12Texture(const std::string& name, GDX12DeviceResources* resources, const Texture* texture)
+{
GDX12TextureDesc desc;
- desc.SRV_UAV_Heap = _srvuavHeap.get();
+ desc.SRV_UAV_Heap = resources->SRV_UAV_Heap.get();
desc.Format = desc.SRVDesc.Format = texture->GetFormat();
desc.Semantic = ConvertTextureSemantic(texture->GetType());
desc.Width = texture->GetWidth();
@@ -185,7 +202,7 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
desc.SRVDesc.TextureCube.MipLevels = numMipLevels;
desc.SRVDesc.TextureCube.MostDetailedMip = 0;
desc.SRVDesc.TextureCube.ResourceMinLODClamp = 0.0f;
- desc.SRVHeapIndex = _srvuavHeap->GetAvailableIndex(TextureCube_StartIndex, TextureCube_RangeLength);
+ desc.SRVHeapIndex = resources->SRV_UAV_Heap->GetAvailableIndex(TextureCube_StartIndex, TextureCube_RangeLength);
auto texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
desc.Format, desc.Width, desc.Height,
@@ -194,7 +211,7 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
D3D12_TEXTURE_LAYOUT_UNKNOWN,
D3D12_RESOURCE_DIMENSION_TEXTURE2D);
- _primaryDevice->GetDevice()->CreateCommittedResource(
+ resources->Device->GetDevice()->CreateCommittedResource(
&defaultHeap,
D3D12_HEAP_FLAG_NONE,
&texDesc,
@@ -210,13 +227,13 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
desc.SRVDesc.Texture2D.MostDetailedMip = 0;
desc.SRVDesc.Texture2D.PlaneSlice = 0;
desc.SRVDesc.Texture2D.ResourceMinLODClamp = 0.0f;
- desc.SRVHeapIndex = _srvuavHeap->GetAvailableIndex(Texture2D_StartIndex, Texture2D_RangeLength);
+ desc.SRVHeapIndex = resources->SRV_UAV_Heap->GetAvailableIndex(Texture2D_StartIndex, Texture2D_RangeLength);
auto texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
desc.Format, desc.Width, desc.Height,
numArraySlices, numMipLevels);
- _primaryDevice->GetDevice()->CreateCommittedResource(
+ resources->Device->GetDevice()->CreateCommittedResource(
&defaultHeap,
D3D12_HEAP_FLAG_NONE,
&texDesc,
@@ -234,14 +251,14 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
std::vector rowSizes(totalSubresources);
auto texDesc = textureResource->GetDesc();
- _primaryDevice->GetDevice()->GetCopyableFootprints(
+ resources->Device->GetDevice()->GetCopyableFootprints(
&texDesc, 0, totalSubresources,
0, footprints.data(), rowCounts.data(), rowSizes.data(), &totalSize);
auto uploadDesc = CD3DX12_RESOURCE_DESC::Buffer(totalSize);
ComPtr uploadBuffer;
- _primaryDevice->GetDevice()->CreateCommittedResource(
+ resources->Device->GetDevice()->CreateCommittedResource(
&uploadHeap,
D3D12_HEAP_FLAG_NONE,
&uploadDesc,
@@ -274,7 +291,7 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
}
uploadBuffer->Unmap(0, nullptr);
- auto cmdQueue = _primaryDevice->GetCommandQueue();
+ auto cmdQueue = resources->Device->GetCommandQueue();
auto cmdList = cmdQueue->GetCommandList();
for (uint32_t arraySlice = 0; arraySlice < numArraySlices; arraySlice++)
@@ -309,14 +326,26 @@ GDX12Texture* RenderModule::CreateTexture(const std::string& name, const Texture
desc.ExternalResource = textureResource;
- _textures[name] = std::make_unique(desc);
+ resources->Textures[name] = std::make_unique();
+ resources->Textures[name]->Initialize(desc);
- return _textures[name].get();
+ return resources->Textures[name].get();
}
void RenderModule::SubmitMesh(const Mesh* mesh, MeshHandle handle)
{
- _geometryBuffer->AddMesh(mesh, handle);
+ if (_primaryPipelineFlags & RENDER_PASS_FLAG_USE_GEOMETRY)
+ { _primaryResources.GeometryBuffer->AddMesh(mesh, handle); }
+ if (_secondaryPipelineFlags & RENDER_PASS_FLAG_USE_GEOMETRY)
+ { _secondaryResources.GeometryBuffer->AddMesh(mesh, handle); }
+}
+
+void RenderModule::SetActiveCamera(CameraComponent* camera)
+{
+ _RPcommonData.ActiveCameraCBufferIndex = camera->_CBufferIndex;
+ _RPcommonData.ActiveCameraFOV = camera->FOV;
+ _RPcommonData.ActiveCameraNearPlane = camera->NearPlane;
+ _RPcommonData.ActiveCameraFarPlane = camera->FarPlane;
}
TransformCompGPUData& RenderModule::GetTransformGPUData(Entity entity)
@@ -431,31 +460,84 @@ void RenderModule::UnsubscribeFromWorld(World& world)
_worldSubscriptions.erase(it);
}
-GDX12FrameConstants* RenderModule::GetCurrentFrameConstants()
+GDX12FrameConstants* RenderModule::GetCurrentPrimaryFrameConstants()
{
- return _frameConstants[_currFrameConstantsIndex].get();
+ return _primaryResources.FrameConstants[_primaryResources.CurrFrameConstantsIndex].get();
}
-const GPUMesh* RenderModule::GetGPUMesh(MeshHandle handle)
+GDX12FrameConstants* RenderModule::GetCurrentSecondaryFrameConstants()
{
- return _geometryBuffer->GetGPUMeshByHandle(handle);
+ return _secondaryResources.FrameConstants[_secondaryResources.CurrFrameConstantsIndex].get();
}
-GDX12UploadBuffer* RenderModule::GetIndirectCommandsCache()
+const GPUMesh* RenderModule::GetPrimaryGPUMesh(MeshHandle handle)
{
- return _IndirectCommandsCache.get();
+ return _primaryResources.GeometryBuffer->GetGPUMeshByHandle(handle);
+}
+
+const GPUMesh* RenderModule::GetSecondaryGPUMesh(MeshHandle handle)
+{
+ return _secondaryResources.GeometryBuffer->GetGPUMeshByHandle(handle);
+}
+
+GDX12UploadBuffer* RenderModule::GetPrimaryIndirectCommandsCache()
+{
+ return _primaryResources.IndirectCommandsCache.get();
+}
+
+GDX12UploadBuffer* RenderModule::GetSecondaryIndirectCommandsCache()
+{
+ return _secondaryResources.IndirectCommandsCache.get();
+}
+
+uint32_t RenderModule::GetPrimaryPipelineFlags()
+{
+ return _primaryPipelineFlags;
+}
+
+uint32_t RenderModule::GetSecondaryPipelineFlags()
+{
+ return _secondaryPipelineFlags;
+}
+
+RenderPipelineCommonData* RenderModule::GetRenderPipelineCommonData()
+{
+ return &_RPcommonData;
+}
+
+bool RenderModule::PrimaryPipelineHasFlag(uint32_t flag)
+{
+ return _primaryPipelineFlags & flag;
+}
+
+bool RenderModule::SecondaryPipelineHasFlag(uint32_t flag)
+{
+ return _secondaryPipelineFlags & flag;
}
void RenderModule::OnTransformComponentCreated(World& world, Entity entity, TransformComponent& component)
{
TransformCompGPUData gpuData;
- gpuData.CBufferIndex = _frameConstants[0]->TransformCache->GetElementCount();
_transformGPUData[entity] = gpuData;
- for (auto& constants : _frameConstants)
+ if (PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ _transformGPUData[entity].CBufferIndex = _primaryResources.FrameConstants[0]->TransformCache->GetElementCount();
+ for (auto& constants : _primaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->TransformCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ }
+ }
+
+ if (SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
{
- auto& CBuffer = constants->TransformCache;
- CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ _transformGPUData[entity].CBufferIndex = _secondaryResources.FrameConstants[0]->TransformCache->GetElementCount();
+ for (auto& constants : _secondaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->TransformCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ }
}
}
@@ -470,13 +552,54 @@ void RenderModule::OnTransformComponentUpdated(World& world, Entity entity, Tran
void RenderModule::OnCameraComponentCreated(World& world, Entity entity, CameraComponent& component)
{
- component._CBufferIndex = _frameConstants[0]->CameraCB->GetElementCount();
+ if (PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_CAMERAS))
+ {
+ component._CBufferIndex = _primaryResources.FrameConstants[0]->CameraCB->GetElementCount();
+
+ for (auto& constants : _primaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->CameraCB;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
- for (auto& constants : _frameConstants)
+ constants->CameraVisibilityCommands.push_back(GDX12VisibilityBuffers());
+
+ auto& buffers = constants->CameraVisibilityCommands[component._CBufferIndex];
+ buffers.VisibleOpaqueCommandsCache = std::make_unique>(_primaryDevice.get(), GetPrimaryIndirectCommandsCache()->GetElementCount(), EBufferType::Default, false);
+ buffers.OpaqueDrawCounter = std::make_unique>(_primaryDevice.get(), 1, EBufferType::Default, false);
+ buffers.VisibleTransparentCommandsCache = std::make_unique>(_primaryDevice.get(), GetPrimaryIndirectCommandsCache()->GetElementCount(), EBufferType::Default, false);
+ buffers.TransparentDrawCounter = std::make_unique>(_primaryDevice.get(), 1, EBufferType::Default, false);
+
+ buffers.VisibleOpaqueCommandsCache->CreateUAV(_primaryResources.SRV_UAV_Heap.get(), _primaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.OpaqueDrawCounter->CreateUAV(_primaryResources.SRV_UAV_Heap.get(), _primaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.VisibleTransparentCommandsCache->CreateUAV(_primaryResources.SRV_UAV_Heap.get(), _primaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.TransparentDrawCounter->CreateUAV(_primaryResources.SRV_UAV_Heap.get(), _primaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ }
+ }
+
+ if (SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_CAMERAS))
{
- auto& CBuffer = constants->CameraCB;
- CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ component._CBufferIndex = _secondaryResources.FrameConstants[0]->CameraCB->GetElementCount();
+
+ for (auto& constants : _secondaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->CameraCB;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+
+ constants->CameraVisibilityCommands.push_back(GDX12VisibilityBuffers());
+
+ auto& buffers = constants->CameraVisibilityCommands[component._CBufferIndex];
+ buffers.VisibleOpaqueCommandsCache = std::make_unique>(_secondaryDevice.get(), GetSecondaryIndirectCommandsCache()->GetElementCount(), EBufferType::Default, false);
+ buffers.OpaqueDrawCounter = std::make_unique>(_secondaryDevice.get(), 1, EBufferType::Default, false);
+ buffers.VisibleTransparentCommandsCache = std::make_unique>(_secondaryDevice.get(), GetSecondaryIndirectCommandsCache()->GetElementCount(), EBufferType::Default, false);
+ buffers.TransparentDrawCounter = std::make_unique>(_secondaryDevice.get(), 1, EBufferType::Default, false);
+
+ buffers.VisibleOpaqueCommandsCache->CreateUAV(_secondaryResources.SRV_UAV_Heap.get(), _secondaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.OpaqueDrawCounter->CreateUAV(_secondaryResources.SRV_UAV_Heap.get(), _secondaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.VisibleTransparentCommandsCache->CreateUAV(_secondaryResources.SRV_UAV_Heap.get(), _secondaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ buffers.TransparentDrawCounter->CreateUAV(_secondaryResources.SRV_UAV_Heap.get(), _secondaryResources.SRV_UAV_Heap->GetAvailableIndex(ConstantsResources));
+ }
}
+
}
void RenderModule::OnCameraComponentDestroyed(World& world, Entity entity, CameraComponent& component)
@@ -489,21 +612,48 @@ void RenderModule::OnCameraComponentUpdated(World& world, Entity entity, CameraC
void RenderModule::OnRenderComponentCreated(World& world, Entity entity, StaticMeshRenderComponent& component)
{
- auto& MeshGPUData = _geometryBuffer->_meshCache[component.MeshHandler.GetValue()];
-
- for (int i = 0; i < MeshGPUData->SubMeshes.size(); i++)
+ if (PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
{
- component._CBufferIndices.push_back(_frameConstants[0]->InstanceCache->GetElementCount());
- _IndirectCommandsCache->Resize(_IndirectCommandsCache->GetElementCount() + 1);
-
- for (auto& constants : _frameConstants)
+ auto& MeshGPUData = _primaryResources.GeometryBuffer->_meshCache[component.MeshHandler.GetValue()];
+ for (int i = 0; i < MeshGPUData->SubMeshes.size(); i++)
{
- auto& CBuffer = constants->InstanceCache;
- CBuffer->Resize(CBuffer->GetElementCount() + 1);
- constants->VisibleOpaqueCommandsCache->Resize(constants->VisibleOpaqueCommandsCache->GetElementCount() + 1);
- constants->VisibleTransparentCommandsCache->Resize(constants->VisibleTransparentCommandsCache->GetElementCount() + 1);
+ component._CBufferIndices.push_back(_primaryResources.FrameConstants[0]->InstanceCache->GetElementCount());
+ _primaryResources.IndirectCommandsCache->Resize(_primaryResources.IndirectCommandsCache->GetElementCount() + 1);
+
+ for (auto& constants : _primaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->InstanceCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+
+ for (auto& buffers : constants->CameraVisibilityCommands)
+ {
+ buffers.VisibleOpaqueCommandsCache->Resize(buffers.VisibleOpaqueCommandsCache->GetElementCount() + 1);
+ buffers.VisibleTransparentCommandsCache->Resize(buffers.VisibleTransparentCommandsCache->GetElementCount() + 1);
+ }
+ }
}
+ }
+
+ if (SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_INSTANCES))
+ {
+ auto& MeshGPUData = _secondaryResources.GeometryBuffer->_meshCache[component.MeshHandler.GetValue()];
+ for (int i = 0; i < MeshGPUData->SubMeshes.size(); i++)
+ {
+ component._CBufferIndices.push_back(_secondaryResources.FrameConstants[0]->InstanceCache->GetElementCount());
+ _secondaryResources.IndirectCommandsCache->Resize(_secondaryResources.IndirectCommandsCache->GetElementCount() + 1);
+
+ for (auto& constants : _secondaryResources.FrameConstants)
+ {
+ auto& CBuffer = constants->InstanceCache;
+ CBuffer->Resize(CBuffer->GetElementCount() + 1);
+ for (auto& buffers : constants->CameraVisibilityCommands)
+ {
+ buffers.VisibleOpaqueCommandsCache->Resize(buffers.VisibleOpaqueCommandsCache->GetElementCount() + 1);
+ buffers.VisibleTransparentCommandsCache->Resize(buffers.VisibleTransparentCommandsCache->GetElementCount() + 1);
+ }
+ }
+ }
}
}
@@ -520,186 +670,104 @@ const float RenderModule::GetAspectRatio()
return _window->GetAspectRatio();
}
-GDX12RenderCommandRecorder* RenderModule::GetCommandRecorder()
-{
- return &_commandRecorder;
-}
-
void RenderModule::OnUpdate()
{
- _currFrameConstantsIndex = (_currFrameConstantsIndex + 1) % NumFrameConstantVariable.GetValue();
+ uint16_t width, height;
+ _window->GetWindowSize(width, height);
+
+ auto consoleModule = BenchmarkEngine::GetLocator().GetModule();
+ IConsoleVariable* ICVNumframes;
+ consoleModule->TryFindConsoleVariable(L"Render.NumFrames", ICVNumframes);
+ int numFrames = ICVNumframes->GetInt();
+
+ //sync & update Primary Device
+ _primaryResources.CurrFrameConstantsIndex = (_primaryResources.CurrFrameConstantsIndex + 1) % numFrames;
auto cmdQueue = _primaryDevice->GetCommandQueue();
- auto& frameConsts = _frameConstants[_currFrameConstantsIndex];
+ auto& frameConsts = _primaryResources.FrameConstants[_primaryResources.CurrFrameConstantsIndex];
if (frameConsts->FenceValue > cmdQueue->GetFence()->GetCompletedValue())
{
- cmdQueue->WaitForFenceValue(frameConsts->FenceValue);
+ cmdQueue->CPUWaitForFenceValue(frameConsts->FenceValue);
}
- UpdateMainCB();
- UpdateMaterialCB();
+ _primaryResources.UpdateMainCB(width, height, _timer);
+ if (PrimaryPipelineHasFlag(RENDER_PASS_FLAG_USE_MATERIALS))
+ { _primaryResources.UpdateMaterialCB(_materials); }
+
+ // same for SecondaryDevice
+ if (_dualGPUMode)
+ {
+ _secondaryResources.CurrFrameConstantsIndex = (_secondaryResources.CurrFrameConstantsIndex + 1) % numFrames;
+
+ auto cmdQueue = _secondaryDevice->GetCommandQueue();
+ auto& frameConsts = _secondaryResources.FrameConstants[_secondaryResources.CurrFrameConstantsIndex];
+
+ if (frameConsts->FenceValue > cmdQueue->GetFence()->GetCompletedValue())
+ {
+ cmdQueue->CPUWaitForFenceValue(frameConsts->FenceValue);
+ }
+
+ _secondaryResources.UpdateMainCB(width, height, _timer);
+ if (SecondaryPipelineHasFlag(RENDER_PASS_FLAG_USE_MATERIALS))
+ { _secondaryResources.UpdateMaterialCB(_materials); }
+ }
}
void RenderModule::OnRender()
{
- auto cmdQueue = _primaryDevice->GetCommandQueue();
-
- cmdQueue->Flush();
-
- auto cmdList = cmdQueue->GetCommandList();
- auto CurrentBackBuffer = _backBuffer->GetCurrentBuffer();
- auto& CurrentFrameConsts = _frameConstants[_currFrameConstantsIndex];
-
- cmdList->BeginPixEvent("Clear Back Buffer", Colors::Aqua);
- cmdList->SetViewport(_backBuffer->GetViewport());
- cmdList->SetScissorRect(_backBuffer->GetScissorRect());
- cmdList->EnhancedTextureBarrier({ CurrentBackBuffer->GetResource()->GetRenderTargetEnhBarrier() });
- cmdList->ResourceBarrier({ _depthStencil->GetResource()->GetDepthWriteBarrier() });
- cmdList->SetRenderTargets({ CurrentBackBuffer }, _depthStencil.get());
- cmdList->ClearRenderTargetView(CurrentBackBuffer);
- cmdList->ClearDepthStencilView(_depthStencil.get());
- cmdList->EndPixEvent();
-
- cmdList->BeginPixEvent("GPU Mesh Culling", Colors::Blue);
-
- cmdList->ResourceBarrier({
- CurrentFrameConsts->VisibleOpaqueCommandsCache->GetResource().GetUnorderedAccessBarrier(),
- CurrentFrameConsts->OpaqueDrawCounter->GetResource().GetUnorderedAccessBarrier(),
- CurrentFrameConsts->VisibleTransparentCommandsCache->GetResource().GetUnorderedAccessBarrier(),
- CurrentFrameConsts->TransparentDrawCounter->GetResource().GetUnorderedAccessBarrier() });
-
- cmdList->SetComputeRootSignature(_rootSignatures["BufferClear"].get());
- cmdList->SetPipelineState(_PSOs["BufferClear"]);
- cmdList->SetDescriptorHeaps({ _srvuavHeap.get() });
- //should probably make this into a foreach or clear multiple counters per dispatch
- cmdList->SetComputeUAV(0, CurrentFrameConsts->OpaqueDrawCounter->GetUAV()->GPUHandle);
- cmdList->Dispatch(1, 1, 1);
- cmdList->SetComputeUAV(0, CurrentFrameConsts->TransparentDrawCounter->GetUAV()->GPUHandle);
- cmdList->Dispatch(1, 1, 1);
-
- cmdList->SetComputeRootSignature(_rootSignatures["Culling"].get());
- cmdList->SetPipelineState(_PSOs["Culling"]);
- cmdList->SetDescriptorHeaps({ _srvuavHeap.get() });
- cmdList->SetComputeRootConstantBufferView(0, CurrentFrameConsts->CameraCB->
- GetElementAddress(_commandRecorder._cameraCBIndex));
- cmdList->SetComputeSRV(0, CurrentFrameConsts->InstanceCache->GetSRV()->GPUHandle);
- cmdList->SetComputeSRV(1, _IndirectCommandsCache->GetSRV()->GPUHandle);
- cmdList->SetComputeSRV(2, CurrentFrameConsts->MaterialCache->GetSRV()->GPUHandle);
- cmdList->SetComputeUAV(0, CurrentFrameConsts->VisibleOpaqueCommandsCache->GetUAV()->GPUHandle);
- cmdList->SetComputeUAV(1, CurrentFrameConsts->OpaqueDrawCounter->GetUAV()->GPUHandle);
- cmdList->SetComputeUAV(2, CurrentFrameConsts->VisibleTransparentCommandsCache->GetUAV()->GPUHandle);
- cmdList->SetComputeUAV(3, CurrentFrameConsts->TransparentDrawCounter->GetUAV()->GPUHandle);
- cmdList->Dispatch((_IndirectCommandsCache->GetElementCount() + 63) / 64, 1, 1);
-
- cmdList->ResourceBarrier({
- CurrentFrameConsts->VisibleOpaqueCommandsCache->GetResource().GetUAVBarrier(),
- CurrentFrameConsts->OpaqueDrawCounter->GetResource().GetUAVBarrier(),
- CurrentFrameConsts->VisibleOpaqueCommandsCache->GetResource().GetIndirectArgsBarrier(),
- CurrentFrameConsts->OpaqueDrawCounter->GetResource().GetIndirectArgsBarrier(),
- CurrentFrameConsts->VisibleTransparentCommandsCache->GetResource().GetIndirectArgsBarrier(),
- CurrentFrameConsts->TransparentDrawCounter->GetResource().GetIndirectArgsBarrier() });
- cmdList->EndPixEvent();
-
-
- cmdList->BeginPixEvent("Opaque Render Pass", Colors::ForestGreen);
- cmdList->SetGraphicsRootSignature(_rootSignatures["OpaquePass"].get());
- cmdList->SetPipelineState(_PSOs["OpaquePass"]);
- cmdList->SetGraphicsRootConstantBufferView(1, CurrentFrameConsts->MainCB->GetElementAddress(0));
- cmdList->SetGraphicsRootConstantBufferView(2, CurrentFrameConsts->CameraCB->
- GetElementAddress(_commandRecorder._cameraCBIndex));
- cmdList->EnhancedTextureBarrier({ _opaqueAccumTexture->GetResource()->GetRenderTargetEnhBarrier() });
- cmdList->SetRenderTargets({ _opaqueAccumTexture.get() }, _depthStencil.get());
- cmdList->ClearRenderTargetView(_opaqueAccumTexture.get());
- cmdList->SetGeometryBuffer(_geometryBuffer.get());
- cmdList->SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- cmdList->SetDescriptorHeaps({ _srvuavHeap.get() });
- cmdList->SetGraphicsSRV(0, CurrentFrameConsts->MaterialCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(1, CurrentFrameConsts->TransformCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(2, CurrentFrameConsts->InstanceCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(3, _srvuavHeap->GetGPUHandle(Texture2D_StartIndex));
- cmdList->ExecuteIndirect(_commandSignatures["OpaquePass"].Get(), _IndirectCommandsCache->GetElementCount(),
- CurrentFrameConsts->VisibleOpaqueCommandsCache->GetResource().D3DResource.Get(), 0,
- CurrentFrameConsts->OpaqueDrawCounter->GetResource().D3DResource.Get(), 0);
- cmdList->EnhancedTextureBarrier({ _opaqueAccumTexture->GetResource()->GetPixelShaderResourceEnhBarrier() });
- cmdList->EndPixEvent();
-
- cmdList->BeginPixEvent("Transparent Render Pass", Colors::Aqua);
- cmdList->SetGraphicsRootSignature(_rootSignatures["OpaquePass"].get());
- cmdList->SetPipelineState(_PSOs["TransparentPass"]);
- cmdList->SetGraphicsRootConstantBufferView(1, CurrentFrameConsts->MainCB->GetElementAddress(0));
- cmdList->SetGraphicsRootConstantBufferView(2, CurrentFrameConsts->CameraCB->
- GetElementAddress(_commandRecorder._cameraCBIndex));
- cmdList->EnhancedTextureBarrier({ _transparencyAccumTexture->GetResource()->GetRenderTargetEnhBarrier(),
- _transparencyRevealageTexture->GetResource()->GetRenderTargetEnhBarrier() });
-
- cmdList->SetRenderTargets({ _transparencyAccumTexture.get(), _transparencyRevealageTexture.get() },
- _depthStencil.get());
- cmdList->ClearRenderTargetView(_transparencyAccumTexture.get());
- cmdList->ClearRenderTargetView(_transparencyRevealageTexture.get());
-
- cmdList->SetGeometryBuffer(_geometryBuffer.get());
- cmdList->SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- cmdList->SetDescriptorHeaps({ _srvuavHeap.get() });
- cmdList->SetGraphicsSRV(0, CurrentFrameConsts->MaterialCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(1, CurrentFrameConsts->TransformCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(2, CurrentFrameConsts->InstanceCache->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(3, _srvuavHeap->GetGPUHandle(Texture2D_StartIndex));
- cmdList->ExecuteIndirect(_commandSignatures["OpaquePass"].Get(), _IndirectCommandsCache->GetElementCount(),
- CurrentFrameConsts->VisibleTransparentCommandsCache->GetResource().D3DResource.Get(), 0,
- CurrentFrameConsts->TransparentDrawCounter->GetResource().D3DResource.Get(), 0);
- cmdList->EnhancedTextureBarrier({ _transparencyAccumTexture->GetResource()->GetPixelShaderResourceEnhBarrier(),
- _transparencyRevealageTexture->GetResource()->GetPixelShaderResourceEnhBarrier() });
- cmdList->EndPixEvent();
-
-
- cmdList->BeginPixEvent("Composition Render Pass", Colors::Bisque);
- cmdList->SetGraphicsRootSignature(_rootSignatures["CompositionPass"].get());
- cmdList->SetPipelineState(_PSOs["CompositionPass"]);
- cmdList->SetRenderTargets({ CurrentBackBuffer }, _depthStencil.get());
- cmdList->SetDescriptorHeaps({ _srvuavHeap.get() });
- cmdList->SetGraphicsSRV(0, _opaqueAccumTexture->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(1, _transparencyAccumTexture->GetSRV()->GPUHandle);
- cmdList->SetGraphicsSRV(2, _transparencyRevealageTexture->GetSRV()->GPUHandle);
- cmdList->GetCommandList()->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- cmdList->GetCommandList()->DrawInstanced(3, 1, 0, 0);
- cmdList->EndPixEvent();
-
- cmdList->EnhancedTextureBarrier({ CurrentBackBuffer->GetResource()->GetPresentEnhBarrier() });
- cmdList->ResourceBarrier({ _depthStencil->GetResource()->GetCommonBarrier() });
+ auto primarycmdQueue = _primaryDevice->GetCommandQueue();
+ auto primarycmdList = primarycmdQueue->GetCommandList();
+ auto primaryCurrentFrameConsts = GetCurrentPrimaryFrameConstants();
+ for (auto& renderPass : _primaryRenderPassExecutionList)
+ {
+ if (renderPass->GetFlagValue(RENDER_PASS_FLAG_SYNC_DEVICES) && _dualGPUMode)
+ {
+ primarycmdQueue->ExecuteCommandList(primarycmdList);
+ primarycmdQueue->WaitForOtherFence(primarycmdList->FenceValue);
+ primarycmdList = primarycmdQueue->GetCommandList();
+ }
+ else { renderPass->Execute(primarycmdList); }
+ }
+ primarycmdQueue->ExecuteCommandList(primarycmdList);
+ primaryCurrentFrameConsts->FenceValue = primarycmdList->FenceValue;
- cmdQueue->ExecuteCommandList(cmdList);
- CurrentFrameConsts->FenceValue = cmdList->FenceValue;
+ if (_dualGPUMode)
+ {
+ auto secondarycmdQueue = _secondaryDevice->GetCommandQueue();
+ auto secondarycmdList = secondarycmdQueue->GetCommandList();
+ auto secondaryCurrentFrameConsts = GetCurrentSecondaryFrameConstants();
+ for (auto& renderPass : _secondaryRenderPassExecutionList)
+ {
+ if (renderPass->GetFlagValue(RENDER_PASS_FLAG_SYNC_DEVICES))
+ {
+ secondarycmdQueue->ExecuteCommandList(secondarycmdList);
+ secondarycmdQueue->WaitForOtherFence(secondarycmdList->FenceValue);
+ secondarycmdList = secondarycmdQueue->GetCommandList();
+ }
+ else { renderPass->Execute(secondarycmdList); }
+ }
+ secondarycmdQueue->ExecuteCommandList(secondarycmdList);
+ secondaryCurrentFrameConsts->FenceValue = secondarycmdList->FenceValue;
+ }
_backBuffer->Present();
}
-void RenderModule::BuildDescHeapsAndBackBuffer()
+void RenderModule::BuildBackBuffer()
{
- _rtvHeap = std::make_unique(_primaryDevice.get(),
- D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1000,
- D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
-
- _srvuavHeap = std::make_unique(_primaryDevice.get(),
- D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1000000,
- D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
-
- _dsvHeap = std::make_unique(_primaryDevice.get(),
- D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1000,
- D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
-
uint16_t width, height;
_window->GetWindowSize(width, height);
_backBuffer = std::make_unique(_primaryDevice.get(), _window->GetWindowHandle(),
- DXGI_FORMAT_R8G8B8A8_UNORM, 2, width, height, _rtvHeap.get());
+ DXGI_FORMAT_R8G8B8A8_UNORM, 2, width, height, _primaryResources.RTVHeap.get());
GDX12TextureDesc desc;
desc.CreateSRV = false;
- desc.DSVHeap = _dsvHeap.get();
+ desc.DSVHeap = _primaryResources.DSVHeap.get();
desc.CreateDSV = true;
- desc.DSVHeapIndex = _dsvHeap->GetAvailableIndex();
+ desc.DSVHeapIndex = _primaryResources.DSVHeap->GetAvailableIndex();
desc.Format = desc.DSVDesc.Format = DXGI_FORMAT_D32_FLOAT;
desc.Width = width;
desc.Height = height;
@@ -708,292 +776,114 @@ void RenderModule::BuildDescHeapsAndBackBuffer()
desc.DSVDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
desc.DSVDesc.Texture2D.MipSlice = 0;
- _depthStencil = std::make_unique(desc);
-
- //MOVE THESE TO RENDER PASSES
- GDX12TextureDesc desc2;
- desc2.Format = desc2.RTVDesc.Format = desc2.SRVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- desc2.Width = width;
- desc2.Height = height;
-
- desc2.CreateSRV = true;
- desc2.SRV_UAV_Heap = _srvuavHeap.get();
- desc2.SRVHeapIndex = _srvuavHeap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
- desc2.SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- desc2.SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
- desc2.SRVDesc.Texture2D.MipLevels = 1;
- desc2.SRVDesc.Texture2D.MostDetailedMip = 0;
- desc2.SRVDesc.Texture2D.PlaneSlice = 0;
- desc2.SRVDesc.Texture2D.ResourceMinLODClamp = 0.0f;
-
- desc2.CreateRTV = true;
- desc2.RTVHeap = _rtvHeap.get();
- desc2.RTVHeapIndex = _rtvHeap->GetAvailableIndex();
- desc2.RTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
- desc2.RTVDesc.Texture2D.PlaneSlice = 0;
- desc2.RTVDesc.Texture2D.MipSlice = 0;
-
- _opaqueAccumTexture = std::make_unique(desc2);
-
- desc2.SRVHeapIndex = _srvuavHeap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
- desc2.RTVHeapIndex = _rtvHeap->GetAvailableIndex();
- _transparencyAccumTexture = std::make_unique(desc2);
-
- desc2.Format = desc2.RTVDesc.Format = desc2.SRVDesc.Format = DXGI_FORMAT_R16_FLOAT;
- desc2.SRVHeapIndex = _srvuavHeap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
- desc2.RTVHeapIndex = _rtvHeap->GetAvailableIndex();
- _transparencyRevealageTexture = std::make_unique(desc2);
-}
+ _depthStencil = std::make_unique();
+ _depthStencil->Initialize(desc);
-void RenderModule::BuildRootSignatures()
-{
- GDX12RootSignatureDesc desc;
- desc.NumSingleCBVSlots = 2;
- desc.NumSingleSRVSlots = 3;
- desc.StaticSamplers = GetStaticSamplers();
- desc.SRVRanges.push_back(GDX12RootSignatureRange(Texture2D_RangeLength));
- desc.Constants.push_back(1);
- _rootSignatures["OpaquePass"] = std::make_unique(_primaryDevice.get(), desc);
-
- std::vector args;
- D3D12_INDIRECT_ARGUMENT_DESC argConst = {};
- argConst.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
- argConst.Constant.DestOffsetIn32BitValues = 0;
- argConst.Constant.Num32BitValuesToSet = 1;
- args.push_back(argConst);
- D3D12_INDIRECT_ARGUMENT_DESC argDraw = {};
- argDraw.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
- args.push_back(argDraw);
- D3D12_COMMAND_SIGNATURE_DESC cmdSigDesc = {};
- cmdSigDesc.ByteStride = sizeof(GDX12IndirectDrawArgs);
- cmdSigDesc.NumArgumentDescs = args.size();
- cmdSigDesc.pArgumentDescs = args.data();
- cmdSigDesc.NodeMask = 0;
-
- _primaryDevice->GetDevice()->CreateCommandSignature(&cmdSigDesc,
- _rootSignatures["OpaquePass"]->GetRootSignature().Get(),
- IID_PPV_ARGS(&_commandSignatures["OpaquePass"]));
-
- GDX12RootSignatureDesc desc3;
- desc3.NumSingleCBVSlots = 1;
- desc3.NumSingleSRVSlots = 3;
- desc3.NumSingleUAVSlots = 4;
- _rootSignatures["Culling"] = std::make_unique(_primaryDevice.get(), desc3);
-
- GDX12RootSignatureDesc desc4;
- desc4.NumSingleUAVSlots = 1;
- _rootSignatures["BufferClear"] = std::make_unique(_primaryDevice.get(), desc4);
-
- GDX12RootSignatureDesc desc5;
- desc5.NumSingleSRVSlots = 3;
- desc5.StaticSamplers = GetStaticSamplers();
- _rootSignatures["CompositionPass"] = std::make_unique(_primaryDevice.get(), desc5);
+ _RPcommonData.WindowWidth = width;
+ _RPcommonData.WindowHeight = height;
}
-void RenderModule::BuildShaders()
+void RenderModule::ShareFences()
{
- auto& Compiler = GDX12ShaderCompiler::GetInstance();
+ HANDLE primaryhandle;
+ ThrowIfFailed(_primaryDevice->GetDevice()->CreateSharedHandle(
+ _primaryDevice->GetCommandQueue()->GetFence().Get(),
+ nullptr, GENERIC_ALL, nullptr, &primaryhandle));
- _shaders["CullingCS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "Culling.hlsl", nullptr, "CS", "cs");
- _shaders["BufferClearCS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "BufferClear.hlsl", nullptr, "CS", "cs");
+ ThrowIfFailed(_secondaryDevice->GetDevice()->OpenSharedHandle(
+ primaryhandle,
+ IID_PPV_ARGS(&_secondaryDevice->GetCommandQueue()->GetOtherFence())));
- _shaders["OpaquePassVS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "OpaquePass.hlsl", nullptr, "VS", "vs");
- _shaders["OpaquePassPS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "OpaquePass.hlsl", nullptr, "PS", "ps");
+ HANDLE secondaryhandle;
+ ThrowIfFailed(_secondaryDevice->GetDevice()->CreateSharedHandle(
+ _secondaryDevice->GetCommandQueue()->GetFence().Get(),
+ nullptr, GENERIC_ALL, nullptr, &secondaryhandle));
- _shaders["TransparentPassVS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "TransparentPass.hlsl", nullptr, "VS", "vs");
- _shaders["TransparentPassPS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "TransparentPass.hlsl", nullptr, "PS", "ps");
-
- _shaders["VS_FSQuad"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "FullScreenVS.hlsl", nullptr, "VS", "vs");
- _shaders["CompositionPassPS"] = Compiler.CompileShader(_primaryDevice.get(), SHADERS_FOLDER "CompositionPass.hlsl", nullptr, "PS", "ps");
+ ThrowIfFailed(_primaryDevice->GetDevice()->OpenSharedHandle(
+ secondaryhandle,
+ IID_PPV_ARGS(&_primaryDevice->GetCommandQueue()->GetOtherFence())));
}
-void RenderModule::BuildPSOs()
+void RenderModule::ConfigureRenderPipeline()
{
- D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {};
-
- desc.InputLayout = { _inputLayouts["Default"].data(), (UINT)_inputLayouts["Default"].size() };
- desc.pRootSignature = _rootSignatures["OpaquePass"]->GetRootSignature().Get();
- desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
- desc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
- desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
- //reversed-Z
- desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
- desc.RasterizerState.FrontCounterClockwise = TRUE;
- desc.SampleMask = UINT_MAX;
- desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
- desc.NumRenderTargets = 1;
- desc.RTVFormats[0] = _backBuffer->GetFormat();
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.DSVFormat = _depthStencil->GetFormat();
-
- desc.VS =
- {
- reinterpret_cast(_shaders["OpaquePassVS"]->GetBufferPointer()),
- _shaders["OpaquePassVS"]->GetBufferSize()
- };
- desc.PS =
- {
- reinterpret_cast(_shaders["OpaquePassPS"]->GetBufferPointer()),
- _shaders["OpaquePassPS"]->GetBufferSize()
- };
- ThrowIfFailed(_primaryDevice->GetDevice()->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&_PSOs["OpaquePass"])));
-
- desc.InputLayout = { nullptr, 0 };
- desc.pRootSignature = _rootSignatures["CompositionPass"]->GetRootSignature().Get();
- desc.DepthStencilState.DepthEnable = false;
- desc.DepthStencilState.StencilEnable = false;
- desc.VS =
- {
- reinterpret_cast(_shaders["VS_FSQuad"]->GetBufferPointer()),
- _shaders["VS_FSQuad"]->GetBufferSize()
- };
- desc.PS =
- {
- reinterpret_cast(_shaders["CompositionPassPS"]->GetBufferPointer()),
- _shaders["CompositionPassPS"]->GetBufferSize()
- };
- ThrowIfFailed(_primaryDevice->GetDevice()->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&_PSOs["CompositionPass"])));
-
- desc.InputLayout = { _inputLayouts["Default"].data(), (UINT)_inputLayouts["Default"].size() };
- desc.pRootSignature = _rootSignatures["OpaquePass"]->GetRootSignature().Get();
- desc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
- // Accumulation
- desc.BlendState.RenderTarget[0].BlendEnable = true;
- desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
- desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
- desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
- // Revealage
- desc.BlendState.RenderTarget[1].BlendEnable = true;
- desc.BlendState.RenderTarget[1].SrcBlend = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[1].DestBlend = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[1].BlendOp = D3D12_BLEND_OP_ADD;
- desc.BlendState.RenderTarget[1].SrcBlendAlpha = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[1].DestBlendAlpha = D3D12_BLEND_ONE;
- desc.BlendState.RenderTarget[1].BlendOpAlpha = D3D12_BLEND_OP_ADD;
- desc.BlendState.RenderTarget[1].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
- // Disable depth write
- desc.DepthStencilState.DepthEnable = true;
- desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
- desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
- desc.DepthStencilState.StencilEnable = false;
-
- desc.NumRenderTargets = 2;
- desc.RTVFormats[0] = _transparencyAccumTexture->GetFormat();
- desc.RTVFormats[1] = _transparencyRevealageTexture->GetFormat();
- desc.DSVFormat = _depthStencil->GetFormat();
- desc.VS =
- {
- reinterpret_cast(_shaders["TransparentPassVS"]->GetBufferPointer()),
- _shaders["TransparentPassVS"]->GetBufferSize()
- };
- desc.PS =
- {
- reinterpret_cast(_shaders["TransparentPassPS"]->GetBufferPointer()),
- _shaders["TransparentPassPS"]->GetBufferSize()
- };
- ThrowIfFailed(_primaryDevice->GetDevice()->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&_PSOs["TransparentPass"])));
+ // Setup render passes you would like to execute
+ // Add in execution order
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ _primaryRenderPassExecutionList.push_back(std::make_unique());
+ SetupRenderPasses();
- D3D12_COMPUTE_PIPELINE_STATE_DESC desc2 = {};
- desc2.pRootSignature = _rootSignatures["Culling"]->GetRootSignature().Get();
- desc2.CS =
- {
- reinterpret_cast(_shaders["CullingCS"]->GetBufferPointer()),
- _shaders["CullingCS"]->GetBufferSize()
- };
+ // Link inputs & outputs for each pass that needs it
+ GDX12RenderPass* clearPass = _primaryRenderPassExecutionList[0].get();
+ GDX12RenderPass* cullingPass = _primaryRenderPassExecutionList[1].get();
+ GDX12RenderPass* opaquePass = _primaryRenderPassExecutionList[2].get();
+ GDX12RenderPass* transparencyPass = _primaryRenderPassExecutionList[3].get();
+ GDX12RenderPass* compositionPass = _primaryRenderPassExecutionList[4].get();
+ GDX12RenderPass* upscalePass = _primaryRenderPassExecutionList[5].get();
+ GDX12RenderPass* outputPass = _primaryRenderPassExecutionList[6].get();
- ThrowIfFailed(_primaryDevice->GetDevice()->CreateComputePipelineState(
- &desc2, IID_PPV_ARGS(&_PSOs["Culling"])));
+ clearPass->SetInputs({ _backBuffer.get(), _depthStencil.get() });
+ cullingPass->SetInputs({});
+ opaquePass->SetInputs({});
+ transparencyPass->SetInputs({ opaquePass->GetOutput(2) });
+ compositionPass->SetInputs({ opaquePass->GetOutput(0), transparencyPass->GetOutput(0), transparencyPass->GetOutput(1) });
+ upscalePass->SetInputs({ opaquePass->GetOutput(2), opaquePass->GetOutput(1), compositionPass->GetOutput(0) });
+ outputPass->SetInputs({ upscalePass->GetOutput(0), _backBuffer.get()});
- D3D12_COMPUTE_PIPELINE_STATE_DESC desc3 = {};
- desc3.pRootSignature = _rootSignatures["BufferClear"]->GetRootSignature().Get();
- desc3.CS =
- {
- reinterpret_cast(_shaders["BufferClearCS"]->GetBufferPointer()),
- _shaders["BufferClearCS"]->GetBufferSize()
- };
+ opaquePass->SetFlag(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION, true);
+ transparencyPass->SetFlag(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION, true);
+ compositionPass->SetFlag(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION, true);
- ThrowIfFailed(_primaryDevice->GetDevice()->CreateComputePipelineState(
- &desc3, IID_PPV_ARGS(&_PSOs["BufferClear"])));
+ InitializeRenderPasses();
}
-void RenderModule::BuildFrameConstants()
+void RenderModule::SetupRenderPasses()
{
- for (int i = 0; i < NumFrameConstantVariable.GetValue(); i++)
+ for (auto& pass : _primaryRenderPassExecutionList)
{
- _frameConstants.push_back(std::make_unique(_primaryDevice.get()));
-
- _frameConstants[i]->MaterialCache->CreateSRV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->TransformCache->CreateSRV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->InstanceCache->CreateSRV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->VisibleOpaqueCommandsCache->CreateUAV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->OpaqueDrawCounter->CreateUAV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->VisibleTransparentCommandsCache->CreateUAV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
- _frameConstants[i]->TransparentDrawCounter->CreateUAV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
+ pass->Setup(&_primaryResources, &_secondaryResources, &_RPcommonData);
+ _primaryPipelineFlags |= pass->GetFlags();
}
- _IndirectCommandsCache = std::make_unique>(_primaryDevice.get(), 0, EBufferType::Upload, false);
- _IndirectCommandsCache->CreateSRV(_srvuavHeap.get(), _srvuavHeap->GetAvailableIndex(ConstantsResources));
-}
-
-void RenderModule::UpdateMainCB()
-{
- auto& frameRes = _frameConstants[_currFrameConstantsIndex];
-
- GDX12MainConstants mainConstants;
-
- uint16_t width, height;
- _window->GetWindowSize(width, height);
-
- mainConstants.RenderTargetSize = { static_cast(width), static_cast(height) };
- mainConstants.TotalTime = _timer->TotalTime();
- mainConstants.DeltaTime = _timer->DeltaTime();
-
- frameRes->MainCB->CopyData(0, mainConstants);
+ for (auto& pass : _secondaryRenderPassExecutionList)
+ {
+ pass->Setup(&_secondaryResources, &_primaryResources, &_RPcommonData);
+ _secondaryPipelineFlags |= pass->GetFlags();
+ }
}
-void RenderModule::UpdateMaterialCB()
+void RenderModule::InitializeRenderPasses()
{
- auto currMaterialCB = _frameConstants[_currFrameConstantsIndex]->MaterialCache.get();
- for (auto& i : _materials)
+ std::vector allRenderPasses;
+ for (auto& pass : _primaryRenderPassExecutionList)
+ allRenderPasses.push_back(pass.get());
+ for (auto& pass : _secondaryRenderPassExecutionList)
+ allRenderPasses.push_back(pass.get());
+ const int MAX_ITERATIONS = 100;
+ int iteration = 0;
+ while (!allRenderPasses.empty())
{
- GDX12Material* material = i.second.get();
-
- if (material->DirtyFlag)
- {
- material->DirtyFlag = false;
- material->_numFramesDirty = _numFrameConstants;
+ if (iteration > MAX_ITERATIONS)
+ {
+ OutputDebugStringA("ERROR: RenderPass linking failed after 100 attempts. This can be caused by wrong render pass inputs\n");
+ break;
}
-
- if (material->_numFramesDirty > 0)
+ for (auto it = allRenderPasses.begin(); it != allRenderPasses.end();)
{
- GDX12MaterialConstants materialConstants;
- materialConstants.Roughness = material->Roughness;
- materialConstants.Metallic = material->Metallic;
- materialConstants.Opacity = material->Opacity;
- materialConstants.RenderLayer = UINT(material->Type);
-
- if (material->Diffuse)
+ GDX12RenderPass* renderPass = *it;
+ if (renderPass->ValidateInputs())
{
- materialConstants.DiffuseIndex = material->Diffuse->GetSRV()->HeapIndex - Texture2D_StartIndex;
+ renderPass->Initialize();
+ it = allRenderPasses.erase(it);
}
- if (material->Normal)
- {
- materialConstants.NormalIndex = material->Normal->GetSRV()->HeapIndex - Texture2D_StartIndex;
- }
- if (material->Displacement)
- {
- materialConstants.DisplacementIndex = material->Displacement->GetSRV()->HeapIndex - Texture2D_StartIndex;
- }
-
- currMaterialCB->CopyData(material->_CBufferIndex, materialConstants);
- material->_numFramesDirty--;
+ else { ++it; }
}
+ iteration++;
}
}
diff --git a/Apps/App.Base/src/SceneManagerModule.cpp b/Apps/App.Base/src/SceneManagerModule.cpp
index 300eb81..ac114bd 100644
--- a/Apps/App.Base/src/SceneManagerModule.cpp
+++ b/Apps/App.Base/src/SceneManagerModule.cpp
@@ -2,7 +2,6 @@
#include "App.Base/Systems/CircleMovementSystem.h"
#include "App.Base/Systems/MovementSystem.h"
-#include "App.Base/Systems/RenderSubmitSystem.h"
#include "App.Base/Systems/GPUDataUpdateSystem.h"
#include "App.Base/Systems/LookAtTargetSystem.h"
#include "App.Base/Systems/SplineFollowSystem.h"
@@ -57,7 +56,6 @@ void SceneManagerModule::Initialize()
AddSystem(world, 2);
AddSystem(world, 3);
AddSystem(world, 101);
- AddSystem(world, 102);
}
void SceneManagerModule::Uninitialize()
diff --git a/Apps/App.Benchmark/App.Benchmark.vcxproj b/Apps/App.Benchmark/App.Benchmark.vcxproj
index f7a784a..db4375d 100644
--- a/Apps/App.Benchmark/App.Benchmark.vcxproj
+++ b/Apps/App.Benchmark/App.Benchmark.vcxproj
@@ -114,12 +114,14 @@
Windows
true
- Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mtd.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
+ Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mtd.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;libxess.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
false
- $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
+ $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\xess\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
- xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+ xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\sl*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\sl*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\nvngx*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\nvngx*.dll" "$(TargetDir)"
@@ -135,11 +137,13 @@
Windows
true
- $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
- Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mt.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
+ $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\xess\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
+ Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mt.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;libxess.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
- xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+ xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\sl*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\sl*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\nvngx*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\nvngx*.dll" "$(TargetDir)"
@@ -148,4 +152,4 @@
-
\ No newline at end of file
+
diff --git a/Apps/App.Editor/App.Editor.vcxproj b/Apps/App.Editor/App.Editor.vcxproj
index 4fd5eb3..19dfbde 100644
--- a/Apps/App.Editor/App.Editor.vcxproj
+++ b/Apps/App.Editor/App.Editor.vcxproj
@@ -114,11 +114,13 @@
Windows
true
- $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
- Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mtd.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
+ $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\xess\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
+ Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mtd.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;libxess.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
- xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+ xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\sl*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\sl*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\nvngx*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\nvngx*.dll" "$(TargetDir)"
@@ -134,11 +136,13 @@
Windows
true
- $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
- Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mt.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
+ $(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.Core\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.RendererDX12\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\Engine.UI\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\App.Base\;$(PEPRepoRoot)Build\bin\$(Platform)\$(Configuration)\External.Libraries\;$(PEPRepoRoot)External\External.Libraries\dxc\lib\$(Platform)\;$(PEPRepoRoot)External\External.Libraries\pix\lib\;$(PEPRepoRoot)External\External.Libraries\assimp\lib\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtk\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\directxtex\lib\$(Platform)\$(Configuration)\;$(PEPRepoRoot)External\External.Libraries\ffx-api\lib\;$(PEPRepoRoot)External\External.Libraries\xess\lib\;$(PEPRepoRoot)External\External.Libraries\directstorage\lib\;$(PEPRepoRoot)External\External.Libraries\directxmesh\lib\;$(PEPRepoRoot)External\External.Libraries\wwise\lib\;%(AdditionalLibraryDirectories)
+ Engine.Core.lib;Engine.RendererDX12.lib;Engine.UI.lib;App.Base.lib;External.Libraries.lib;dxcompiler.lib;dxil.lib;WinPixEventRuntime.lib;assimp-vc143-mt.lib;DirectXTK12.lib;DirectXTex.lib;amd_fidelityfx_dx12.lib;libxess.lib;dstorage.lib;DirectXMesh.lib;AkSoundEngine.lib;AkMemoryMgr.lib;AkStreamMgr.lib;CommunicationCentral.lib;%(AdditionalDependencies)
- xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+ xcopy /Y /D "$(PEPRepoRoot)External\Runtime\*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\sl*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\sl*.dll" "$(TargetDir)"
+if exist "$(PEPRepoRoot)External\Runtime\nvngx*.dll" xcopy /Y "$(PEPRepoRoot)External\Runtime\nvngx*.dll" "$(TargetDir)"
@@ -147,4 +151,4 @@
-
\ No newline at end of file
+
diff --git a/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj b/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj
index 3fbd69f..5e82c14 100644
--- a/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj
+++ b/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj
@@ -21,9 +21,23 @@
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -39,13 +53,16 @@
+
+
+
-
+
diff --git a/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj.filters b/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj.filters
index f300a89..09f0937 100644
--- a/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj.filters
+++ b/Engine/Engine.RendererDX12/Engine.RendererDX12.vcxproj.filters
@@ -66,15 +66,63 @@
Header Files
-
- Header Files
-
Header Files
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
@@ -110,6 +158,9 @@
Source Files
+
+ Source Files
+
Source Files
@@ -119,11 +170,20 @@
Source Files
-
+
Source Files
-
+
Source Files
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandList.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandList.h
index caf104d..523c00f 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandList.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandList.h
@@ -85,7 +85,7 @@ class GDX12CommandList
//Misc
void BeginPixEvent(const std::string& name, XMVECTOR color);
void EndPixEvent();
-
+ void CopyResource(ID3D12Resource* destResource, ID3D12Resource* sourceResource);
void BuildRaytracingAccelerationStructure(const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC* pDesc);
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandQueue.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandQueue.h
index e81c9e6..2382fdb 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandQueue.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12CommandQueue.h
@@ -14,15 +14,18 @@ class GDX12CommandQueue
void Reset();
const ComPtr& GetCommandQueue();
+ const ComPtr& GetPresentCommandQueue();
const ComPtr& GetFence();
+ ComPtr& GetOtherFence();
// Returns a CommandList that you can work with.
// If all previously created lists are busy - a new one will be created.
GDX12CommandList* GetCommandList();
void ExecuteCommandList(GDX12CommandList* commandList);
- void ExecuteCommandLists(GDX12CommandList** lists, UINT count);
+ void ExecuteCommandLists(std::vector& commandLists);
- void WaitForFenceValue(uint64_t fenceValue);
+ void CPUWaitForFenceValue(uint64_t fenceValue);
+ void WaitForOtherFence(uint64_t otherFenceValue);
//Waits for execution of all active lists
void Flush();
@@ -36,7 +39,12 @@ class GDX12CommandQueue
void ClearCompletedLists();
ComPtr _commandQueue;
+ ComPtr _proxyCommandQueue;
ComPtr _fence;
+ //shared fence from another device
+ //null if _dualGPUMode is false
+ ComPtr _otherFence;
+
GDX12Device* _device;
// Command Lists can be requested via GetCommandList()
@@ -47,4 +55,4 @@ class GDX12CommandQueue
std::vector> _availableCommandLists;
uint64_t _lastDispatchedFenceValue;
-};
\ No newline at end of file
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12ConstantStructures.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12ConstantStructures.h
index e1bc106..b0c8e95 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12ConstantStructures.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12ConstantStructures.h
@@ -12,6 +12,7 @@ struct GDX12MainConstants
struct GDX12TransformConstants
{
XMFLOAT4X4 WorldMatrix = Identity4x4();
+ XMFLOAT4X4 PrevWorldMatrix = Identity4x4();
};
struct GDX12MaterialConstants
@@ -33,7 +34,9 @@ struct GDX12MaterialConstants
struct GDX12CameraConstants
{
XMFLOAT4X4 ViewProj = Identity4x4();
+ XMFLOAT4X4 ViewProjNoJitter = Identity4x4();
XMFLOAT4X4 View = Identity4x4();
+ XMFLOAT4X4 PrevViewProjNoJitter = Identity4x4();
XMFLOAT3 CameraLocation = { 0.f, 0.f, 0.f };
float NearPlane;
float FarPlane;
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Device.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Device.h
index 1f652f5..f739965 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Device.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Device.h
@@ -8,16 +8,17 @@ class GDX12CommandQueue;
struct DeviceSpecs
{
D3D_FEATURE_LEVEL MaxFeatureLevel;
- D3D_SHADER_MODEL MaxShaderModel;
- bool RaytracingSupport;
- bool MeshShadersSupport;
- bool VariableRateShadingSupport;
- bool EnhancedBarriersSupport;
- bool CrossAdapterRowMajorTextureSupport;
std::string Name;
size_t DedicatedVideoMemory; // in bytes
size_t DedicatedSystemMemory; // in bytes
size_t SharedSystemMemory; // in bytes
+ CD3DX12FeatureSupport Features;
+};
+
+enum EDeviceRole
+{
+ DEVICE_ROLE_PRIMARY,
+ DEVICE_ROLE_SECONDARY
};
class GDX12Device : public std::enable_shared_from_this
@@ -30,15 +31,19 @@ class GDX12Device : public std::enable_shared_from_this
void Reset();
const ComPtr& GetDevice();
+ const ComPtr& GetCommandQueueCreationDevice();
GDX12CommandQueue* GetCommandQueue();
const DeviceSpecs& GetDeviceFeatures();
+ LUID GetAdapterLuid() const;
const bool IsInitialized();
+ EDeviceRole Role;
private:
void CollectDeviceFeatures();
ComPtr _adapter;
ComPtr _device;
+ ComPtr _proxyDevice;
std::unique_ptr _commandQueue;
@@ -49,4 +54,4 @@ class GDX12Device : public std::enable_shared_from_this
UINT _cbvSrvUavDescriptorSize;
DeviceSpecs _specs;
-};
\ No newline at end of file
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceFactory.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceFactory.h
index c5f49da..2df9238 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceFactory.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceFactory.h
@@ -45,5 +45,6 @@ class GDX12DeviceFactory
GDX12DeviceFactory() = delete;
static ComPtr _dxgiFactory;
+ static ComPtr _dxgiFactoryProxy;
static bool _isInitialized;
-};
\ No newline at end of file
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceResources.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceResources.h
new file mode 100644
index 0000000..329b8f7
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12DeviceResources.h
@@ -0,0 +1,41 @@
+#pragma once
+#include "Engine.RendererDX12/D3DHelpers.h"
+#include "Engine.RendererDX12/GDX12DescriptorHeap.h"
+#include "Engine.RendererDX12/GDX12FrameConstants.h"
+#include "Engine.RendererDX12/GDX12RootSignature.h"
+#include "Engine.RendererDX12/GDX12Texture.h"
+#include "Engine.RendererDX12/GDX12Material.h"
+#include "Engine.RendererDX12/GDX12GeometryBuffer.h"
+
+class GDX12Device;
+class GameTimer;
+
+class GDX12DeviceResources
+{
+public:
+ GDX12DeviceResources() : CurrFrameConstantsIndex(0), Device(nullptr) {}
+
+ std::unordered_map> InputLayouts;
+ std::unique_ptr GeometryBuffer;
+
+ // All heaps created in one high-capacity instance
+ std::unique_ptr RTVHeap;
+ std::unique_ptr SRV_UAV_Heap;
+ std::unique_ptr DSVHeap;
+
+ std::vector> FrameConstants;
+ UINT CurrFrameConstantsIndex;
+
+ std::unique_ptr> IndirectCommandsCache;
+
+ std::unordered_map> Shaders;
+ std::unordered_map> PSOs;
+ std::unordered_map> RootSignatures;
+ std::unordered_map > CommandSignatures;
+ std::unordered_map> Textures;
+
+ GDX12Device* Device;
+ void Initialize(GDX12Device* device);
+ void UpdateMainCB(UINT width, UINT height, GameTimer* timer);
+ void UpdateMaterialCB(std::unordered_map>& materials);
+};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12FrameConstants.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12FrameConstants.h
index 9afdb68..6cc3258 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12FrameConstants.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12FrameConstants.h
@@ -8,6 +8,16 @@
class GDX12Device;
+// Used for collecting & using GPU culling results
+// This structured is used by any object that uses culling(cameras, shadowmaps)
+struct GDX12VisibilityBuffers
+{
+ std::unique_ptr> VisibleOpaqueCommandsCache;
+ std::unique_ptr> OpaqueDrawCounter;
+ std::unique_ptr> VisibleTransparentCommandsCache;
+ std::unique_ptr> TransparentDrawCounter;
+};
+
class GDX12FrameConstants
{
public:
@@ -25,13 +35,7 @@ class GDX12FrameConstants
std::unique_ptr> InstanceCache;
std::unique_ptr> LightCB;
std::unique_ptr> CameraCB;
-
- // Append buffer for visible indirect commands
- std::unique_ptr> VisibleOpaqueCommandsCache;
- std::unique_ptr> OpaqueDrawCounter;
-
- std::unique_ptr> VisibleTransparentCommandsCache;
- std::unique_ptr> TransparentDrawCounter;
+ std::vector CameraVisibilityCommands;
UINT64 FenceValue;
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Material.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Material.h
index f73a4ed..92d7cf3 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Material.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Material.h
@@ -2,6 +2,8 @@
#include "Engine.RendererDX12/D3DHelpers.h"
+#include "Engine.Core/Types/TextureTypes.h"
+
class GDX12Texture;
enum class MaterialType
@@ -11,17 +13,24 @@ enum class MaterialType
Transparent = 2,
};
+struct GPUTexture
+{
+ std::string Name;
+ GDX12Texture* PrimaryDeviceTexture = nullptr;
+ GDX12Texture* SecondaryDeviceTexture = nullptr;
+};
+
class GDX12Material
{
public:
std::string Name;
- GDX12Texture* Diffuse;
- GDX12Texture* Normal;
- GDX12Texture* Specular;
- GDX12Texture* RoughnessMap;
- GDX12Texture* Emissive;
- GDX12Texture* Displacement;
+ GPUTexture* Diffuse;
+ GPUTexture* Normal;
+ GPUTexture* Specular;
+ GPUTexture* RoughnessMap;
+ GPUTexture* Emissive;
+ GPUTexture* Displacement;
float Metallic;
float Roughness;
@@ -39,6 +48,7 @@ class GDX12Material
private:
friend class RenderModule;
+ friend class GDX12DeviceResources;
GDX12Material() : Name(""), Diffuse(nullptr), Normal(nullptr), Specular(nullptr), RoughnessMap(nullptr),
Emissive(nullptr), Displacement(nullptr), Metallic(0.f), Roughness(1.f), Opacity(1.f),
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12RenderCommandRecorder.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12RenderCommandRecorder.h
deleted file mode 100644
index 996e095..0000000
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12RenderCommandRecorder.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "Engine.RendererDX12/D3DHelpers.h"
-
-#include "Engine.RendererDX12/GDX12GeometryBuffer.h"
-#include "Engine.RendererDX12/GDX12Material.h"
-
-struct RenderCommand
-{
-
-};
-
-struct DrawMeshCommand : RenderCommand
-{
- MeshHandle Mesh;
- std::vector Materials;
- int TransformCBIndex;
-
- DrawMeshCommand(MeshHandle mesh, std::vector materials, int transformCBIndex)
- : Mesh(mesh), Materials(materials), TransformCBIndex(transformCBIndex)
- {
-
- }
-};
-
-class GDX12RenderCommandRecorder
-{
-public:
- GDX12RenderCommandRecorder();
-
- void DrawFromCamera(int cameraCBIndex);
- void ClearCommands();
-
-private:
- friend class RenderModule;
-
- int _cameraCBIndex;
-};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Resource.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Resource.h
index a544a79..bb8d798 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Resource.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Resource.h
@@ -23,10 +23,15 @@ class GDX12Resource
CD3DX12_RESOURCE_BARRIER GetPresentBarrier();
CD3DX12_RESOURCE_BARRIER GetIndirectArgsBarrier();
CD3DX12_RESOURCE_BARRIER GetUAVBarrier();
+ CD3DX12_RESOURCE_BARRIER GetSRVBarrier();
void SetCurrentState(D3D12_RESOURCE_STATES newState);
D3D12_RESOURCE_STATES GetCurrentState();
+ void Reset();
+
+ virtual void ResetState();
+
ComPtr D3DResource;
private:
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SharedTexture.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SharedTexture.h
new file mode 100644
index 0000000..a84e7ca
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SharedTexture.h
@@ -0,0 +1,176 @@
+#pragma once
+
+#include "Engine.RendererDX12\D3DHelpers.h"
+
+#include "Engine.Core/Types/TextureTypes.h"
+#include "Engine.RendererDX12/IRenderPassLink.h"
+#include "Engine.RendererDX12/GDX12Device.h"
+#include "Engine.RendererDX12/GDX12TextureResource.h"
+
+class GDX12SharedTexture : public IRenderPassLink
+{
+public:
+ GDX12SharedTexture() : _width(0) , _height(0),
+ _format(DXGI_FORMAT_UNKNOWN), _heapSize(0), _transferFromDeivce(nullptr),
+ _transferToDevice(nullptr), _isInitiliazed(false)
+ {
+ }
+
+ ~GDX12SharedTexture()
+ {
+ Release();
+ }
+
+ GDX12Texture* GetTexture() override
+ {
+ OutputDebugStringA("ERROR: Getting texture from SharedTexture via interface is not allowed! Use GetSharedTexture() or get it via CopyFromRenderPass.\n");
+ return nullptr;
+ }
+
+ void Initialize(GDX12Device* transferFromDeivce, GDX12Device* transferToDevice,
+ UINT width, UINT height, DXGI_FORMAT format)
+ {
+ Release();
+
+ _transferFromDeivce = transferFromDeivce;
+ _transferToDevice = transferToDevice;
+ _width = width;
+ _height = height;
+ _format = format;
+
+ CreateSharedHeap();
+ CreatePlacedResources();
+ ShareResources();
+
+ _isInitiliazed = true;
+ }
+
+ void Release()
+ {
+ _sharedTexturePrimary.Reset();
+ _sharedTextureSecondary.Reset();
+ _sharedHeap.Reset();
+ _width = 0;
+ _height = 0;
+ _format = DXGI_FORMAT_UNKNOWN;
+ _heapSize = 0;
+ }
+
+ void Resize(UINT width, UINT height)
+ {
+ DXGI_FORMAT cachedFormat = _format;
+ Release();
+ Initialize(_transferFromDeivce, _transferToDevice, width, height, cachedFormat);
+ }
+
+ //Transfer happens from primary to secondary
+ GDX12Resource* GetPrimaryResource() { return &_sharedTexturePrimary; }
+ GDX12Resource* GetSecondaryResource() { return &_sharedTextureSecondary; }
+ UINT GetWidth() { return _width; }
+ UINT GetHeight() { return _height; }
+ DXGI_FORMAT GetFormat() { return _format; }
+ GDX12SharedTexture* GetSharedTexture() override { return this; }
+ bool IsInitialized() override { return _isInitiliazed; }
+
+private:
+ GDX12Device* _transferFromDeivce;
+ GDX12Device* _transferToDevice;
+ UINT64 _heapSize;
+ ComPtr _sharedHeap;
+ GDX12TextureResource _sharedTexturePrimary;
+ GDX12TextureResource _sharedTextureSecondary;
+ DXGI_FORMAT _format;
+ UINT _width;
+ UINT _height;
+ bool _isInitiliazed;
+
+ void CreateSharedHeap()
+ {
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ desc.Alignment = 0;
+ desc.Width = _width;
+ desc.Height = _height;
+ desc.DepthOrArraySize = 1;
+ desc.MipLevels = 1;
+ desc.Format = _format;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+ desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;
+
+ D3D12_RESOURCE_ALLOCATION_INFO primaryInfo = _transferFromDeivce->GetDevice()->GetResourceAllocationInfo(0, 1, &desc);
+ D3D12_RESOURCE_ALLOCATION_INFO secondaryInfo = _transferToDevice->GetDevice()->GetResourceAllocationInfo(0, 1, &desc);
+
+ _heapSize = std::max(primaryInfo.SizeInBytes, secondaryInfo.SizeInBytes);
+ _heapSize = (_heapSize + D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT - 1) & ~(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT - 1);
+
+ D3D12_HEAP_DESC heapDesc = {};
+ heapDesc.SizeInBytes = _heapSize;
+ heapDesc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
+ heapDesc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ heapDesc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ heapDesc.Properties.CreationNodeMask = 1;
+ heapDesc.Properties.VisibleNodeMask = 1;
+ heapDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+ heapDesc.Flags = D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER;
+
+ ThrowIfFailed(_transferFromDeivce->GetDevice()->CreateHeap(
+ &heapDesc, IID_PPV_ARGS(&_sharedHeap)));
+ }
+
+ void CreatePlacedResources()
+ {
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ desc.Alignment = 0;
+ desc.Width = _width;
+ desc.Height = _height;
+ desc.DepthOrArraySize = 1;
+ desc.MipLevels = 1;
+ desc.Format = _format;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;
+
+ ThrowIfFailed(_transferFromDeivce->GetDevice()->CreatePlacedResource(
+ _sharedHeap.Get(), 0, &desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
+ IID_PPV_ARGS(&_sharedTexturePrimary.D3DResource)), "Failed to create placed resource on primary device");
+ }
+
+ void ShareResources()
+ {
+ HANDLE heapHandle = nullptr;
+ ThrowIfFailed(_transferFromDeivce->GetDevice()->CreateSharedHandle(
+ _sharedHeap.Get(), nullptr, GENERIC_ALL, nullptr,
+ &heapHandle));
+
+ if (!heapHandle) throw std::runtime_error("Failed to create shared handle (handle is null)");
+
+ Microsoft::WRL::ComPtr sharedHeapOnSecondary;
+ HRESULT hr = _transferToDevice->GetDevice()->OpenSharedHandle(
+ heapHandle,
+ IID_PPV_ARGS(&sharedHeapOnSecondary));
+
+ CloseHandle(heapHandle);
+ ThrowIfFailed(hr);
+
+ D3D12_RESOURCE_DESC desc = {};
+ desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ desc.Alignment = 0;
+ desc.Width = _width;
+ desc.Height = _height;
+ desc.DepthOrArraySize = 1;
+ desc.MipLevels = 1;
+ desc.Format = _format;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;
+
+ ThrowIfFailed(_transferToDevice->GetDevice()->CreatePlacedResource(
+ sharedHeapOnSecondary.Get(), 0, &desc, D3D12_RESOURCE_STATE_COMMON,
+ nullptr, IID_PPV_ARGS(&_sharedTextureSecondary.D3DResource)));
+ }
+};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12StreamlineSDK.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12StreamlineSDK.h
new file mode 100644
index 0000000..3201c02
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12StreamlineSDK.h
@@ -0,0 +1,130 @@
+#pragma once
+
+#include "Engine.RendererDX12/D3DHelpers.h"
+
+#include
+
+#ifdef free
+#pragma push_macro("free")
+#undef free
+#define PEP_RESTORE_FREE_MACRO_STREAMLINE 1
+#endif
+#include "nvidia-sdk/sl.h"
+#include "nvidia-sdk/sl_consts.h"
+#include "nvidia-sdk/sl_dlss.h"
+#include "nvidia-sdk/sl_helpers.h"
+#ifdef PEP_RESTORE_FREE_MACRO_STREAMLINE
+#pragma pop_macro("free")
+#undef PEP_RESTORE_FREE_MACRO_STREAMLINE
+#endif
+
+class GDX12StreamlineSDK
+{
+public:
+ static GDX12StreamlineSDK& Get();
+
+ bool Initialize();
+ void Shutdown();
+
+ bool IsEnabled() const;
+
+ static std::string ResultToString(sl::Result result);
+
+ ComPtr CreateProxyFactory(const ComPtr& nativeFactory) const;
+ ComPtr CreateProxyDevice(const ComPtr& nativeDevice, bool setAsMainDevice) const;
+ ComPtr GetNativeFactory(const ComPtr& factory) const;
+ ComPtr GetNativeDevice(const ComPtr& device) const;
+ ComPtr GetNativeCommandQueue(const ComPtr& commandQueue) const;
+ ComPtr GetNativeSwapChain(const ComPtr& swapChain) const;
+ ComPtr GetNativeResource(const ComPtr& resource) const;
+ sl::Result IsFeatureSupported(sl::Feature feature, const sl::AdapterInfo& adapterInfo) const;
+ sl::Result GetNewFrameToken(sl::FrameToken*& token, const uint32_t* frameIndex = nullptr) const;
+ sl::Result SetTagForFrame(const sl::FrameToken& frame, const sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer) const;
+ sl::Result EvaluateFeature(sl::Feature feature, const sl::FrameToken& frame, const sl::BaseStructure** inputs, uint32_t numInputs, sl::CommandBuffer* cmdBuffer) const;
+ sl::Result FreeResources(sl::Feature feature, const sl::ViewportHandle& viewport) const;
+ sl::Result SetConstants(const sl::Constants& values, const sl::FrameToken& frame, const sl::ViewportHandle& viewport) const;
+ sl::Result DLSSGetOptimalSettings(const sl::DLSSOptions& options, sl::DLSSOptimalSettings& settings) const;
+ sl::Result DLSSSetOptions(const sl::ViewportHandle& viewport, const sl::DLSSOptions& options) const;
+
+private:
+ GDX12StreamlineSDK() = default;
+
+ static void StreamlineLog(sl::LogType type, const char* message);
+
+ std::wstring GetRuntimeDirectory() const;
+ void LoadInterposer();
+ void LoadFunctions();
+ sl::Result LoadDLSSFunctions() const;
+
+ void Log(const std::string& message) const;
+ void LogWarning(const std::string& message) const;
+ void LogFailure(const char* operation, sl::Result result) const;
+
+ template
+ sl::Result LoadFeatureFunction(sl::Feature feature, const char* functionName, T*& function) const
+ {
+ if (function) { return sl::Result::eOk; }
+ if (!_initialized || !_slGetFeatureFunction) { return sl::Result::eErrorInvalidState; }
+
+ void* rawFunction = nullptr;
+ const sl::Result result = _slGetFeatureFunction(feature, functionName, rawFunction);
+ if (result == sl::Result::eOk) { function = reinterpret_cast(rawFunction); }
+
+ return result;
+ }
+
+ template
+ ComPtr UpgradeInterface(const ComPtr& baseInterface, const char* interfaceName) const
+ {
+ if (!_initialized || !_slUpgradeInterface || !baseInterface) { return baseInterface; }
+
+ T* upgradedInterface = baseInterface.Get();
+ const T* originalInterface = upgradedInterface;
+ const sl::Result result = _slUpgradeInterface(reinterpret_cast(&upgradedInterface));
+ if (result != sl::Result::eOk)
+ {
+ LogFailure(interfaceName, result);
+ return baseInterface;
+ }
+
+ if (!upgradedInterface || upgradedInterface == originalInterface) { return baseInterface; }
+
+ ComPtr proxyInterface;
+ proxyInterface.Attach(upgradedInterface);
+ return proxyInterface;
+ }
+
+ template
+ ComPtr UnwrapInterface(const ComPtr& proxyInterface) const
+ {
+ if (!_initialized || !_slGetNativeInterface || !proxyInterface) { return proxyInterface; }
+
+ T* nativeInterface = nullptr;
+ const sl::Result result = _slGetNativeInterface(proxyInterface.Get(), reinterpret_cast(&nativeInterface));
+ if (result != sl::Result::eOk || !nativeInterface) { return proxyInterface; }
+
+ ComPtr baseInterface;
+ baseInterface.Attach(nativeInterface);
+ return baseInterface;
+ }
+
+ HMODULE _interposerModule = nullptr;
+ bool _initialized = false;
+ bool _mainDeviceWasSet = false;
+ std::wstring _runtimeDirectory;
+
+ PFun_slInit* _slInit = nullptr;
+ PFun_slShutdown* _slShutdown = nullptr;
+ PFun_slUpgradeInterface* _slUpgradeInterface = nullptr;
+ PFun_slGetNativeInterface* _slGetNativeInterface = nullptr;
+ PFun_slSetD3DDevice* _slSetD3DDevice = nullptr;
+ PFun_slIsFeatureSupported* _slIsFeatureSupported = nullptr;
+ PFun_slGetFeatureFunction* _slGetFeatureFunction = nullptr;
+ PFun_slEvaluateFeature* _slEvaluateFeature = nullptr;
+ PFun_slFreeResources* _slFreeResources = nullptr;
+ PFun_slSetTagForFrame* _slSetTagForFrame = nullptr;
+ PFun_slSetConstants* _slSetConstants = nullptr;
+ PFun_slGetNewFrameToken* _slGetNewFrameToken = nullptr;
+ mutable PFun_slDLSSGetOptimalSettings* _slDLSSGetOptimalSettings = nullptr;
+ mutable PFun_slDLSSSetOptions* _slDLSSSetOptions = nullptr;
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SwapChain.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SwapChain.h
index 359624c..13e7460 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SwapChain.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12SwapChain.h
@@ -1,12 +1,13 @@
#pragma once
#include "Engine.RendererDX12/D3DHelpers.h"
+#include "Engine.RendererDX12/IRenderPassLink.h"
class GDX12Device;
class GDX12Texture;
class GDX12DescriptorHeap;
-class GDX12SwapChain
+class GDX12SwapChain : public IRenderPassLink
{
public:
GDX12SwapChain(GDX12Device* device, HWND hwnd,
@@ -25,15 +26,20 @@ class GDX12SwapChain
GDX12Texture* GetBuffer(UINT index);
D3D12_VIEWPORT GetViewport();
D3D12_RECT GetScissorRect();
-
+ GDX12Texture* GetTexture() override;
+ bool IsInitialized() override;
const ComPtr& GetSwapChain();
void Reset();
+ bool bVSyncEnabled;
+
private:
void CreateBuffers();
+ IDXGISwapChain4* GetPresentationSwapChain() const;
GDX12Device* _device;
+ ComPtr _proxySwapChain;
ComPtr _swapChain;
GDX12DescriptorHeap* _rtvHeap;
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Texture.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Texture.h
index 74a7805..6bb9693 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Texture.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12Texture.h
@@ -2,6 +2,9 @@
#include "Engine.RendererDX12\D3DHelpers.h"
+#include "Engine.Core/Types/TextureTypes.h"
+#include "Engine.RendererDX12/IRenderPassLink.h"
+
class GDX12Descriptor;
class GDX12DescriptorHeap;
class GDX12Device;
@@ -15,6 +18,22 @@ enum class ETextureSemantic
Data,
};
+namespace
+{
+ ETextureSemantic ConvertTextureSemantic(const Engine::Core::ETextureType textureType)
+ {
+ switch (textureType)
+ {
+ case Engine::Core::ETextureType::Color:
+ return ETextureSemantic::Color;
+ case Engine::Core::ETextureType::Data:
+ return ETextureSemantic::Data;
+ default:
+ return ETextureSemantic::Unknown;
+ }
+ }
+}
+
struct GDX12TextureDesc
{
GDX12DescriptorHeap* SRV_UAV_Heap = nullptr;
@@ -44,12 +63,14 @@ struct GDX12TextureDesc
ComPtr ExternalResource = nullptr;
};
-class GDX12Texture
+class GDX12Texture : public IRenderPassLink
{
public:
- GDX12Texture(GDX12TextureDesc desc);
+ GDX12Texture();
~GDX12Texture();
+ void Initialize(GDX12TextureDesc desc);
+
//Recreates resources with new size and same descriptors
//This will wipe all data on said resources, unless ExternalResource is provided
void Resize(UINT width, UINT height);
@@ -58,11 +79,20 @@ class GDX12Texture
GDX12Descriptor* GetRTV();
GDX12Descriptor* GetUAV();
GDX12Descriptor* GetDSV();
+ bool HasDSV();
+ bool HasSRV();
+ bool HasUAV();
+ bool HasRTV();
D3D12_CLEAR_VALUE& GetClearValue();
GDX12TextureResource* GetResource();
DXGI_FORMAT GetFormat();
ETextureSemantic GetSemantic() const;
-
+ D3D12_VIEWPORT GetViewport();
+ D3D12_RECT GetScissorRect();
+ UINT GetWidth();
+ UINT GetHeight();
+ GDX12Texture* GetTexture() override;
+ bool IsInitialized() override;
private:
void CreateResource();
@@ -77,4 +107,9 @@ class GDX12Texture
std::unique_ptr _uav;
std::unique_ptr _dsv;
D3D12_CLEAR_VALUE _clearValue;
+
+ D3D12_VIEWPORT _viewport;
+ D3D12_RECT _scissorRect;
+
+ bool _isInitialized;
};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12TextureResource.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12TextureResource.h
index 34de206..77408ac 100644
--- a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12TextureResource.h
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/GDX12TextureResource.h
@@ -7,6 +7,7 @@ class GDX12TextureResource : public GDX12Resource
{
public:
GDX12TextureResource(ComPtr resource);
+ GDX12TextureResource();
~GDX12TextureResource();
// Enhanced texture barrier transition getters
@@ -28,7 +29,7 @@ class GDX12TextureResource : public GDX12Resource
D3D12_BARRIER_ACCESS accessAfter, D3D12_BARRIER_LAYOUT layoutAfter);
void SetCurrentState(D3D12_BARRIER_SYNC sync, D3D12_BARRIER_ACCESS access, D3D12_BARRIER_LAYOUT layout);
-
+ void ResetState() override;
D3D12_BARRIER_SYNC GetCurrentSync();
D3D12_BARRIER_ACCESS GetCurrentAccess();
D3D12_BARRIER_LAYOUT GetCurrentLayout();
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/IRenderPassLink.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/IRenderPassLink.h
new file mode 100644
index 0000000..9ec233d
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/IRenderPassLink.h
@@ -0,0 +1,21 @@
+#pragma once
+
+class GDX12Texture;
+class GDX12SharedTexture;
+class RenderPipelineCommonData;
+
+class IRenderPassLink
+{
+public:
+ virtual GDX12Texture* GetTexture()
+ {
+ OutputDebugStringA("ERROR: Forbidden interface call\n");
+ return nullptr;
+ }
+ virtual GDX12SharedTexture* GetSharedTexture()
+ {
+ OutputDebugStringA("ERROR: Forbidden interface call\n");
+ return nullptr;
+ }
+ virtual bool IsInitialized() { return false; }
+};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12DLSSUpscalePass.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12DLSSUpscalePass.h
new file mode 100644
index 0000000..3410e1b
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12DLSSUpscalePass.h
@@ -0,0 +1,317 @@
+#pragma once
+#include "Engine.RendererDX12/RenderPasses/GDX12RenderPass.h"
+#include "Common/GameTimer.h"
+
+// HOLY SHIT
+// we need this crazy include since SL's free() function conflits with CRT library's free() function
+#ifdef free
+#pragma push_macro("free")
+#undef free
+#define PEP_RESTORE_FREE_MACRO_DLSS_PASS 1
+#endif
+#include "nvidia-sdk/sl.h"
+#include "nvidia-sdk/sl_consts.h"
+#include "nvidia-sdk/sl_dlss.h"
+#ifdef PEP_RESTORE_FREE_MACRO_DLSS_PASS
+#pragma pop_macro("free")
+#undef PEP_RESTORE_FREE_MACRO_DLSS_PASS
+#endif
+#include "Engine.RendererDX12/GDX12StreamlineSDK.h"
+
+class GDX12DLSSUpscalePass : public GDX12RenderPass
+{
+public:
+ GDX12DLSSUpscalePass() : IN_DepthBuffer(nullptr), IN_MotionVectors(nullptr), _viewportHandle(1337),
+ _DLSSQualityMode(sl::DLSSMode::eMaxQuality)
+ { _flags = RENDER_PASS_FLAG_UPSCALER | RENDER_PASS_FLAG_USE_JITTER | RENDER_PASS_FLAG_USE_STREAMLINE; }
+
+ virtual void SetInputs(std::vector inputs) override
+ {
+ _inputs = inputs;
+ _numInputs = 2;
+ MatchOutputCount(inputs.size() > 2 ? inputs.size() - 2 : 0);
+ }
+
+ IRenderPassLink* GetOutput(UINT index) override
+ {
+ if (_inputs.empty()) { MatchOutputCount(index + 1); }
+ return GDX12RenderPass::GetOutput(index);
+ }
+
+ // Input 0 - DepthStencil
+ // Input 1 - MotionVectors
+ // Input N - Input Texture
+ // Output N - UpscaledTexture
+ void Initialize() override
+ {
+ _commonData->Upscaler = this;
+
+ IN_DepthBuffer = _inputs[0];
+ IN_MotionVectors = _inputs[1];
+
+ GDX12TextureDesc TextureDesc1;
+ TextureDesc1.Width = _commonData->WindowWidth;
+ TextureDesc1.Height = _commonData->WindowHeight;
+
+ TextureDesc1.CreateSRV = true;
+ TextureDesc1.SRV_UAV_Heap = _resources->SRV_UAV_Heap.get();
+ TextureDesc1.SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ TextureDesc1.SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ TextureDesc1.SRVDesc.Texture2D.MipLevels = 1;
+ TextureDesc1.SRVDesc.Texture2D.MostDetailedMip = 0;
+ TextureDesc1.SRVDesc.Texture2D.PlaneSlice = 0;
+ TextureDesc1.SRVDesc.Texture2D.ResourceMinLODClamp = 0.0f;
+
+ IN_Textures.resize(_numOutputs);
+ for (UINT i = 0; i < _numOutputs; i++)
+ {
+ IN_Textures[i] = _inputs[i + 2];
+ GDX12Texture* inputTexture = IN_Textures[i]->GetTexture();
+ TextureDesc1.Format = TextureDesc1.RTVDesc.Format = TextureDesc1.SRVDesc.Format = inputTexture->GetFormat();
+ TextureDesc1.SRVHeapIndex = _resources->SRV_UAV_Heap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
+ OUT_UpscaledTextures[i]->Initialize(TextureDesc1);
+ }
+
+ }
+
+ void Setup(GDX12DeviceResources* initOnResources, GDX12DeviceResources* otherResources, RenderPipelineCommonData* commonData) override
+ {
+ GDX12RenderPass::Setup(initOnResources, otherResources, commonData);
+
+ CheckDLSSSupport();
+ QueryRenderTargetResolution();
+ CreateDLSSFeature();
+ }
+
+ void Execute(GDX12CommandList* cmdList) override
+ {
+ using namespace sl;
+
+ cmdList->BeginPixEvent("DLSS Upscale Pass", Colors::Blue);
+
+ FrameToken* currentFrame = nullptr;
+ Result result = GDX12StreamlineSDK::Get().GetNewFrameToken(currentFrame);
+ if (result != Result::eOk || currentFrame == nullptr)
+ {
+ std::string errorMsg = "DLSS: Failed to get a frame token: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ cmdList->EndPixEvent();
+ return;
+ }
+
+ SetConstants(currentFrame);
+
+ GDX12Texture* depthStencil = IN_DepthBuffer->GetTexture();
+ GDX12Texture* motionVectors = IN_MotionVectors->GetTexture();
+
+ Resource depthResource = Resource{ ResourceType::eTex2d,
+ depthStencil->GetResource()->D3DResource.Get(),
+ nullptr, nullptr, static_cast(depthStencil->GetResource()->GetCurrentState()) };
+
+ Resource mvecResource = Resource{ ResourceType::eTex2d,
+ motionVectors->GetResource()->D3DResource.Get(),
+ nullptr, nullptr, static_cast(motionVectors->GetResource()->GetCurrentState()) };
+
+ Extent fullExtent{};
+ fullExtent.top = 0;
+ fullExtent.left = 0;
+ fullExtent.width = _commonData->DownscaledWidth;
+ fullExtent.height = _commonData->DownscaledHeight;
+
+ Extent outputExtent{};
+ outputExtent.top = 0;
+ outputExtent.left = 0;
+ outputExtent.width = _commonData->WindowWidth;
+ outputExtent.height = _commonData->WindowHeight;
+
+ ResourceTag depthTag{ &depthResource, kBufferTypeDepth, ResourceLifecycle::eValidUntilEvaluate, &fullExtent };
+ ResourceTag mvecTag{ &mvecResource, kBufferTypeMotionVectors, ResourceLifecycle::eValidUntilEvaluate, &fullExtent };
+
+ for (int i = 0; i < _numOutputs; i++)
+ {
+ GDX12Texture* inputTexture = IN_Textures[i]->GetTexture();
+ GDX12Texture* upscaledTexture = OUT_UpscaledTextures[i].get();
+
+ Resource inputResource = Resource{ ResourceType::eTex2d,
+ inputTexture->GetResource()->D3DResource.Get(),
+ nullptr, nullptr, static_cast(inputTexture->GetResource()->GetCurrentState()) };
+
+ Resource outputResource = Resource{ ResourceType::eTex2d,
+ upscaledTexture->GetResource()->D3DResource.Get(),
+ nullptr, nullptr, static_cast(upscaledTexture->GetResource()->GetCurrentState()) };
+
+ ResourceTag inputTag{ &inputResource, kBufferTypeScalingInputColor, ResourceLifecycle::eValidUntilEvaluate, &fullExtent };
+ ResourceTag outputTag{ &outputResource, kBufferTypeScalingOutputColor, ResourceLifecycle::eValidUntilEvaluate, &outputExtent };
+
+ ResourceTag tags[] = { depthTag, mvecTag, inputTag, outputTag };
+ result = GDX12StreamlineSDK::Get().SetTagForFrame(*currentFrame, _viewportHandle, tags, _countof(tags), cmdList->GetCommandList().Get());
+ if (result != Result::eOk)
+ {
+ std::string errorMsg = "DLSS: Failed to set tags: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ }
+
+ const BaseStructure* inputs[] = { &_viewportHandle };
+ result = GDX12StreamlineSDK::Get().EvaluateFeature(kFeatureDLSS, *currentFrame, inputs, _countof(inputs), cmdList->GetCommandList().Get());
+ if (result != Result::eOk)
+ {
+ std::string errorMsg = "DLSS EVALUATE ERROR: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ }
+
+ }
+ cmdList->EndPixEvent();
+ }
+
+ void Resize() override
+ {
+ for (auto& texture : OUT_UpscaledTextures) { texture->Resize(_commonData->WindowWidth, _commonData->WindowHeight); }
+ GDX12StreamlineSDK::Get().FreeResources(sl::kFeatureDLSS, _viewportHandle);
+ GDX12StreamlineSDK::Get().DLSSSetOptions(_viewportHandle, sl::DLSSOptions{});
+ CreateDLSSFeature();
+ }
+
+ void QueryRenderTargetResolution() override
+ {
+ using namespace sl;
+
+ DLSSOptions dlssOptions = {};
+ dlssOptions.mode = _DLSSQualityMode;
+ dlssOptions.outputWidth = _commonData->WindowWidth;
+ dlssOptions.outputHeight = _commonData->WindowHeight;
+
+ DLSSOptimalSettings optimalSettings = {};
+ Result result = GDX12StreamlineSDK::Get().DLSSGetOptimalSettings(dlssOptions, optimalSettings);
+ if (result != Result::eOk)
+ {
+ std::string errorMsg = "DLSS: Failed to get optimal settings: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ _commonData->DownscaledWidth = _commonData->WindowWidth;
+ _commonData->DownscaledHeight = _commonData->WindowHeight;
+ return;
+ }
+
+ if (optimalSettings.optimalRenderWidth == 0 || optimalSettings.optimalRenderHeight == 0)
+ {
+ OutputDebugStringA("DLSS: Optimal settings returned a zero-sized render resolution, falling back to full-resolution rendering.\n");
+ _commonData->DownscaledWidth = _commonData->WindowWidth;
+ _commonData->DownscaledHeight = _commonData->WindowHeight;
+ return;
+ }
+
+ _commonData->DownscaledWidth = optimalSettings.optimalRenderWidth;
+ _commonData->DownscaledHeight = optimalSettings.optimalRenderHeight;
+ }
+
+ void ClearDenendencies() override
+ {
+ GDX12RenderPass::ClearDenendencies();
+ GDX12StreamlineSDK::Get().FreeResources(sl::kFeatureDLSS, _viewportHandle);
+ IN_DepthBuffer = nullptr;
+ IN_MotionVectors = nullptr;
+ IN_Textures.clear();
+ OUT_UpscaledTextures.clear();
+ }
+
+private:
+ IRenderPassLink* IN_DepthBuffer;
+ IRenderPassLink* IN_MotionVectors;
+ std::vector IN_Textures;
+ std::vector> OUT_UpscaledTextures;
+ sl::ViewportHandle _viewportHandle;
+ sl::DLSSMode _DLSSQualityMode;
+
+ void MatchOutputCount(UINT outputCount)
+ {
+ if (OUT_UpscaledTextures.size() < outputCount) { OUT_UpscaledTextures.resize(outputCount); }
+ if (_outputs.size() < outputCount) { _outputs.resize(outputCount, nullptr); }
+
+ for (UINT i = 0; i < outputCount; i++)
+ {
+ if (!OUT_UpscaledTextures[i]) { OUT_UpscaledTextures[i] = std::make_unique(); }
+ _outputs[i] = OUT_UpscaledTextures[i].get();
+ }
+
+ _numOutputs = outputCount;
+ }
+
+ bool CheckDLSSSupport()
+ {
+ using namespace sl;
+
+ LUID adapterLuid = _resources->Device->GetDevice()->GetAdapterLuid();
+ AdapterInfo adapterInfo = {};
+ adapterInfo.deviceLUID = reinterpret_cast(&adapterLuid);
+ adapterInfo.deviceLUIDSizeInBytes = sizeof(adapterLuid);
+
+ Result result = GDX12StreamlineSDK::Get().IsFeatureSupported(kFeatureDLSS, adapterInfo);
+ if (result == Result::eOk) { return true; }
+
+ std::string errorMsg = "ERROR: DLSS Feature is not supported on the current adapter: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ return false;
+ }
+
+ void SetConstants(sl::FrameToken* currentFrameToken)
+ {
+ using namespace sl;
+
+ Constants constants = {};
+
+ //expects row major unjittered matrices
+ constants.cameraViewToClip = *reinterpret_cast(&_commonData->CameraViewToClip);
+ constants.clipToCameraView = *reinterpret_cast(&_commonData->ClipToCameraView);
+ constants.clipToPrevClip = *reinterpret_cast(&_commonData->ClipToPrevClip);
+ constants.prevClipToClip = *reinterpret_cast(&_commonData->PrevClipToClip);
+
+ constants.cameraNear = _commonData->ActiveCameraNearPlane;
+ constants.cameraFar = _commonData->ActiveCameraFarPlane;
+ constants.cameraFOV = XMConvertToRadians(_commonData->ActiveCameraFOV);
+ constants.cameraAspectRatio = static_cast(_commonData->WindowWidth) / _commonData->WindowHeight;
+
+ constants.jitterOffset = { -_commonData->ActiveCameraJitterOffsetX, -_commonData->ActiveCameraJitterOffsetY };
+ constants.mvecScale = { 1.f, 1.f };
+
+ constants.depthInverted = Boolean::eTrue;
+ constants.cameraMotionIncluded = Boolean::eTrue;
+ constants.motionVectors3D = Boolean::eFalse;
+ constants.reset = Boolean::eFalse;
+ constants.orthographicProjection = Boolean::eFalse;
+ constants.motionVectorsDilated = Boolean::eFalse;
+ constants.motionVectorsJittered = Boolean::eFalse;
+
+ Result result = GDX12StreamlineSDK::Get().SetConstants(constants, *currentFrameToken, _viewportHandle);
+ if (result != Result::eOk)
+ {
+ std::string errorMsg = "DLSS: Failed to set constants: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ }
+ }
+
+ void CreateDLSSFeature()
+ {
+ using namespace sl;
+
+ // Create DLSS feature
+ DLSSOptions dlssOptions = {};
+ dlssOptions.mode = _DLSSQualityMode;
+ dlssOptions.outputWidth = _commonData->WindowWidth;
+ dlssOptions.outputHeight = _commonData->WindowHeight;
+ dlssOptions.sharpness = 0.25f;
+ dlssOptions.colorBuffersHDR = Boolean::eFalse;
+
+ Result result = GDX12StreamlineSDK::Get().DLSSSetOptions(_viewportHandle, dlssOptions);
+ if (result != Result::eOk)
+ {
+ std::string errorMsg = "ERROR: Failed to set DLSS options: " + SLResultToString(result) + "\n";
+ OutputDebugStringA(errorMsg.c_str());
+ return;
+ }
+
+ }
+
+ std::string SLResultToString(sl::Result result)
+ {
+ return GDX12StreamlineSDK::ResultToString(result);
+ }
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12FSRUpscalePass.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12FSRUpscalePass.h
new file mode 100644
index 0000000..c047854
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12FSRUpscalePass.h
@@ -0,0 +1,222 @@
+#pragma once
+#include "Engine.RendererDX12/RenderPasses/GDX12RenderPass.h"
+#include "Common/GameTimer.h"
+
+#include "ffx-api/ffx_api.h"
+#include "ffx-api/ffx_upscale.h"
+#include "ffx-api/dx12/ffx_api_dx12.h"
+
+class GDX12FSRUpscalePass : public GDX12RenderPass
+{
+public:
+ GDX12FSRUpscalePass() : IN_DepthBuffer(nullptr), IN_MotionVectors(nullptr), _FFXContext(nullptr),
+ _FSRQualityMode(FFX_UPSCALE_QUALITY_MODE_QUALITY)
+ { _flags = RENDER_PASS_FLAG_UPSCALER | RENDER_PASS_FLAG_USE_JITTER; }
+
+ virtual void SetInputs(std::vector inputs) override
+ {
+ _inputs = inputs;
+ _numInputs = 2;
+ MatchOutputCount(inputs.size() > 2 ? inputs.size() - 2 : 0);
+ }
+
+ IRenderPassLink* GetOutput(UINT index) override
+ {
+ if (_inputs.empty()) { MatchOutputCount(index + 1); }
+ return GDX12RenderPass::GetOutput(index);
+ }
+
+ // Input 0 - DepthStencil
+ // Input 1 - MotionVectors
+ // Input N - Input Texture
+ // Output N - UpscaledTexture
+ void Initialize() override
+ {
+ _commonData->Upscaler = this;
+
+ IN_DepthBuffer = _inputs[0];
+ IN_MotionVectors = _inputs[1];
+
+ GDX12TextureDesc TextureDesc1;
+ TextureDesc1.Width = _commonData->WindowWidth;
+ TextureDesc1.Height = _commonData->WindowHeight;
+
+ TextureDesc1.CreateSRV = true;
+ TextureDesc1.SRV_UAV_Heap = _resources->SRV_UAV_Heap.get();
+ TextureDesc1.SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ TextureDesc1.SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ TextureDesc1.SRVDesc.Texture2D.MipLevels = 1;
+ TextureDesc1.SRVDesc.Texture2D.MostDetailedMip = 0;
+ TextureDesc1.SRVDesc.Texture2D.PlaneSlice = 0;
+ TextureDesc1.SRVDesc.Texture2D.ResourceMinLODClamp = 0.0f;
+
+ IN_Textures.resize(_numOutputs);
+ for (UINT i = 0; i < _numOutputs; i++)
+ {
+ IN_Textures[i] = _inputs[i + 2];
+ GDX12Texture* inputTexture = IN_Textures[i]->GetTexture();
+ TextureDesc1.Format = TextureDesc1.RTVDesc.Format = TextureDesc1.SRVDesc.Format = inputTexture->GetFormat();
+ TextureDesc1.SRVHeapIndex = _resources->SRV_UAV_Heap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
+ OUT_UpscaledTextures[i]->Initialize(TextureDesc1);
+ }
+
+ }
+
+ void Setup(GDX12DeviceResources* initOnResources, GDX12DeviceResources* otherResources, RenderPipelineCommonData* commonData) override
+ {
+ GDX12RenderPass::Setup(initOnResources, otherResources, commonData);
+
+ BuildFSRContext();
+ QueryRenderTargetResolution();
+ }
+
+ void Execute(GDX12CommandList* cmdList) override
+ {
+ GDX12Texture* depthStencil = IN_DepthBuffer->GetTexture();
+ GDX12Texture* motionVectors = IN_MotionVectors->GetTexture();
+
+ cmdList->BeginPixEvent("FSR Upscale Pass", Colors::Blue);
+ ffxDispatchDescUpscale dispatchDesc;
+ dispatchDesc.header.type = FFX_API_DISPATCH_DESC_TYPE_UPSCALE;
+ dispatchDesc.commandList = cmdList->GetCommandList().Get();
+ dispatchDesc.depth = ffxApiGetResourceDX12(depthStencil->GetResource()->D3DResource.Get(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ dispatchDesc.motionVectors = ffxApiGetResourceDX12(motionVectors->GetResource()->D3DResource.Get(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ // Resolution before upscaling
+ dispatchDesc.renderSize = { _commonData->DownscaledWidth, _commonData->DownscaledHeight };
+ dispatchDesc.motionVectorScale = { static_cast(_commonData->DownscaledWidth),
+ static_cast(_commonData->DownscaledHeight) };
+ dispatchDesc.upscaleSize = { _commonData->WindowWidth, _commonData->WindowHeight };
+ // We use inverted depth, this is not a mistake
+ dispatchDesc.cameraNear = _commonData->ActiveCameraFarPlane;
+ dispatchDesc.cameraFar = _commonData->ActiveCameraNearPlane;
+ dispatchDesc.cameraFovAngleVertical = XMConvertToRadians(_commonData->ActiveCameraFOV);
+
+ dispatchDesc.jitterOffset.x = -_commonData->ActiveCameraJitterOffsetX;
+ dispatchDesc.jitterOffset.y = -_commonData->ActiveCameraJitterOffsetY;
+
+ dispatchDesc.enableSharpening = true;
+ dispatchDesc.sharpness = 1.f;
+ // for whatever reason, it doesnt like it when frame time is lower than 1.f
+ float clampedTime = std::max(_commonData->GameTimer->DeltaTime() * 1000.f, 1.f);
+ dispatchDesc.frameTimeDelta = clampedTime; //expects milliseconds
+ dispatchDesc.reset = false; // set to true if camera teleports or moves not smoothly
+
+ dispatchDesc.preExposure = 1.f;
+ dispatchDesc.viewSpaceToMetersFactor = 1.f;
+
+ dispatchDesc.exposure = ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ dispatchDesc.reactive = ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ dispatchDesc.transparencyAndComposition = ffxApiGetResourceDX12(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ //dispatchDesc.flags = FFX_UPSCALE_FLAG_DRAW_DEBUG_VIEW;
+ dispatchDesc.flags = 0;
+ for (int i = 0; i < _numOutputs; i++)
+ {
+ GDX12Texture* inputTexture = IN_Textures[i]->GetTexture();
+ GDX12Texture* upscaledTexture = OUT_UpscaledTextures[i].get();
+ dispatchDesc.color = ffxApiGetResourceDX12(inputTexture->GetResource()->D3DResource.Get(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ);
+ dispatchDesc.output = ffxApiGetResourceDX12(upscaledTexture->GetResource()->D3DResource.Get(), FFX_API_RESOURCE_STATE_UNORDERED_ACCESS);
+
+ ffxReturnCode_t dispatchError = ffxDispatch(&_FFXContext, &dispatchDesc.header);
+ if (dispatchError != FFX_API_RETURN_OK)
+ {
+ std::string errorMsg = "FSR DISPATCH ERROR: " + std::to_string(dispatchError) + " \n";
+ OutputDebugStringA(errorMsg.c_str());
+ }
+ }
+ cmdList->EndPixEvent();
+ }
+
+ void Resize() override
+ {
+ for (auto& texture : OUT_UpscaledTextures) { texture->Resize(_commonData->WindowWidth, _commonData->WindowHeight); }
+ ffxDestroyContext(&_FFXContext, nullptr);
+ BuildFSRContext();
+ }
+
+ void QueryRenderTargetResolution() override
+ {
+ ffxQueryDescUpscaleGetRenderResolutionFromQualityMode queryDesc = {};
+ queryDesc.header.type = FFX_API_QUERY_DESC_TYPE_UPSCALE_GETRENDERRESOLUTIONFROMQUALITYMODE;
+ queryDesc.displayHeight = _commonData->WindowHeight;
+ queryDesc.displayWidth = _commonData->WindowWidth;
+ queryDesc.qualityMode = _FSRQualityMode;
+ queryDesc.pOutRenderHeight = &_commonData->DownscaledHeight;
+ queryDesc.pOutRenderWidth = &_commonData->DownscaledWidth;
+ ffxQuery(&_FFXContext, &queryDesc.header);
+ }
+
+ void ClearDenendencies() override
+ {
+ GDX12RenderPass::ClearDenendencies();
+
+ if (_FFXContext) { ffxDestroyContext(&_FFXContext, nullptr); }
+ IN_DepthBuffer = nullptr;
+ IN_MotionVectors = nullptr;
+ IN_Textures.clear();
+ OUT_UpscaledTextures.clear();
+ }
+
+private:
+ IRenderPassLink* IN_DepthBuffer;
+ IRenderPassLink* IN_MotionVectors;
+ std::vector IN_Textures;
+ std::vector> OUT_UpscaledTextures;
+ ffxContext _FFXContext;
+ FfxApiUpscaleQualityMode _FSRQualityMode;
+
+ void MatchOutputCount(UINT outputCount)
+ {
+ if (OUT_UpscaledTextures.size() < outputCount) { OUT_UpscaledTextures.resize(outputCount); }
+ if (_outputs.size() < outputCount) { _outputs.resize(outputCount, nullptr); }
+
+ for (UINT i = 0; i < outputCount; i++)
+ {
+ if (!OUT_UpscaledTextures[i]) { OUT_UpscaledTextures[i] = std::make_unique(); }
+ _outputs[i] = OUT_UpscaledTextures[i].get();
+ }
+
+ _numOutputs = outputCount;
+ }
+
+ void BuildFSRContext()
+ {
+ ffxCreateBackendDX12Desc backendDesc = {};
+ backendDesc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12;
+ backendDesc.device = _resources->Device->GetDevice().Get();
+
+ ffxCreateContextDescUpscale upscaleDesc = {};
+ upscaleDesc.header.type = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
+ upscaleDesc.header.pNext = &backendDesc.header;
+ upscaleDesc.maxRenderSize = { static_cast(_commonData->WindowWidth), static_cast(_commonData->WindowHeight) };
+ upscaleDesc.maxUpscaleSize = { static_cast(_commonData->WindowWidth), static_cast(_commonData->WindowHeight) };
+ upscaleDesc.flags = FFX_UPSCALE_ENABLE_DEBUG_CHECKING | FFX_UPSCALE_ENABLE_DEPTH_INVERTED;
+ upscaleDesc.fpMessage = [](uint32_t type, const wchar_t* message)
+ {
+ std::wstring wideMessage(message);
+ std::string narrowMessage(wideMessage.begin(), wideMessage.end());
+
+ std::string prefix;
+ switch (type) {
+ case FFX_API_MESSAGE_TYPE_ERROR:
+ prefix = "[FFX ERROR] ";
+ break;
+ case FFX_API_MESSAGE_TYPE_WARNING:
+ prefix = "[FFX WARNING] ";
+ break;
+ default:
+ prefix = "[FFX DEBUG] ";
+ break;
+ }
+
+ std::string fullMessage = prefix + narrowMessage + "\n";
+ OutputDebugStringA(fullMessage.c_str());
+ };
+
+ ffxReturnCode_t errorCode = ffxCreateContext(&_FFXContext, &upscaleDesc.header, nullptr);
+ if (errorCode != FFX_API_RETURN_OK)
+ {
+ std::string errorMsg = "ERROR: FSR3 CONTEXT CREATION FAILED\n";
+ OutputDebugStringA(errorMsg.c_str());
+ }
+ }
+};
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12GPUCullingPass.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12GPUCullingPass.h
new file mode 100644
index 0000000..c19f414
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12GPUCullingPass.h
@@ -0,0 +1,104 @@
+#pragma once
+#include "Engine.RendererDX12/RenderPasses/GDX12RenderPass.h"
+
+class GDX12GPUCullingPass : public GDX12RenderPass
+{
+public:
+ GDX12GPUCullingPass()
+ { _flags = RENDER_PASS_FLAG_USE_CAMERAS | RENDER_PASS_FLAG_USE_INSTANCES; }
+
+ void Setup(GDX12DeviceResources* initOnResources, GDX12DeviceResources* otherResources, RenderPipelineCommonData* commonData) override
+ {
+ GDX12RenderPass::Setup(initOnResources, otherResources, commonData);
+
+ // Shaders
+ auto& shaderCompiler = GDX12ShaderCompiler::GetInstance();
+ _cullingCS = shaderCompiler.CompileShader(_resources->Device, SHADERS_FOLDER "Culling.hlsl", nullptr, "CS", "cs");
+ _bufferClearCS = shaderCompiler.CompileShader(_resources->Device, SHADERS_FOLDER "BufferClear.hlsl", nullptr, "CS", "cs");
+
+ // Root Signatures
+ GDX12RootSignatureDesc RSDesc1;
+ RSDesc1.NumSingleCBVSlots = 1;
+ RSDesc1.NumSingleSRVSlots = 3;
+ RSDesc1.NumSingleUAVSlots = 4;
+ _cullingRS = std::make_unique(_resources->Device, RSDesc1);
+
+ GDX12RootSignatureDesc RSDesc2;
+ RSDesc2.NumSingleUAVSlots = 2;
+ _bufferClearRS = std::make_unique(_resources->Device, RSDesc2);
+
+ // Pipeline State Objects
+ D3D12_COMPUTE_PIPELINE_STATE_DESC PSODesc1 = {};
+ PSODesc1.pRootSignature = _cullingRS->GetRootSignature().Get();
+ PSODesc1.CS = { reinterpret_cast(_cullingCS->GetBufferPointer()), _cullingCS->GetBufferSize() };
+
+ ThrowIfFailed(_resources->Device->GetDevice()->CreateComputePipelineState(
+ &PSODesc1, IID_PPV_ARGS(&_cullingPSO)));
+
+ D3D12_COMPUTE_PIPELINE_STATE_DESC PSODesc2 = {};
+ PSODesc2.pRootSignature = _bufferClearRS->GetRootSignature().Get();
+ PSODesc2.CS = { reinterpret_cast(_bufferClearCS->GetBufferPointer()), _bufferClearCS->GetBufferSize() };
+
+ ThrowIfFailed(_resources->Device->GetDevice()->CreateComputePipelineState(
+ &PSODesc2, IID_PPV_ARGS(&_bufferClearPSO)));
+ }
+
+ // automatically uses IN_OUT_CameraVisibilityBuffers from cameraCBIndex
+ void Execute(GDX12CommandList* cmdList) override
+ {
+ auto& currentFrameConstants = _resources->FrameConstants[_resources->CurrFrameConstantsIndex];
+ auto& currentCameraVisBuffers = currentFrameConstants->CameraVisibilityCommands[_commonData->ActiveCameraCBufferIndex];
+
+ cmdList->BeginPixEvent("GPU Mesh Culling", Colors::Blue);
+ cmdList->ResourceBarrier({
+ currentCameraVisBuffers.VisibleOpaqueCommandsCache->GetResource().GetUnorderedAccessBarrier(),
+ currentCameraVisBuffers.OpaqueDrawCounter->GetResource().GetUnorderedAccessBarrier(),
+ currentCameraVisBuffers.VisibleTransparentCommandsCache->GetResource().GetUnorderedAccessBarrier(),
+ currentCameraVisBuffers.TransparentDrawCounter->GetResource().GetUnorderedAccessBarrier() });
+
+ cmdList->SetComputeRootSignature(_bufferClearRS.get());
+ cmdList->SetPipelineState(_bufferClearPSO);
+ cmdList->SetDescriptorHeaps({ _resources->SRV_UAV_Heap.get() });
+ cmdList->SetComputeUAV(0, currentCameraVisBuffers.OpaqueDrawCounter->GetUAV()->GPUHandle);
+ cmdList->SetComputeUAV(1, currentCameraVisBuffers.TransparentDrawCounter->GetUAV()->GPUHandle);
+ cmdList->Dispatch(1, 1, 1);
+
+ cmdList->SetComputeRootSignature(_cullingRS.get());
+ cmdList->SetPipelineState(_cullingPSO);
+ cmdList->SetDescriptorHeaps({ _resources->SRV_UAV_Heap.get() });
+ cmdList->SetComputeRootConstantBufferView(0, currentFrameConstants->CameraCB->GetElementAddress(_commonData->ActiveCameraCBufferIndex));
+ cmdList->SetComputeSRV(0, currentFrameConstants->InstanceCache->GetSRV()->GPUHandle);
+ cmdList->SetComputeSRV(1, _resources->IndirectCommandsCache->GetSRV()->GPUHandle);
+ cmdList->SetComputeSRV(2, currentFrameConstants->MaterialCache->GetSRV()->GPUHandle);
+ cmdList->SetComputeUAV(0, currentCameraVisBuffers.VisibleOpaqueCommandsCache->GetUAV()->GPUHandle);
+ cmdList->SetComputeUAV(1, currentCameraVisBuffers.OpaqueDrawCounter->GetUAV()->GPUHandle);
+ cmdList->SetComputeUAV(2, currentCameraVisBuffers.VisibleTransparentCommandsCache->GetUAV()->GPUHandle);
+ cmdList->SetComputeUAV(3, currentCameraVisBuffers.TransparentDrawCounter->GetUAV()->GPUHandle);
+ cmdList->Dispatch((_resources->IndirectCommandsCache->GetElementCount() + 63) / 64, 1, 1);
+
+ cmdList->ResourceBarrier({
+ currentCameraVisBuffers.VisibleOpaqueCommandsCache->GetResource().GetUAVBarrier(),
+ currentCameraVisBuffers.OpaqueDrawCounter->GetResource().GetUAVBarrier() });
+ cmdList->EndPixEvent();
+ }
+
+ void ClearDenendencies() override
+ {
+ GDX12RenderPass::ClearDenendencies();
+
+ _cullingRS.reset();
+ _cullingPSO.Reset();
+ _bufferClearCS.Reset();
+ _bufferClearRS.reset();
+ _bufferClearPSO.Reset();
+ }
+
+private:
+ ComPtr _cullingCS;
+ std::unique_ptr _cullingRS;
+ ComPtr _cullingPSO;
+
+ ComPtr _bufferClearCS;
+ std::unique_ptr _bufferClearRS;
+ ComPtr _bufferClearPSO;
+};
\ No newline at end of file
diff --git a/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12OpaquePass.h b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12OpaquePass.h
new file mode 100644
index 0000000..4e6cd6a
--- /dev/null
+++ b/Engine/Engine.RendererDX12/Include/Engine.RendererDX12/RenderPasses/GDX12OpaquePass.h
@@ -0,0 +1,204 @@
+#pragma once
+#include "Engine.RendererDX12/RenderPasses/GDX12RenderPass.h"
+
+class GDX12OpaquePass : public GDX12RenderPass
+{
+public:
+ GDX12OpaquePass()
+ {
+ _flags = RENDER_PASS_FLAG_USE_CAMERAS | RENDER_PASS_FLAG_USE_GEOMETRY | RENDER_PASS_FLAG_USE_MATERIALS
+ | RENDER_PASS_FLAG_USE_INSTANCES;
+ _numInputs = 0;
+ _numOutputs = 3;
+ OUT_Accumulation = std::make_unique();
+ OUT_VelocityBuffer = std::make_unique();
+ OUT_DepthStencil = std::make_unique();
+
+ _outputs.push_back(OUT_Accumulation.get());
+ _outputs.push_back(OUT_VelocityBuffer.get());
+ _outputs.push_back(OUT_DepthStencil.get());
+ }
+
+ // Output 0 - AccumulationTexture
+ // Output 1 - MotionVectors
+ // Output 2 - DepthStencil
+ void Initialize() override
+ {
+ GDX12TextureDesc TextureDesc1;
+ TextureDesc1.Format = TextureDesc1.RTVDesc.Format = TextureDesc1.SRVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ TextureDesc1.Width = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledWidth : _commonData->WindowWidth;
+ TextureDesc1.Height = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledHeight : _commonData->WindowHeight;
+
+ TextureDesc1.CreateSRV = true;
+ TextureDesc1.SRV_UAV_Heap = _resources->SRV_UAV_Heap.get();
+ TextureDesc1.SRVHeapIndex = _resources->SRV_UAV_Heap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
+ TextureDesc1.SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ TextureDesc1.SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+ TextureDesc1.SRVDesc.Texture2D.MipLevels = 1;
+ TextureDesc1.SRVDesc.Texture2D.MostDetailedMip = 0;
+ TextureDesc1.SRVDesc.Texture2D.PlaneSlice = 0;
+ TextureDesc1.SRVDesc.Texture2D.ResourceMinLODClamp = 0.0f;
+
+ TextureDesc1.CreateRTV = true;
+ TextureDesc1.RTVHeap = _resources->RTVHeap.get();
+ TextureDesc1.RTVHeapIndex = _resources->RTVHeap->GetAvailableIndex();
+ TextureDesc1.RTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
+ TextureDesc1.RTVDesc.Texture2D.PlaneSlice = 0;
+ TextureDesc1.RTVDesc.Texture2D.MipSlice = 0;
+
+ OUT_Accumulation->Initialize(TextureDesc1);
+
+ TextureDesc1.Format = TextureDesc1.RTVDesc.Format = TextureDesc1.SRVDesc.Format = DXGI_FORMAT_R16G16_FLOAT;
+ TextureDesc1.RTVHeapIndex = _resources->RTVHeap->GetAvailableIndex();
+ TextureDesc1.SRVHeapIndex = _resources->SRV_UAV_Heap->GetAvailableIndex(TextureResources_StartIndex, TextureResources_RangeLength);
+
+ OUT_VelocityBuffer->Initialize(TextureDesc1);
+
+ GDX12TextureDesc desc;
+ desc.CreateSRV = false;
+ desc.DSVHeap = _resources->DSVHeap.get();
+
+ desc.CreateDSV = true;
+ desc.DSVHeapIndex = _resources->DSVHeap->GetAvailableIndex();
+ desc.Format = desc.DSVDesc.Format = DXGI_FORMAT_D32_FLOAT;
+ desc.Width = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledWidth : _commonData->WindowWidth;;
+ desc.Height = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledHeight : _commonData->WindowHeight;;
+ desc.ClearValue = { 0.f, 0.f, 0.f, 0.f };
+
+ desc.DSVDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
+ desc.DSVDesc.Texture2D.MipSlice = 0;
+
+ OUT_DepthStencil->Initialize(desc);
+
+ // Shaders
+ auto& shaderCompiler = GDX12ShaderCompiler::GetInstance();
+ _opaqueVS = shaderCompiler.CompileShader(_resources->Device, SHADERS_FOLDER "OpaquePass.hlsl", nullptr, "VS", "vs");
+ _opaquePS = shaderCompiler.CompileShader(_resources->Device, SHADERS_FOLDER "OpaquePass.hlsl", nullptr, "PS", "ps");
+
+ // Root Signatures
+ GDX12RootSignatureDesc RSDesc1;
+ RSDesc1.NumSingleCBVSlots = 2;
+ RSDesc1.NumSingleSRVSlots = 3;
+ RSDesc1.StaticSamplers = GetStaticSamplers();
+ RSDesc1.SRVRanges.push_back(GDX12RootSignatureRange(Texture2D_RangeLength));
+ RSDesc1.Constants.push_back(1);
+ _opaqueRS = std::make_unique(_resources->Device, RSDesc1);
+
+ //Command Signatures
+ std::vector args;
+ D3D12_INDIRECT_ARGUMENT_DESC argConst = {};
+ argConst.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
+ argConst.Constant.DestOffsetIn32BitValues = 0;
+ argConst.Constant.Num32BitValuesToSet = 1;
+ args.push_back(argConst);
+ D3D12_INDIRECT_ARGUMENT_DESC argDraw = {};
+ argDraw.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
+ args.push_back(argDraw);
+
+ D3D12_COMMAND_SIGNATURE_DESC CSDesc1 = {};
+ CSDesc1.ByteStride = sizeof(GDX12IndirectDrawArgs);
+ CSDesc1.NumArgumentDescs = args.size();
+ CSDesc1.pArgumentDescs = args.data();
+ CSDesc1.NodeMask = 0;
+
+ _resources->Device->GetDevice()->CreateCommandSignature(&CSDesc1,
+ _opaqueRS->GetRootSignature().Get(),
+ IID_PPV_ARGS(&_opaqueCS));
+
+ // Pipeline State Objects
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC PSODesc1 = {};
+
+ PSODesc1.InputLayout = { _resources->InputLayouts["Default"].data(), (UINT)_resources->InputLayouts["Default"].size() };
+ PSODesc1.pRootSignature = _opaqueRS->GetRootSignature().Get();
+ PSODesc1.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
+ PSODesc1.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
+ PSODesc1.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
+ //reversed-Z
+ PSODesc1.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
+ PSODesc1.RasterizerState.FrontCounterClockwise = TRUE;
+ PSODesc1.SampleMask = UINT_MAX;
+ PSODesc1.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ PSODesc1.NumRenderTargets = 2;
+ PSODesc1.RTVFormats[0] = OUT_Accumulation->GetFormat();
+ PSODesc1.RTVFormats[1] = OUT_VelocityBuffer->GetFormat();
+ PSODesc1.SampleDesc.Count = 1;
+ PSODesc1.SampleDesc.Quality = 0;
+ PSODesc1.DSVFormat = OUT_DepthStencil->GetTexture()->GetFormat();
+ PSODesc1.VS = { reinterpret_cast(_opaqueVS->GetBufferPointer()), _opaqueVS->GetBufferSize() };
+ PSODesc1.PS = { reinterpret_cast(_opaquePS->GetBufferPointer()), _opaquePS->GetBufferSize() };
+ ThrowIfFailed(_resources->Device->GetDevice()->CreateGraphicsPipelineState(&PSODesc1, IID_PPV_ARGS(&_opaquePSO)));
+ }
+
+ // VisibilityBuffers will automatically be selected from CameraCBIndex
+ // It requires GPUCullingPass to be executed beforehand
+ void Execute(GDX12CommandList* cmdList) override
+ {
+ auto& currentFrameConstants = _resources->FrameConstants[_resources->CurrFrameConstantsIndex];
+ auto& currentCameraVisBuffers = currentFrameConstants->CameraVisibilityCommands[_commonData->ActiveCameraCBufferIndex];
+ GDX12Texture* depthStencil = OUT_DepthStencil->GetTexture();
+
+ cmdList->BeginPixEvent("Opaque Render Pass", Colors::ForestGreen);
+ cmdList->SetViewport(OUT_Accumulation->GetViewport());
+ cmdList->SetScissorRect(OUT_Accumulation->GetScissorRect());
+ cmdList->SetGraphicsRootSignature(_opaqueRS.get());
+ cmdList->SetPipelineState(_opaquePSO.Get());
+ cmdList->SetGraphicsRootConstantBufferView(1, currentFrameConstants->MainCB->GetElementAddress(0));
+ cmdList->SetGraphicsRootConstantBufferView(2, currentFrameConstants->CameraCB->
+ GetElementAddress(_commonData->ActiveCameraCBufferIndex));
+ cmdList->SetGeometryBuffer(_resources->GeometryBuffer.get());
+ cmdList->SetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ cmdList->SetDescriptorHeaps({ _resources->SRV_UAV_Heap.get() });
+ cmdList->SetGraphicsSRV(0, currentFrameConstants->MaterialCache->GetSRV()->GPUHandle);
+ cmdList->SetGraphicsSRV(1, currentFrameConstants->TransformCache->GetSRV()->GPUHandle);
+ cmdList->SetGraphicsSRV(2, currentFrameConstants->InstanceCache->GetSRV()->GPUHandle);
+ cmdList->SetGraphicsSRV(3, _resources->SRV_UAV_Heap->GetGPUHandle(Texture2D_StartIndex));
+ cmdList->ResourceBarrier({
+ currentCameraVisBuffers.VisibleOpaqueCommandsCache->GetResource().GetIndirectArgsBarrier(),
+ currentCameraVisBuffers.OpaqueDrawCounter->GetResource().GetIndirectArgsBarrier(),
+ OUT_Accumulation->GetResource()->GetRenderTargetBarrier(),
+ OUT_VelocityBuffer->GetResource()->GetRenderTargetBarrier(),
+ depthStencil->GetResource()->GetDepthWriteBarrier() });
+ cmdList->SetRenderTargets({ OUT_Accumulation.get(), OUT_VelocityBuffer.get() }, depthStencil);
+ cmdList->ClearDepthStencilView(depthStencil);
+ cmdList->ClearRenderTargetView(OUT_Accumulation.get());
+ cmdList->ClearRenderTargetView(OUT_VelocityBuffer.get());
+ cmdList->ExecuteIndirect(_opaqueCS.Get(), _resources->IndirectCommandsCache->GetElementCount(),
+ currentCameraVisBuffers.VisibleOpaqueCommandsCache->GetResource().D3DResource.Get(), 0,
+ currentCameraVisBuffers.OpaqueDrawCounter->GetResource().D3DResource.Get(), 0);
+ cmdList->EndPixEvent();
+ }
+
+ void Resize() override
+ {
+ UINT newWidth = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledWidth : _commonData->WindowWidth;
+ UINT newHeight = GetFlagValue(RENDER_PASS_FLAG_USE_DOWNSCALED_RESOLUTION) ? _commonData->DownscaledHeight : _commonData->WindowHeight;
+ OUT_Accumulation->Resize(newWidth, newHeight);
+ OUT_VelocityBuffer->Resize(newWidth, newHeight);
+ OUT_DepthStencil->Resize(newWidth, newHeight);
+ }
+
+ void ClearDenendencies() override
+ {
+ GDX12RenderPass::ClearDenendencies();
+
+ OUT_Accumulation.reset();
+ OUT_VelocityBuffer.reset();
+ OUT_DepthStencil.reset();
+ _opaqueVS.Reset();
+ _opaquePS.Reset();
+ _opaqueRS.reset();
+ _opaqueCS.Reset();
+ _opaquePSO.Reset();
+ }
+
+private:
+ ComPtr _opaqueVS;
+ ComPtr _opaquePS;
+ std::unique_ptr _opaqueRS;
+ ComPtr _opaqueCS;
+ ComPtr _opaquePSO;
+
+ std::unique_ptr OUT_Accumulation;
+ std::unique_ptr