diff --git a/HPL2/include/graphics/CopyTextureSubpass4.h b/HPL2/include/graphics/CopyTextureSubpass4.h new file mode 100644 index 000000000..1cd5a5a9a --- /dev/null +++ b/HPL2/include/graphics/CopyTextureSubpass4.h @@ -0,0 +1,26 @@ +#pragma once + +#include "graphics/ForgeRenderer.h" +#include "graphics/ForgeHandles.h" + +namespace hpl { + + class CopyTextureSubpass4 { + public: + + static constexpr uint32_t NumberOfDescriptors = 32; + CopyTextureSubpass4(CopyTextureSubpass4&&) = default; + CopyTextureSubpass4(CopyTextureSubpass4&) = delete; + CopyTextureSubpass4(hpl::ForgeRenderer& renderer); + void operator=(CopyTextureSubpass4&) = delete; + CopyTextureSubpass4& operator=(CopyTextureSubpass4&&) = default; + + void Dispatch(ForgeRenderer::Frame& frame, Texture* src, Texture* dest); + private: + SharedRootSignature m_copyRootSignature; + std::array m_copyPerFrameSet; + SharedPipeline m_copyPipline; + SharedShader m_copyShader; + std::array m_index; + }; +} // namespace hpl diff --git a/HPL2/include/graphics/ForgeRenderer.h b/HPL2/include/graphics/ForgeRenderer.h index fee58b804..ac074e757 100644 --- a/HPL2/include/graphics/ForgeRenderer.h +++ b/HPL2/include/graphics/ForgeRenderer.h @@ -11,6 +11,7 @@ #include +#include "Common_3/Utilities/RingBuffer.h" #include "graphics/ForgeHandles.h" #include "windowing/NativeWindow.h" #include "engine/QueuedEventLoopHandler.h" @@ -54,13 +55,12 @@ namespace hpl { CopyPipelineCount = 2 }; + static constexpr uint32_t MaxCopyFrames = 32; static constexpr uint32_t SwapChainLength = 2; // double buffered static constexpr uint32_t ResourcePoolSize = 4; // double buffered void InitializeRenderer(window::NativeWindowWrapper* window); - void InitializeResource(); - //RendererApi GetApi(); struct SamplerPoolKey { union { @@ -104,9 +104,13 @@ namespace hpl { * tracks the resources used by a single command buffer */ struct Frame { + public: uint32_t m_currentFrame = 0; uint32_t m_frameIndex = 0; - uint32_t m_swapChainIndex = 0; + GpuCmdRingElement m_cmdRingElement; + bool m_isFinished = true; + //FrameState m_state = FrameState::Unitialize; + ForgeRenderer* m_renderer = nullptr; SwapChain* m_swapChain = nullptr; Cmd* m_cmd = nullptr; @@ -115,26 +119,37 @@ namespace hpl { Semaphore* m_renderCompleteSemaphore = nullptr; CommandResourcePool* m_resourcePool = nullptr; RenderTarget* m_finalRenderTarget = nullptr; - std::vector* m_waitSemaphores; - }; - const inline Frame GetFrame() { - Frame frame; - frame.m_currentFrame = FrameCount(); - frame.m_frameIndex = CurrentFrameIndex(); - frame.m_swapChainIndex = SwapChainIndex(); - frame.m_renderer = this; - frame.m_swapChain = m_swapChain.m_handle; - - frame.m_cmd = m_cmds[CurrentFrameIndex()]; - frame.m_cmdPool = m_cmdPools[CurrentFrameIndex()]; - frame.m_renderCompleteFence = m_renderCompleteFences[CurrentFrameIndex()]; - frame.m_renderCompleteSemaphore = m_renderCompleteSemaphores[CurrentFrameIndex()]; - frame.m_resourcePool = &m_resourcePool[CurrentFrameIndex()]; - frame.m_finalRenderTarget = m_finalRenderTarget[CurrentFrameIndex()].m_handle; - frame.m_waitSemaphores = &m_waitSemaphores[CurrentFrameIndex()]; - return frame; + template + inline void pushResource(const T& ele) { + m_resourcePool->Push(ele); + } + inline uint32_t index() { + return m_frameIndex; + } + + inline Cmd*& cmd() { + return m_cmdRingElement.pCmds[0]; + } + + inline RenderTarget* finalTarget() { + return m_finalRenderTarget; + } + + // inline RenderTarget* swapChainTarget() { + // return m_swapChainTarget; + // } + + inline GpuCmdRingElement& RingElement() { + return m_cmdRingElement; + } + + friend class ForgeRenderer; + }; + + inline Frame& GetFrame() { + return m_frame; } // void BeginFrame() {} @@ -147,10 +162,6 @@ namespace hpl { } RootSignature* PipelineSignature() { return m_pipelineSignature; } - size_t SwapChainIndex() { return m_swapChainIndex; } - size_t CurrentFrameIndex() { return m_currentFrameCount % SwapChainLength; } - size_t FrameCount() { return m_currentFrameCount; } - inline SwapChain* GetSwapChain() { return m_swapChain.m_handle; } inline Queue* GetGraphicsQueue() { return m_graphicsQueue; } void cmdCopyTexture(Cmd* cmd, Texture* srcTexture, RenderTarget* dstTexture); @@ -160,20 +171,15 @@ namespace hpl { private: std::array m_samplerPool; std::array m_resourcePool; - std::array m_renderCompleteFences; - std::array m_renderCompleteSemaphores; std::array m_cmdPools; std::array m_cmds; std::array m_finalRenderTarget; - std::array, SwapChainLength> m_waitSemaphores; - - - float m_gamma = 1.0f; - window::WindowEvent::QueuedEventHandler m_windowEventHandler; window::NativeWindowWrapper* m_window = nullptr; + GpuCmdRing m_graphicsCmdRing; + Renderer* m_renderer = nullptr; RootSignature* m_pipelineSignature = nullptr; SharedSwapChain m_swapChain; @@ -192,11 +198,14 @@ namespace hpl { SharedSampler m_pointSampler ; RootSignature* m_copyPostProcessingRootSignature = nullptr; - DescriptorSet* m_copyPostProcessingDescriptorSet = nullptr; + std::array m_copyPostProcessingDescriptorSet ; uint32_t m_copyRegionDescriptorIndex = 0; + float m_gamma = 1.0f; + uint32_t m_swapChainCount; + + + Frame m_frame; - uint32_t m_currentFrameCount = 0; - uint32_t m_swapChainIndex = 0; }; } // namespace hpl diff --git a/HPL2/include/graphics/Renderer.h b/HPL2/include/graphics/Renderer.h index bf374c9a8..f1765c9cd 100644 --- a/HPL2/include/graphics/Renderer.h +++ b/HPL2/include/graphics/Renderer.h @@ -29,6 +29,7 @@ #include "math/MathTypes.h" #include "scene/SceneTypes.h" +#include "graphics/ScopedBarrier.h" #include "graphics/RenderFunctions.h" #include "scene/Viewport.h" #include @@ -149,13 +150,13 @@ namespace hpl { // ensure the contents is copied to the RenderViewport virtual void Draw( Cmd* cmd, - const ForgeRenderer::Frame& context, + ForgeRenderer::Frame& context, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) = 0; + cRenderSettings* apSettings + ) = 0; void Update(float afTimeStep); diff --git a/HPL2/include/graphics/RendererDeferred.h b/HPL2/include/graphics/RendererDeferred.h index 918eaa0db..e8bdceaa1 100644 --- a/HPL2/include/graphics/RendererDeferred.h +++ b/HPL2/include/graphics/RendererDeferred.h @@ -21,6 +21,7 @@ #include "engine/RTTI.h" #include "graphics/SceneResource.h" +#include "graphics/ScopedBarrier.h" #include "scene/Viewport.h" #include "scene/World.h" #include "windowing/NativeWindow.h" @@ -356,13 +357,12 @@ namespace hpl { virtual void Draw( Cmd* cmd, - const ForgeRenderer::Frame& frame, + ForgeRenderer::Frame& frame, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) override; + cRenderSettings* apSettings) override; private: iVertexBuffer* GetLightShape(iLight* apLight, eDeferredShapeQuality aQuality) const; diff --git a/HPL2/include/graphics/RendererDeferred2.h b/HPL2/include/graphics/RendererDeferred2.h index 166ac2b7d..0eb6467c7 100644 --- a/HPL2/include/graphics/RendererDeferred2.h +++ b/HPL2/include/graphics/RendererDeferred2.h @@ -21,9 +21,11 @@ #include "engine/RTTI.h" #include "graphics/CommandBufferPool.h" +#include "graphics/CopyTextureSubpass4.h" #include "graphics/GraphicsTypes.h" #include "graphics/ImageBindlessPool.h" #include "graphics/SceneResource.h" +#include "graphics/ScopedBarrier.h" #include "graphics/ShadowCache.h" #include "graphics/BindlessDescriptorPool.h" #include "scene/Viewport.h" @@ -120,13 +122,14 @@ namespace hpl { ViewportData() = default; ViewportData(const ViewportData&) = delete; ViewportData(ViewportData&& buffer)= default; - ViewportData& operator=(const ViewportData&) = delete; ViewportData& operator=(ViewportData&& buffer) = default; + ViewportData& operator=(const ViewportData&) = delete; uint2 m_size = uint2(0, 0); std::array m_outputBuffer; std::array m_depthBuffer; std::array m_albedoBuffer; // this is used for the adding decals to albedo + std::array m_refractionImage; std::array m_testBuffer; //encodes the parallax std::array m_visiblityBuffer; @@ -148,13 +151,12 @@ namespace hpl { virtual SharedRenderTarget GetOutputImage(uint32_t frameIndex, cViewport& viewport) override; virtual void Draw( Cmd* cmd, - const ForgeRenderer::Frame& frame, + ForgeRenderer::Frame& frame, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) override; + cRenderSettings* apSettings) override; private: void setIndirectDrawArg(const ForgeRenderer::Frame& frame, uint32_t drawArgIndex, uint32_t slot, DrawPacket& packet); @@ -312,6 +314,8 @@ namespace hpl { BlendPipelines m_translucencyIlluminationPipline; BlendPipelines m_translucencyIlluminationPiplineNoDepth; + CopyTextureSubpass4 m_copySubpass; + bool m_supportIndirectRootConstant = false; }; }; // namespace hpl diff --git a/HPL2/include/graphics/RendererWireFrame.h b/HPL2/include/graphics/RendererWireFrame.h index 5b76c0266..b75d1300c 100644 --- a/HPL2/include/graphics/RendererWireFrame.h +++ b/HPL2/include/graphics/RendererWireFrame.h @@ -86,13 +86,12 @@ namespace hpl { virtual void Draw( Cmd* cmd, - const ForgeRenderer::Frame& context, + ForgeRenderer::Frame& context, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) override; + cRenderSettings* apSettings) override; std::array m_frameBufferUniform; uint32_t m_perFrameIndex = 0; diff --git a/HPL2/include/graphics/ScopedBarrier.h b/HPL2/include/graphics/ScopedBarrier.h new file mode 100644 index 000000000..11a060740 --- /dev/null +++ b/HPL2/include/graphics/ScopedBarrier.h @@ -0,0 +1,61 @@ +#pragma once + +#include "Common_3/Graphics/Interfaces/IGraphics.h" +#include + +namespace hpl { + class RenderTargetScopedBarrier; + struct RenderTargetTransition { + RenderTargetScopedBarrier* m_resource; + ResourceState m_newState; + }; + + namespace ScopedBarrier { + void End( + Cmd* cmd, + std::span + ); + + void Transition( + Cmd* cmd, + std::span + ); + }; + + class RenderTargetScopedBarrier { + public: + RenderTargetScopedBarrier(); + RenderTargetScopedBarrier(RenderTarget* target, ResourceState start, ResourceState end); + RenderTargetScopedBarrier(RenderTargetScopedBarrier&) = delete; + RenderTargetScopedBarrier(RenderTargetScopedBarrier&&); + + void Set(RenderTarget* target, ResourceState start, ResourceState end); + void operator=(RenderTargetBarrier&) = delete; + void operator=(RenderTargetScopedBarrier&&); + + ~RenderTargetScopedBarrier() { + // scope hasn't been closed + ASSERT(m_target == nullptr); + } + + inline bool IsValid() { + return m_target != nullptr; + } + + inline RenderTarget* Target() { + return m_target; + } + + private: + ResourceState m_startState; + ResourceState m_currentState; + ResourceState m_endState; + RenderTarget* m_target = nullptr; + + friend void ScopedBarrier::End(Cmd*, std::span); + friend void ScopedBarrier::Transition(Cmd*, std::span); + + }; + + +} diff --git a/HPL2/include/scene/Scene.h b/HPL2/include/scene/Scene.h index 145e1f270..bc3304ff5 100644 --- a/HPL2/include/scene/Scene.h +++ b/HPL2/include/scene/Scene.h @@ -66,7 +66,7 @@ namespace hpl { * Called by cEngine */ void Render(float afFrameTime, tFlag alFlags) {} //TODO MP: this needs to be replaced - void Render(const ForgeRenderer::Frame&, float afFrameTime, tFlag alFlags); + void Render(ForgeRenderer::Frame&, float afFrameTime, tFlag alFlags); void Update(float timeStep); diff --git a/HPL2/resource/parallax_bindless.h.fsl b/HPL2/resource/parallax_bindless.h.fsl index 181d309b0..5c68f04c9 100644 --- a/HPL2/resource/parallax_bindless.h.fsl +++ b/HPL2/resource/parallax_bindless.h.fsl @@ -4,16 +4,10 @@ #ifndef _PARALLAX_BINDLESS_H #define _PARALLAX_BINDLESS_H -float GetNormalizedDepth(SamplerState sh, uint heightIdx, float startDepth, float stopDepth, float inverseDepthRange, float2 uv, bool isHeightMapSingleChannel) { - float currentSample = 0.0; - float4 value; - if(SampleSceneTextureFloat4(heightIdx, sh, uv, value)) { - if(isHeightMapSingleChannel) { - currentSample = value.r; - } else { - currentSample = value.a; - } - } +INLINE float GetNormalizedDepth(float currentSample, float startDepth, float stopDepth, float inverseDepthRange) { + //float currentSample = 0.0; + // BeginNonUniformResourceIndex(heightIdx); + // EndNonUniformResourceIndex(); float normalizedDepth = 0.0; if(stopDepth - startDepth > 0.0001) @@ -33,8 +27,7 @@ float2 ParallaxAdvance( float3 normal, float3 tangent, float3 bitangent, - uint heightIdx, - SamplerState sh, + uint heightTextureIndex, bool isHeightMapSingleChannel) { float3 dirToCameraTS = normalize(WorldSpaceToTangent(dir, normal, tangent, bitangent)); @@ -54,16 +47,12 @@ float2 ParallaxAdvance( // It is adjusted according to the depthOffset, raising or lowering the whole surface by depthOffset units. float3 parallaxOffset = -dirToCameraTS.xyz * dirToCameraZInverse * depthOffset; - float currentSample; - float4 value; - if(SampleSceneTextureFloat4(heightIdx, sh, uv.xy + parallaxOffset.xy, value)) { - if(isHeightMapSingleChannel) { - currentSample = value.r; - } else { - currentSample = value.a; - } - } - float prevSample; + float currentSample = 0.0; + uint index2 = heightTextureIndex; + BeginNonUniformResourceIndex(index2); + currentSample = isHeightMapSingleChannel ? SampleTex2D(Get(sceneTextures)[index2], Get(sceneSampler), uv.xy + parallaxOffset.xy).r : SampleTex2D(Get(sceneTextures)[index2], Get(sceneSampler), uv.xy + parallaxOffset.xy).a; + EndNonUniformResourceIndex(); + float prevSample = 0.0; // Do a basic search for the intersect step while(currentSample > currentStep) { @@ -71,7 +60,12 @@ float2 ParallaxAdvance( parallaxOffset += delta; prevSample = currentSample; - currentSample = GetNormalizedDepth(sh, heightIdx, depthSearchStart, depthSearchEnd, inverseDepthFactor, uv.xy + parallaxOffset.xy, isHeightMapSingleChannel); + float newSample; + uint index = heightTextureIndex; + BeginNonUniformResourceIndex(index); + newSample = isHeightMapSingleChannel ? SampleTex2D(Get(sceneTextures)[index], Get(sceneSampler), uv.xy + parallaxOffset.xy).r : SampleTex2D(Get(sceneTextures)[index], Get(sceneSampler), uv.xy + parallaxOffset.xy).a; + EndNonUniformResourceIndex(); + currentSample = GetNormalizedDepth(newSample, depthSearchStart, depthSearchEnd, inverseDepthFactor); } if(currentStep > 0.0) @@ -95,7 +89,12 @@ float2 ParallaxAdvance( parallaxOffset += adjustedDelta; prevSample = currentSample; - currentSample = GetNormalizedDepth(sh, heightIdx, depthSearchStart, depthSearchEnd, inverseDepthFactor, uv.xy + parallaxOffset.xy, isHeightMapSingleChannel); + float newSample; + uint index = heightTextureIndex; + BeginNonUniformResourceIndex(index); + newSample = isHeightMapSingleChannel ? SampleTex2D(Get(sceneTextures)[index], Get(sceneSampler), uv.xy + parallaxOffset.xy).r : SampleTex2D(Get(sceneTextures)[index], Get(sceneSampler), uv.xy + parallaxOffset.xy).a; + EndNonUniformResourceIndex(); + currentSample = GetNormalizedDepth(newSample, depthSearchStart, depthSearchEnd, inverseDepthFactor); } } if(parallaxOffset.z > 0.0) diff --git a/HPL2/resource/scene_defs.h.fsl b/HPL2/resource/scene_defs.h.fsl index 2187f508e..7d749f962 100644 --- a/HPL2/resource/scene_defs.h.fsl +++ b/HPL2/resource/scene_defs.h.fsl @@ -1,6 +1,8 @@ #ifndef _SCENE_RESOURCE_DEFS_H_ #define _SCENE_RESOURCE_DEFS_H_ +#define VK_EXT_DESCRIPTOR_INDEXING_ENABLED 1 + #define PARALLAX_MULTIPLIER 0.7 #define POINT_LIGHT_MAX_COUNT (256) diff --git a/HPL2/resource/scene_resource.h.fsl b/HPL2/resource/scene_resource.h.fsl index 83df271d8..b00ba368b 100644 --- a/HPL2/resource/scene_resource.h.fsl +++ b/HPL2/resource/scene_resource.h.fsl @@ -4,7 +4,7 @@ #define _SCENE_RESOURCE_H #if defined(DIRECT3D12) - PUSH_CONSTANT(indirectRootConstant, b1) + PUSH_CONSTANT(indirectRootConstant, b0) { DATA(uint, indirectDrawId, None); }; @@ -12,44 +12,44 @@ #define INDIRECT_ROOT_CONSTANT 1 #endif -CBUFFER(sceneInfo, UPDATE_FREQ_PER_FRAME, b2, binding = 0) { +RES(SamplerState, nearEdgeClampSampler, UPDATE_FREQ_NONE, s0, binding = 0); +RES(SamplerState, nearPointWrapSampler, UPDATE_FREQ_NONE, s1, binding = 1); +RES(SamplerState, linearBorderSampler, UPDATE_FREQ_NONE, s2, binding = 2); +RES(SamplerState, sceneSampler, UPDATE_FREQ_NONE, s3, binding = 3); + +CBUFFER(sceneInfo, UPDATE_FREQ_PER_FRAME, b1, binding = 4) { DATA(WorldInfo, worldInfo, None); DATA(ViewportInfo, viewports[64], None); }; -RES(Buffer(UniformObject), sceneObjects, UPDATE_FREQ_PER_FRAME, t0, binding = 1); -RES(Buffer(Light), lights, UPDATE_FREQ_PER_FRAME, t1, binding = 2); -RES(Buffer(Particle), particles, UPDATE_FREQ_PER_FRAME, t2, binding = 3); -RES(Buffer(Decal), decals, UPDATE_FREQ_PER_FRAME, t3, binding = 4); +RES(Buffer(UniformObject), sceneObjects, UPDATE_FREQ_PER_FRAME, t0, binding = 5); +RES(Buffer(Light), lights, UPDATE_FREQ_PER_FRAME, t1, binding = 6); +RES(Buffer(Particle), particles, UPDATE_FREQ_PER_FRAME, t2, binding = 7); +RES(Buffer(Decal), decals, UPDATE_FREQ_PER_FRAME, t3, binding = 8); // opaque geometry set -RES(ByteBuffer, vtxOpaqueIndex, UPDATE_FREQ_NONE, t4, binding = 5); -RES(ByteBuffer, vtxOpaquePosition, UPDATE_FREQ_NONE, t5, binding = 6); -RES(ByteBuffer, vtxOpaqueTangnet, UPDATE_FREQ_NONE, t6, binding = 7); -RES(ByteBuffer, vtxOpaqueNormal, UPDATE_FREQ_NONE, t7, binding = 8); -RES(ByteBuffer, vtxOpaqueUv, UPDATE_FREQ_NONE, t8, binding = 9); -RES(ByteBuffer, vtxOpaqueColor, UPDATE_FREQ_NONE, t9, binding = 10); - -RES(Buffer(DiffuseMaterial), sceneDiffuseMat, UPDATE_FREQ_NONE, t10, binding = 11); -RES(Buffer(TranslucentMaterial), sceneTranslucentMat, UPDATE_FREQ_NONE, t10, binding = 12); -RES(Buffer(WaterMaterial), sceneWaterMat, UPDATE_FREQ_NONE, t10, binding = 13); +RES(ByteBuffer, vtxOpaqueIndex, UPDATE_FREQ_NONE, t4, binding = 9); +RES(ByteBuffer, vtxOpaquePosition, UPDATE_FREQ_NONE, t5, binding = 10); +RES(ByteBuffer, vtxOpaqueTangnet, UPDATE_FREQ_NONE, t6, binding = 11); +RES(ByteBuffer, vtxOpaqueNormal, UPDATE_FREQ_NONE, t7, binding = 12); +RES(ByteBuffer, vtxOpaqueUv, UPDATE_FREQ_NONE, t8, binding = 13); +RES(ByteBuffer, vtxOpaqueColor, UPDATE_FREQ_NONE, t9, binding = 14); -RES(SamplerState, nearEdgeClampSampler, UPDATE_FREQ_NONE, s0, binding = 14); -RES(SamplerState, nearPointWrapSampler, UPDATE_FREQ_NONE, s1, binding = 15); -RES(SamplerState, linearBorderSampler, UPDATE_FREQ_NONE, s1, binding = 16); +RES(Buffer(DiffuseMaterial), sceneDiffuseMat, UPDATE_FREQ_NONE, t10, binding = 15); +RES(Buffer(TranslucentMaterial), sceneTranslucentMat, UPDATE_FREQ_NONE, t11, binding = 16); +RES(Buffer(WaterMaterial), sceneWaterMat, UPDATE_FREQ_NONE, t12, binding = 17); -RES(Tex2D(float4), visibilityTexture, UPDATE_FREQ_PER_FRAME, t11, binding = 17); -RES(Tex2D(float4), albedoTexture, UPDATE_FREQ_PER_FRAME, t12, binding = 18); -RES(Tex2D(float4), refractionTexture, UPDATE_FREQ_PER_FRAME, t12, binding = 19); +RES(Tex2D(float4), visibilityTexture, UPDATE_FREQ_PER_FRAME, t13, binding = 18); +RES(Tex2D(float4), albedoTexture, UPDATE_FREQ_PER_FRAME, t14, binding = 19); +RES(Tex2D(float4), refractionTexture, UPDATE_FREQ_PER_FRAME, t15, binding = 20); -RES(Tex2D(float4), dissolveTexture, UPDATE_FREQ_NONE, t14, binding = 20); +RES(Tex2D(float4), dissolveTexture, UPDATE_FREQ_NONE, t16, binding = 21); -RES(ByteBuffer, lightClustersCount, UPDATE_FREQ_PER_FRAME, t15, binding = 21); -RES(ByteBuffer, lightClusters, UPDATE_FREQ_PER_FRAME, t16, binding = 22); +RES(ByteBuffer, lightClustersCount, UPDATE_FREQ_PER_FRAME, t17, binding = 22); +RES(ByteBuffer, lightClusters, UPDATE_FREQ_PER_FRAME, t18, binding = 23); -RES(SamplerState, sceneSampler, UPDATE_FREQ_NONE, s2, binding = 23); -RES(Tex2D(float4), sceneTextures[SCENE_MAX_TEXTURE_COUNT], UPDATE_FREQ_PER_FRAME, t17, binding = 24); -RES(TexCube(float4), sceneCubeTextures[SCENE_MAX_TEXTURE_CUBE_COUNT], UPDATE_FREQ_PER_FRAME, t18, binding = 25 + SCENE_MAX_TEXTURE_CUBE_COUNT); +RES(Tex2D(float4), sceneTextures[SCENE_MAX_TEXTURE_COUNT], UPDATE_FREQ_PER_FRAME, t19, binding = 24); +RES(TexCube(float4), sceneCubeTextures[SCENE_MAX_TEXTURE_CUBE_COUNT], UPDATE_FREQ_PER_FRAME, t10020, binding = 25); #define SCENE_OBJECT_ID_BIT 19 // 13 bits for ObjectID #define SCENE_PRIM_ID_BIT 0 // 19 bits for PrimitiveID @@ -67,7 +67,7 @@ RES(TexCube(float4), sceneCubeTextures[SCENE_MAX_TEXTURE_CUBE_COUNT], UPDATE_FR bool SampleSceneTextureProjFloat4(uint textureIdx, SamplerState sh, float4 projectUV, inout float4 value) { if(textureIdx < SCENE_MAX_TEXTURE_COUNT) { - BeginNonUniformResourceIndex(textureIdx, SCENE_MAX_TEXTURE_COUNT); + BeginNonUniformResourceIndex(textureIdx); value = SampleTex2DProj(Get(sceneTextures)[textureIdx], sh, projectUV); EndNonUniformResourceIndex(); return true; @@ -75,9 +75,9 @@ bool SampleSceneTextureProjFloat4(uint textureIdx, SamplerState sh, float4 proje return false; } -bool SampleSceneCubeTextureFloat4(uint textureIdx, SamplerState sh, float3 uv, inout float4 value) { +INLINE bool SampleSceneCubeTextureFloat4(uint textureIdx, SamplerState sh, float3 uv, inout float4 value) { if(textureIdx < SCENE_MAX_TEXTURE_CUBE_COUNT) { - BeginNonUniformResourceIndex(textureIdx, SCENE_MAX_TEXTURE_CUBE_COUNT); + BeginNonUniformResourceIndex(textureIdx); value = SampleTexCube(Get(sceneCubeTextures)[textureIdx], sh, uv); EndNonUniformResourceIndex(); return true; @@ -85,18 +85,18 @@ bool SampleSceneCubeTextureFloat4(uint textureIdx, SamplerState sh, float3 uv, i return false; } -bool SampleSceneTextureFloat4(uint textureIdx,SamplerState sh, float2 uv, inout float4 value) { +INLINE bool SampleSceneTextureFloat4(uint textureIdx,SamplerState sh, float2 uv, inout float4 value) { if(textureIdx < SCENE_MAX_TEXTURE_COUNT) { - BeginNonUniformResourceIndex(textureIdx, SCENE_MAX_TEXTURE_COUNT); + BeginNonUniformResourceIndex(textureIdx); value = SampleTex2D(Get(sceneTextures)[textureIdx], sh, uv); EndNonUniformResourceIndex(); return true; } return false; } -bool SampleSceneTextureGradFloat4(uint textureIdx, SamplerState sh, float2 uv, float2 texCoordDX, float2 texCoordDY, inout float4 value) { +INLINE bool SampleSceneTextureGradFloat4(uint textureIdx, SamplerState sh, float2 uv, float2 texCoordDX, float2 texCoordDY, inout float4 value) { if(textureIdx < SCENE_MAX_TEXTURE_COUNT) { - BeginNonUniformResourceIndex(textureIdx, SCENE_MAX_TEXTURE_COUNT); + BeginNonUniformResourceIndex(textureIdx); value = SampleGradTex2D(Get(sceneTextures)[textureIdx], sh, uv, texCoordDX, texCoordDY); EndNonUniformResourceIndex(); return true; diff --git a/HPL2/resource/translucency_shade.frag.fsl b/HPL2/resource/translucency_shade.frag.fsl index d464e3613..949d93fad 100644 --- a/HPL2/resource/translucency_shade.frag.fsl +++ b/HPL2/resource/translucency_shade.frag.fsl @@ -124,7 +124,7 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) float fFresnel = Fresnel(afEDotN, material.frenselBias, material.frenselPos); //Alpha for environment map - float4 specular = float4(0); + float4 specular; if(SampleSceneTextureFloat4(material.cubeMapAlphaTextureIndex, Get(sceneSampler), In.uv.xy, specular)) { reflectionColor *= specular.w; } diff --git a/HPL2/resource/visibilityBuffer_alpha_pass.frag.fsl b/HPL2/resource/visibilityBuffer_alpha_pass.frag.fsl index 77c1b5a3d..1dcb86a98 100644 --- a/HPL2/resource/visibilityBuffer_alpha_pass.frag.fsl +++ b/HPL2/resource/visibilityBuffer_alpha_pass.frag.fsl @@ -15,15 +15,10 @@ STRUCT(PsIn) DATA(float3, bitangent, BITANGENT); }; -STRUCT(PsOut) -{ - DATA(float4, visibility, SV_Target0); -}; -PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) +float4 PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) { INIT_MAIN; - PsOut Out; #if !defined(INDIRECT_ROOT_CONSTANT) UniformObject obj = Get(sceneObjects)[In.drawID]; @@ -47,7 +42,6 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) In.tangent, In.bitangent, material.heightTextureIndex, - Get(sceneSampler), (material.config & MATERIAL_IS_HEIGHT_SINGLE_CHANNEL) > 0); } @@ -69,7 +63,7 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) if(SampleSceneTextureFloat4(material.dissolveAlphaTextureIndex, Get(sceneSampler), texCoord, alphaValue)) { //Get in 0.75 - 1 range fDissolve = fDissolve * 0.25 + 0.75; - float fDissolveAlpha = alphaValue.r; + float fDissolveAlpha = ((material.config & MATERIAL_IS_ALPHA_SINGLE_CHANNEL) > 0) ? alphaValue.r : alphaValue.a; fDissolve -= (0.25 - fDissolveAlpha * 0.25); } else { //Get in 0.5 - 1 range. @@ -83,11 +77,10 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) } #if !defined(INDIRECT_ROOT_CONSTANT) - Out.visibility = unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(In.drawID, primitiveID)); + RETURN(unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(In.drawID, primitiveID))); #else - Out.visibility = unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(Get(indirectDrawId), primitiveID)); + RETURN(unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(Get(indirectDrawId), primitiveID))); #endif - RETURN(Out); } diff --git a/HPL2/resource/visibilityBuffer_pass.frag.fsl b/HPL2/resource/visibilityBuffer_pass.frag.fsl index 1ef5f3527..46c64eda3 100644 --- a/HPL2/resource/visibilityBuffer_pass.frag.fsl +++ b/HPL2/resource/visibilityBuffer_pass.frag.fsl @@ -12,12 +12,10 @@ STRUCT(PsIn) float4 PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) { INIT_MAIN; - float4 result; #if !defined(INDIRECT_ROOT_CONSTANT) - result = unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(In.drawID, primitiveID)); - #else - result = unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(Get(indirectDrawId), primitiveID)); - #endif - RETURN(result); + RETURN(unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(In.drawID, primitiveID))); + #else + RETURN(unpackUnorm4x8(SCENE_VIZ_ALPHA_ID(Get(indirectDrawId), primitiveID))); + #endif } diff --git a/HPL2/resource/visibility_emit_shade_pass.frag.fsl b/HPL2/resource/visibility_emit_shade_pass.frag.fsl index f896884f8..9619cdfaa 100644 --- a/HPL2/resource/visibility_emit_shade_pass.frag.fsl +++ b/HPL2/resource/visibility_emit_shade_pass.frag.fsl @@ -11,12 +11,8 @@ STRUCT(PsIn) DATA(float2, screenPos, TEXCOORD0); }; -STRUCT(PsOut) -{ - DATA(float4, albedoColor , SV_Target0); -}; -PsOut PS_MAIN(PsIn In) +float4 PS_MAIN(PsIn In) { INIT_MAIN; @@ -101,7 +97,6 @@ PsOut PS_MAIN(PsIn In) DiffuseMaterial material = Get(sceneDiffuseMat)[materialIndex]; float2 texCoord = results.interp; - PsOut Out; if(isTextureIndexValid(material.heightTextureIndex)) { texCoord += ParallaxAdvance( results.interp, @@ -113,14 +108,19 @@ PsOut PS_MAIN(PsIn In) worldTangent, worldBitangent, material.heightTextureIndex, - Get(sceneSampler), (material.config & MATERIAL_IS_HEIGHT_SINGLE_CHANNEL) > 0); } float4 diffuseColor = float4(0,0,0,0); float3 shadedColor = f3(0.0f); - SampleSceneTextureGradFloat4(material.diffuseTextureIndex, Get(sceneSampler), texCoord, texCoordDX, texCoordDY, diffuseColor); - Out.albedoColor = diffuseColor; - RETURN(Out); + + if(isTextureIndexValid(material.diffuseTextureIndex)) { + const uint diffuseTextureIdx = material.diffuseTextureIndex; + BeginNonUniformResourceIndex(diffuseTextureIdx); + diffuseColor = SampleGradTex2D(Get(sceneTextures)[diffuseTextureIdx], Get(sceneSampler), texCoord, texCoordDX, texCoordDY); + EndNonUniformResourceIndex(); + } + + RETURN(diffuseColor); } diff --git a/HPL2/resource/visibility_shade_pass.frag.fsl b/HPL2/resource/visibility_shade_pass.frag.fsl index 23c786210..5efb7cb87 100644 --- a/HPL2/resource/visibility_shade_pass.frag.fsl +++ b/HPL2/resource/visibility_shade_pass.frag.fsl @@ -11,16 +11,10 @@ STRUCT(PsIn) DATA(float2, screenPos, TEXCOORD0); }; -STRUCT(PsOut) -{ - DATA(float4, outColor , SV_Target0); - DATA(float4, test, SV_Target1); -}; -PsOut PS_MAIN(PsIn In) +float4 PS_MAIN(PsIn In) { INIT_MAIN; - PsOut Out; const float4 visRaw = LoadTex2D(Get(visibilityTexture), Get(nearEdgeClampSampler), uint2(In.position.xy), 0); const uint objectId_triId = packUnorm4x8(visRaw); @@ -103,6 +97,7 @@ PsOut PS_MAIN(PsIn In) float2 texCoord = results.interp; float4 diffuseColor = LoadTex2D(Get(albedoTexture), Get(nearEdgeClampSampler), uint2(In.position.xy), 0); + if(isTextureIndexValid(material.heightTextureIndex)) { texCoord += ParallaxAdvance( results.interp, @@ -114,11 +109,10 @@ PsOut PS_MAIN(PsIn In) worldTangent, worldBitangent, material.heightTextureIndex, - Get(sceneSampler), (material.config & MATERIAL_IS_HEIGHT_SINGLE_CHANNEL) > 0); } float4 normalSample = float4(0,0,0,0); - float3 shadedColor = float3(0.0f); + float3 shadedColor = float3(0.0,0.0,0.0); if (SampleSceneTextureGradFloat4(material.normalTextureIndex, Get(sceneSampler), texCoord, texCoordDX, texCoordDY, normalSample)) { normalSample -= 0.5; @@ -182,11 +176,9 @@ PsOut PS_MAIN(PsIn In) } } - Out.outColor = float4(shadedColor, 0.0f); //Out.outColor = float4(diffuseColor.rgb, 0.0f); - Out.test = float4(clusterCoords.x,clusterCoords.y,slice, lightClusterCount); - RETURN(Out); - + //Out.test = float4(clusterCoords.x,clusterCoords.y,slice, lightClusterCount); + RETURN(float4(shadedColor, 0.0)); } diff --git a/HPL2/sources/graphics/CopyTextureSubpass4.cpp b/HPL2/sources/graphics/CopyTextureSubpass4.cpp new file mode 100644 index 000000000..a5b43d2d1 --- /dev/null +++ b/HPL2/sources/graphics/CopyTextureSubpass4.cpp @@ -0,0 +1,60 @@ +#include "graphics/CopyTextureSubpass4.h" + +namespace hpl { + + CopyTextureSubpass4::CopyTextureSubpass4(hpl::ForgeRenderer& renderer) { + + m_copyShader.Load(renderer.Rend(), [&](Shader** shader) { + ShaderLoadDesc loadDesc = {}; + loadDesc.mStages[0].pFileName = "copy_channel_4.comp"; + addShader(renderer.Rend(), &loadDesc, shader); + return true; + }); + m_copyRootSignature.Load(renderer.Rend(), [&](RootSignature** signature) { + RootSignatureDesc refractionCopyRootDesc = {}; + refractionCopyRootDesc.mShaderCount = 1; + refractionCopyRootDesc.ppShaders = &m_copyShader.m_handle; + addRootSignature(renderer.Rend(), &refractionCopyRootDesc, signature); + return true; + }); + m_copyPipline.Load(renderer.Rend(), [&](Pipeline** pipeline) { + PipelineDesc desc = {}; + desc.mType = PIPELINE_TYPE_COMPUTE; + ComputePipelineDesc& pipelineSettings = desc.mComputeDesc; + pipelineSettings.pShaderProgram = m_copyShader.m_handle; + pipelineSettings.pRootSignature = m_copyRootSignature.m_handle; + addPipeline(renderer.Rend(), &desc, pipeline); + return true; + }); + DescriptorSetDesc setDesc = { m_copyRootSignature.m_handle, + DESCRIPTOR_UPDATE_FREQ_PER_FRAME, + CopyTextureSubpass4::NumberOfDescriptors }; + for (auto& frameset : m_copyPerFrameSet) { + frameset.Load(renderer.Rend(), [&](DescriptorSet** descriptor) { + addDescriptorSet(renderer.Rend(), &setDesc, descriptor); + return true; + }); + } + for(auto& idx: m_index) { + idx = 0; + } + } + + void CopyTextureSubpass4::Dispatch(ForgeRenderer::Frame& frame, Texture* src, Texture* dest) { + std::array params = { + DescriptorData {.pName = "sourceInput", .ppTextures = &src}, + DescriptorData {.pName = "destOutput", .ppTextures = &dest} + }; + m_index[frame.index()] = (m_index[frame.index()] + 1) % NumberOfDescriptors; + updateDescriptorSet( + frame.m_renderer->Rend(), m_index[frame.index()], m_copyPerFrameSet[frame.m_frameIndex].m_handle, params.size(), params.data()); + cmdBindPipeline( + frame.m_cmd, m_copyPipline.m_handle); + cmdBindDescriptorSet(frame.m_cmd, m_index[frame.index()], m_copyPerFrameSet[frame.m_frameIndex].m_handle); + cmdDispatch( + frame.m_cmd, + static_cast(static_cast(dest->mWidth) / 16.0f) + 1, + static_cast(static_cast(dest->mHeight) / 16.0f) + 1, + 1); + } +} diff --git a/HPL2/sources/graphics/ForgeRenderer.cpp b/HPL2/sources/graphics/ForgeRenderer.cpp index 0bbb61913..ed8c6d6af 100644 --- a/HPL2/sources/graphics/ForgeRenderer.cpp +++ b/HPL2/sources/graphics/ForgeRenderer.cpp @@ -6,6 +6,7 @@ #include "windowing/NativeWindow.h" #include "Common_3/Graphics/Interfaces/IGraphics.h" +#include "Common_3/Utilities/RingBuffer.h" #ifdef HPL2_RENDERDOC_ENABLED #ifdef WIN32 @@ -16,104 +17,109 @@ #endif namespace hpl { - void ForgeRenderer::IncrementFrame() { + if (!m_frame.m_isFinished) { + return; + } + m_frame.m_isFinished = false; + // Stall if CPU is running "Swap Chain Buffer Count" frames ahead of GPU // m_resourcePoolIndex = (m_resourcePoolIndex + 1) % ResourcePoolSize; - m_currentFrameCount++; - auto frame = GetFrame(); + //m_currentFrameCount++; + m_frame.m_cmdRingElement = getNextGpuCmdRingElement(&m_graphicsCmdRing, true, 1); + m_frame.m_currentFrame++; + m_frame.m_frameIndex = (m_frame.m_frameIndex + 1) % ForgeRenderer::SwapChainLength; + //m_frame.m_swapChainTarget = m_swapChain.m_handle->ppRenderTargets[m_frame.m_swapChainIndex]; + m_frame.m_finalRenderTarget = m_finalRenderTarget[m_frame.index()].m_handle; + m_frame.m_resourcePool = &m_resourcePool[m_frame.index()]; + m_frame.m_cmd = m_frame.cmd(); + m_frame.m_renderer = this; FenceStatus fenceStatus; - auto& completeFence = frame.m_renderCompleteFence; - getFenceStatus(m_renderer, completeFence, &fenceStatus); - if (fenceStatus == FENCE_STATUS_INCOMPLETE) { - waitForFences(m_renderer, 1, &completeFence); - } - acquireNextImage(m_renderer, m_swapChain.m_handle, m_imageAcquiredSemaphore, nullptr, &m_swapChainIndex); + getFenceStatus(m_renderer, m_frame.m_cmdRingElement.pFence, &fenceStatus); + if (fenceStatus == FENCE_STATUS_INCOMPLETE) + waitForFences(m_renderer, 1, &m_frame.m_cmdRingElement.pFence); - resetCmdPool(m_renderer, frame.m_cmdPool); - frame.m_resourcePool->ResetPool(); - beginCmd(frame.m_cmd); + resetCmdPool(m_renderer, m_frame.m_cmdRingElement.pCmdPool); + m_frame.m_resourcePool->ResetPool(); + beginCmd(m_frame.cmd()); - auto& swapChainImage = frame.m_swapChain->ppRenderTargets[m_swapChainIndex]; std::array rtBarriers = { - RenderTargetBarrier { swapChainImage, RESOURCE_STATE_PRESENT, RESOURCE_STATE_RENDER_TARGET }, + RenderTargetBarrier { m_frame.finalTarget(), RESOURCE_STATE_SHADER_RESOURCE, RESOURCE_STATE_RENDER_TARGET }, }; - frame.m_resourcePool->Push(m_finalRenderTarget[frame.m_frameIndex]); - cmdResourceBarrier(frame.m_cmd, 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); + + m_frame.pushResource(m_finalRenderTarget[m_frame.index()]); + cmdResourceBarrier(m_frame.cmd(), 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); } void ForgeRenderer::SubmitFrame() { - auto frame = GetFrame(); - auto& waitSemaphores = m_waitSemaphores[frame.m_frameIndex]; - auto& swapChainTarget = frame.m_swapChain->ppRenderTargets[frame.m_swapChainIndex]; + uint32_t swapChainIndex = 0; + acquireNextImage(m_renderer, m_swapChain.m_handle, m_imageAcquiredSemaphore, NULL, &swapChainIndex); + RenderTarget* swapChainTarget = m_swapChain.m_handle->ppRenderTargets[swapChainIndex]; + { - cmdBindRenderTargets(frame.m_cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); + cmdBindRenderTargets(m_frame.cmd(), 0, NULL, NULL, NULL, NULL, NULL, -1, -1); std::array rtBarriers = { - RenderTargetBarrier{ m_finalRenderTarget[frame.m_frameIndex].m_handle, RESOURCE_STATE_RENDER_TARGET, RESOURCE_STATE_SHADER_RESOURCE}, + RenderTargetBarrier { swapChainTarget, RESOURCE_STATE_PRESENT, RESOURCE_STATE_RENDER_TARGET }, + RenderTargetBarrier{ m_frame.finalTarget(), RESOURCE_STATE_RENDER_TARGET, RESOURCE_STATE_SHADER_RESOURCE}, }; - cmdResourceBarrier(frame.m_cmd, 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); + cmdResourceBarrier(m_frame.cmd(), 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); } { - cmdBindRenderTargets(frame.m_cmd, 1, &swapChainTarget, NULL, NULL, NULL, NULL, -1, -1); + cmdBindRenderTargets(m_frame.cmd(), 1, &swapChainTarget, NULL, NULL, NULL, NULL, -1, -1); uint32_t rootConstantIndex = getDescriptorIndexFromName(m_finalRootSignature , "uRootConstants"); - cmdSetViewport(frame.m_cmd, 0.0f, 0.0f, static_cast(swapChainTarget->mWidth), static_cast(swapChainTarget->mHeight), 0.0f, 1.0f); - cmdSetScissor(frame.m_cmd, 0, 0, static_cast(swapChainTarget->mWidth), static_cast(swapChainTarget->mHeight)); - cmdBindPipeline(frame.m_cmd, m_finalPipeline.m_handle); - cmdBindPushConstants(frame.m_cmd, m_finalRootSignature, rootConstantIndex, &m_gamma); - - std::array params = {}; - params[0].pName = "sourceInput"; - params[0].ppTextures = &m_finalRenderTarget[frame.m_frameIndex].m_handle->pTexture; - updateDescriptorSet( - frame.m_renderer->Rend(), 0, m_finalPerFrameDescriptorSet[frame.m_frameIndex].m_handle, params.size(), params.data()); - cmdBindDescriptorSet(frame.m_cmd, 0, m_finalPerFrameDescriptorSet[frame.m_frameIndex].m_handle); - cmdDraw(frame.m_cmd, 3, 0); + cmdSetViewport(m_frame.cmd(), 0.0f, 0.0f, m_frame.finalTarget()->mWidth, m_frame.finalTarget()->mHeight, 0.0f, 1.0f); + cmdSetScissor(m_frame.cmd(), 0, 0, m_frame.finalTarget()->mWidth, m_frame.finalTarget()->mHeight); + cmdBindPipeline(m_frame.cmd(), m_finalPipeline.m_handle); + cmdBindPushConstants(m_frame.cmd(), m_finalRootSignature, rootConstantIndex, &m_gamma); + + std::array params = { + DescriptorData {.pName = "sourceInput", .ppTextures = &m_frame.finalTarget()->pTexture} + }; + updateDescriptorSet(m_renderer, 0, m_finalPerFrameDescriptorSet[m_frame.index()].m_handle, params.size(), params.data()); + cmdBindDescriptorSet(m_frame.cmd(), 0, m_finalPerFrameDescriptorSet[m_frame.index()].m_handle); + cmdDraw(m_frame.cmd(), 3, 0); } { - cmdBindRenderTargets(frame.m_cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); + cmdBindRenderTargets(m_frame.cmd(), 0, NULL, NULL, NULL, NULL, NULL, -1, -1); std::array rtBarriers = { - RenderTargetBarrier{ m_finalRenderTarget[frame.m_frameIndex].m_handle, RESOURCE_STATE_SHADER_RESOURCE, RESOURCE_STATE_RENDER_TARGET}, RenderTargetBarrier{ swapChainTarget, RESOURCE_STATE_RENDER_TARGET, RESOURCE_STATE_PRESENT }, }; - cmdResourceBarrier(frame.m_cmd, 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); + cmdResourceBarrier(m_frame.cmd(), 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); } - endCmd(m_cmds[frame.m_frameIndex]); - FlushResourceUpdateDesc flushUpdateDesc = {}; flushUpdateDesc.mNodeIndex = 0; flushResourceUpdates(&flushUpdateDesc); - waitSemaphores.push_back(flushUpdateDesc.pOutSubmittedSemaphore); - waitSemaphores.push_back(m_imageAcquiredSemaphore); + endCmd(m_frame.cmd()); + std::array waitSemaphores = {flushUpdateDesc.pOutSubmittedSemaphore, m_imageAcquiredSemaphore}; QueueSubmitDesc submitDesc = {}; - submitDesc.mCmdCount = 1; - submitDesc.mSignalSemaphoreCount = 1; submitDesc.mWaitSemaphoreCount = waitSemaphores.size(); - submitDesc.ppCmds = &frame.m_cmd; - submitDesc.ppSignalSemaphores = &frame.m_renderCompleteSemaphore; submitDesc.ppWaitSemaphores = waitSemaphores.data(); - submitDesc.pSignalFence = frame.m_renderCompleteFence; + submitDesc.mCmdCount = 1; + submitDesc.ppCmds = m_frame.RingElement().pCmds; + submitDesc.mSignalSemaphoreCount = 1; + submitDesc.ppSignalSemaphores = &m_frame.RingElement().pSemaphore; + submitDesc.pSignalFence = m_frame.RingElement().pFence; queueSubmit(m_graphicsQueue, &submitDesc); QueuePresentDesc presentDesc = {}; - presentDesc.mIndex = m_swapChainIndex; + presentDesc.mIndex = swapChainIndex; presentDesc.mWaitSemaphoreCount = 1; presentDesc.pSwapChain = m_swapChain.m_handle; - presentDesc.ppWaitSemaphores = &frame.m_renderCompleteSemaphore; + presentDesc.ppWaitSemaphores = &m_frame.RingElement().pSemaphore; presentDesc.mSubmitDone = true; queuePresent(m_graphicsQueue, &presentDesc); - waitSemaphores.clear(); + m_frame.m_isFinished = true; } void ForgeRenderer::InitializeRenderer(window::NativeWindowWrapper* window) { m_window = window; SyncToken token = {}; - RendererDesc desc{}; #ifdef HPL2_RENDERDOC_ENABLED static RENDERDOC_API_1_1_2* rdoc_api = NULL; @@ -133,32 +139,35 @@ namespace hpl { #endif - initRenderer("test", &desc, &m_renderer); + RendererDesc settings; + memset(&settings, 0, sizeof(settings)); + initRenderer("HPL2", &settings, &m_renderer); QueueDesc queueDesc = {}; queueDesc.mType = QUEUE_TYPE_GRAPHICS; queueDesc.mFlag = QUEUE_FLAG_INIT_MICROPROFILE; addQueue(m_renderer, &queueDesc, &m_graphicsQueue); - for (size_t i = 0; i < m_cmds.size(); i++) { - CmdPoolDesc cmdPoolDesc = {}; - cmdPoolDesc.pQueue = m_graphicsQueue; - addCmdPool(m_renderer, &cmdPoolDesc, &m_cmdPools[i]); - CmdDesc cmdDesc = {}; - cmdDesc.pPool = m_cmdPools[i]; - addCmd(m_renderer, &cmdDesc, &m_cmds[i]); - } + GpuCmdRingDesc cmdRingDesc = {}; + cmdRingDesc.pQueue = m_graphicsQueue; + cmdRingDesc.mPoolCount = SwapChainLength; + cmdRingDesc.mCmdPerPoolCount = 1; + cmdRingDesc.mAddSyncPrimitives = true; + addGpuCmdRing(m_renderer, &cmdRingDesc, &m_graphicsCmdRing); + const auto windowSize = window->GetWindowSize(); m_swapChain.Load(m_renderer, [&](SwapChain** handle) { SwapChainDesc swapChainDesc = {}; swapChainDesc.mWindowHandle = m_window->ForgeWindowHandle(); + m_swapChainCount = getRecommendedSwapchainImageCount(m_renderer, &swapChainDesc.mWindowHandle); swapChainDesc.mPresentQueueCount = 1; swapChainDesc.ppPresentQueues = &m_graphicsQueue; swapChainDesc.mWidth = windowSize.x; swapChainDesc.mHeight = windowSize.y; - swapChainDesc.mImageCount = SwapChainLength; + swapChainDesc.mImageCount = m_swapChainCount; swapChainDesc.mColorFormat = TinyImageFormat_R8G8B8A8_UNORM;//getRecommendedSwapchainFormat(false, false); + swapChainDesc.mColorSpace = COLOR_SPACE_SDR_LINEAR; swapChainDesc.mColorClearValue = { { 1, 1, 1, 1 } }; swapChainDesc.mEnableVsync = false; addSwapChain(m_renderer, &swapChainDesc, handle); @@ -168,12 +177,6 @@ namespace hpl { addRootSignature(m_renderer, &graphRootDesc, &m_pipelineSignature); addSemaphore(m_renderer, &m_imageAcquiredSemaphore); - for (auto& completeSem : m_renderCompleteSemaphores) { - addSemaphore(m_renderer, &completeSem); - } - for (auto& completeFence : m_renderCompleteFences) { - addFence(m_renderer, &completeFence); - } for(auto& rt: m_finalRenderTarget) { rt.Load(m_renderer,[&](RenderTarget** target) { RenderTargetDesc renderTarget = {}; @@ -186,8 +189,8 @@ namespace hpl { renderTarget.mDescriptors = DESCRIPTOR_TYPE_TEXTURE; renderTarget.mSampleCount = SAMPLE_COUNT_1; renderTarget.mSampleQuality = 0; - renderTarget.mStartState = RESOURCE_STATE_RENDER_TARGET; - renderTarget.pName = "final RT"; + renderTarget.mStartState = RESOURCE_STATE_SHADER_RESOURCE; + renderTarget.pName = "final output RT"; addRenderTarget(m_renderer, &renderTarget, target); return true; }); @@ -263,7 +266,8 @@ namespace hpl { RootSignatureDesc rootDesc = { &m_copyShader, 1 }; addRootSignature(m_renderer, &rootDesc, &m_copyPostProcessingRootSignature); DescriptorSetDesc setDesc = { m_copyPostProcessingRootSignature, DESCRIPTOR_UPDATE_FREQ_PER_DRAW, MaxCopyFrames }; - addDescriptorSet(m_renderer, &setDesc, &m_copyPostProcessingDescriptorSet); + addDescriptorSet(m_renderer, &setDesc, &m_copyPostProcessingDescriptorSet[0]); + addDescriptorSet(m_renderer, &setDesc, &m_copyPostProcessingDescriptorSet[1]); DepthStateDesc depthStateDisabledDesc = {}; depthStateDisabledDesc.mDepthWrite = false; @@ -302,6 +306,7 @@ namespace hpl { } m_windowEventHandler.Connect(window->NativeWindowEvent()); + IncrementFrame(); } Sampler* ForgeRenderer::resolve(SamplerPoolKey key) { @@ -331,10 +336,11 @@ namespace hpl { swapChainDesc.ppPresentQueues = &m_graphicsQueue; swapChainDesc.mWidth = windowSize.x; swapChainDesc.mHeight = windowSize.y; - swapChainDesc.mImageCount = SwapChainLength; + swapChainDesc.mImageCount = m_swapChainCount; swapChainDesc.mColorFormat = TinyImageFormat_R8G8B8A8_UNORM;//getRecommendedSwapchainFormat(false, false); + swapChainDesc.mColorSpace = COLOR_SPACE_SDR_LINEAR; swapChainDesc.mColorClearValue = { { 1, 1, 1, 1 } }; - swapChainDesc.mEnableVsync = false; + swapChainDesc.mEnableVsync = true; addSwapChain(m_renderer, &swapChainDesc, handle); return true; }); @@ -352,7 +358,7 @@ namespace hpl { renderTarget.mDescriptors = DESCRIPTOR_TYPE_TEXTURE; renderTarget.mSampleCount = SAMPLE_COUNT_1; renderTarget.mSampleQuality = 0; - renderTarget.mStartState = RESOURCE_STATE_RENDER_TARGET; + renderTarget.mStartState = RESOURCE_STATE_SHADER_RESOURCE; renderTarget.pName = "final RT"; addRenderTarget(m_renderer, &renderTarget, target); return true; @@ -366,16 +372,15 @@ namespace hpl { }){ } - void ForgeRenderer::InitializeResource() { - } void ForgeRenderer::cmdCopyTexture(Cmd* cmd, Texture* srcTexture, RenderTarget* dstTexture) { ASSERT(srcTexture != nullptr); ASSERT(dstTexture != nullptr); + m_copyRegionDescriptorIndex = (m_copyRegionDescriptorIndex + 1) % MaxCopyFrames; - std::array params = {}; - params[0].pName = "inputMap"; - params[0].ppTextures = &srcTexture; + std::array params = { + DescriptorData { .pName = "inputMap", .ppTextures = &srcTexture} + }; LoadActionsDesc loadActions = {}; loadActions.mLoadActionsColor[0] = LOAD_ACTION_LOAD; @@ -385,7 +390,7 @@ namespace hpl { cmdSetViewport(cmd, 0.0f, 0.0f, static_cast(dstTexture->mWidth), static_cast(dstTexture->mHeight), 0.0f, 1.0f); cmdSetScissor(cmd, 0, 0, dstTexture->mWidth, dstTexture->mHeight); - updateDescriptorSet(m_renderer, m_copyRegionDescriptorIndex, m_copyPostProcessingDescriptorSet, params.size(), params.data()); + updateDescriptorSet(m_renderer, m_copyRegionDescriptorIndex, m_copyPostProcessingDescriptorSet[m_frame.index()], params.size(), params.data()); auto swapChainFormat = TinyImageFormat_R8G8B8A8_UNORM;//getSupportedSwapchainFormat(m_renderer, false, false); switch(dstTexture->mFormat) { case TinyImageFormat_R8G8B8A8_UNORM: @@ -396,9 +401,8 @@ namespace hpl { break; } - cmdBindDescriptorSet(cmd, m_copyRegionDescriptorIndex, m_copyPostProcessingDescriptorSet); + cmdBindDescriptorSet(cmd, m_copyRegionDescriptorIndex, m_copyPostProcessingDescriptorSet[m_frame.index()]); cmdDraw(cmd, 3, 0); - m_copyRegionDescriptorIndex = (m_copyRegionDescriptorIndex + 1) % MaxCopyFrames; } }; // namespace hpl diff --git a/HPL2/sources/graphics/RendererDeferred.cpp b/HPL2/sources/graphics/RendererDeferred.cpp index 8c0f7a078..e95c05b2c 100644 --- a/HPL2/sources/graphics/RendererDeferred.cpp +++ b/HPL2/sources/graphics/RendererDeferred.cpp @@ -3883,15 +3883,14 @@ namespace hpl { void cRendererDeferred::Draw( Cmd* cmd, - const ForgeRenderer::Frame& frame, + ForgeRenderer::Frame& frame, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) { + cRenderSettings* apSettings) { // keep around for the moment ... - BeginRendering(afFrameTime, apFrustum, apWorld, apSettings, abSendFrameBufferToPostEffects); + BeginRendering(afFrameTime, apFrustum, apWorld, apSettings, false); if (frame.m_currentFrame != m_activeFrame) { m_materialSet.m_objectIndex = 0; diff --git a/HPL2/sources/graphics/RendererDeferred2.cpp b/HPL2/sources/graphics/RendererDeferred2.cpp index 3bca5edf1..fd32e40e2 100644 --- a/HPL2/sources/graphics/RendererDeferred2.cpp +++ b/HPL2/sources/graphics/RendererDeferred2.cpp @@ -210,7 +210,8 @@ namespace hpl { } // namespace detail cRendererDeferred2::cRendererDeferred2(cGraphics* apGraphics, cResources* apResources, std::shared_ptr debug) - : iRenderer("Deferred2", apGraphics, apResources) { + : iRenderer("Deferred2", apGraphics, apResources), + m_copySubpass(*Interface::Get()){ auto* forgeRenderer = Interface::Get(); m_sceneTexture2DPool = BindlessDescriptorPool(ForgeRenderer::SwapChainLength, resource::MaxScene2DTextureCount); m_sceneTextureCubePool = BindlessDescriptorPool(ForgeRenderer::SwapChainLength, resource::MaxSceneCubeTextureCount); @@ -244,7 +245,7 @@ namespace hpl { return true; }); m_samplerMaterial.Load(forgeRenderer->Rend(), [&](Sampler** sampler) { - SamplerDesc pointSamplerDesc = { FILTER_LINEAR, FILTER_LINEAR, MIPMAP_MODE_LINEAR, + SamplerDesc pointSamplerDesc = { FILTER_LINEAR, FILTER_LINEAR, MIPMAP_MODE_NEAREST, ADDRESS_MODE_REPEAT, ADDRESS_MODE_REPEAT, ADDRESS_MODE_REPEAT }; addSampler(forgeRenderer->Rend(), &pointSamplerDesc, sampler); return true; @@ -441,23 +442,26 @@ namespace hpl { m_translucencyRefractionShaderAlpha.m_handle, m_translucencyRefractionShaderPremulAlpha.m_handle, m_translucencyIlluminationShaderPremulAlpha.m_handle }; - Sampler* vbShadeSceneSamplers[] = { m_samplerLinearClampToBorder.m_handle, + std::array vbShadeSceneSamplers = { m_samplerLinearClampToBorder.m_handle, m_samplerMaterial.m_handle, m_samplerNearEdgeClamp.m_handle, m_samplerPointWrap.m_handle }; - const char* vbShadeSceneSamplersNames[] = { + std::array vbShadeSceneSamplersNames = { "linearBorderSampler", "sceneSampler", "nearEdgeClampSampler", "nearPointWrapSampler" }; RootSignatureDesc rootSignatureDesc = {}; rootSignatureDesc.ppShaders = shaders.data(); rootSignatureDesc.mShaderCount = shaders.size(); - rootSignatureDesc.mStaticSamplerCount = std::size(vbShadeSceneSamplersNames); - rootSignatureDesc.ppStaticSamplers = vbShadeSceneSamplers; - rootSignatureDesc.ppStaticSamplerNames = vbShadeSceneSamplersNames; + rootSignatureDesc.mStaticSamplerCount = vbShadeSceneSamplersNames.size(); + rootSignatureDesc.ppStaticSamplers = vbShadeSceneSamplers.data(); + rootSignatureDesc.ppStaticSamplerNames = vbShadeSceneSamplersNames.data(); rootSignatureDesc.mMaxBindlessTextures = hpl::resource::MaxScene2DTextureCount; addRootSignature(forgeRenderer->Rend(), &rootSignatureDesc, signature); return true; }); + + + // Indirect Argument signature { uint32_t indirectArgCount = 0; @@ -540,9 +544,8 @@ namespace hpl { addPipeline(forgeRenderer->Rend(), &pipelineDesc, pipeline); return true; }); - - m_visiblityShadePass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { - std::array colorFormats = { ColorBufferFormat, TinyImageFormat_R16G16B16A16_SFLOAT }; + m_visbilityEmitBufferPass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { + std::array colorFormats = { ColorBufferFormat }; RasterizerStateDesc rasterizerStateDesc = {}; rasterizerStateDesc.mCullMode = CULL_MODE_FRONT; rasterizerStateDesc.mFrontFace = FRONT_FACE_CCW; @@ -552,7 +555,7 @@ namespace hpl { depthStateDisabledDesc.mDepthTest = false; PipelineDesc pipelineDesc = {}; - pipelineDesc.pName = "visibility shade pass"; + pipelineDesc.pName = "visibility emit shade pass"; pipelineDesc.mType = PIPELINE_TYPE_GRAPHICS; auto& pipelineSettings = pipelineDesc.mGraphicsDesc; pipelineSettings.mPrimitiveTopo = PRIMITIVE_TOPO_TRI_LIST; @@ -561,7 +564,7 @@ namespace hpl { pipelineSettings.mSampleCount = SAMPLE_COUNT_1; pipelineSettings.mSampleQuality = 0; pipelineSettings.pRootSignature = m_sceneRootSignature.m_handle; - pipelineSettings.pShaderProgram = m_visibilityShadePassShader.m_handle; + pipelineSettings.pShaderProgram = m_visibilityBufferEmitPassShader.m_handle; pipelineSettings.pRasterizerState = &rasterizerStateDesc; pipelineSettings.pDepthState = &depthStateDisabledDesc; pipelineSettings.pVertexLayout = nullptr; @@ -569,18 +572,19 @@ namespace hpl { return true; }); - m_visbilityEmitBufferPass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { + m_visiblityShadePass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { std::array colorFormats = { ColorBufferFormat }; RasterizerStateDesc rasterizerStateDesc = {}; rasterizerStateDesc.mCullMode = CULL_MODE_FRONT; rasterizerStateDesc.mFrontFace = FRONT_FACE_CCW; + DepthStateDesc depthStateDisabledDesc = {}; depthStateDisabledDesc.mDepthWrite = false; depthStateDisabledDesc.mDepthTest = false; PipelineDesc pipelineDesc = {}; - pipelineDesc.pName = "visibility emit shade pass"; + pipelineDesc.pName = "visibility shade pass"; pipelineDesc.mType = PIPELINE_TYPE_GRAPHICS; auto& pipelineSettings = pipelineDesc.mGraphicsDesc; pipelineSettings.mPrimitiveTopo = PRIMITIVE_TOPO_TRI_LIST; @@ -589,14 +593,16 @@ namespace hpl { pipelineSettings.mSampleCount = SAMPLE_COUNT_1; pipelineSettings.mSampleQuality = 0; pipelineSettings.pRootSignature = m_sceneRootSignature.m_handle; - pipelineSettings.pShaderProgram = m_visibilityBufferEmitPassShader.m_handle; + pipelineSettings.pShaderProgram = m_visibilityShadePassShader.m_handle; pipelineSettings.pRasterizerState = &rasterizerStateDesc; pipelineSettings.pDepthState = &depthStateDisabledDesc; pipelineSettings.pVertexLayout = nullptr; + // pipelineSettings.pBlendState = &blendStateDesc; addPipeline(forgeRenderer->Rend(), &pipelineDesc, pipeline); return true; }); + m_visibilityBufferPass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { VertexLayout vertexLayout = {}; vertexLayout.mBindingCount = 1; @@ -1322,6 +1328,7 @@ namespace hpl { DescriptorData{ .pName = "dissolveTexture", .ppTextures = &m_dissolveImage->GetTexture().m_handle }, DescriptorData{ .pName = "sceneDiffuseMat", .ppBuffers = &m_diffuseMatUniformBuffer.m_handle }, + DescriptorData{ .pName = "sceneTranslucentMat", .ppBuffers = &m_translucencyMatBuffer.m_handle }, // DescriptorData{ .pName = "sceneFilters", .mCount = samplers.size(), .ppSamplers = samplers.data() }, DescriptorData{ .pName = "vtxOpaqueIndex", .ppBuffers = &opaqueSet.indexBuffer().m_handle }, DescriptorData{ .pName = "vtxOpaquePosition", @@ -1448,13 +1455,15 @@ namespace hpl { void cRendererDeferred2::Draw( Cmd* cmd, - const ForgeRenderer::Frame& frame, + ForgeRenderer::Frame& frame, cViewport& viewport, float frameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) { + cRenderSettings* apSettings) { + + BeginRendering(frameTime, apFrustum, apWorld, apSettings, false); + auto* forgeRenderer = Interface::Get(); auto* graphicsAllocator = Interface::Get(); if (frame.m_currentFrame != m_activeFrame) { @@ -1485,7 +1494,6 @@ namespace hpl { m_objectIndex = 0; m_activeFrame = frame.m_currentFrame; } - const bool supportIndirectRootConstant = forgeRenderer->Rend()->pGpu->mSettings.mIndirectRootConstant; auto viewportDatum = m_boundViewportData.resolve(viewport); if (!viewportDatum || viewportDatum->m_size != viewport.GetSizeU2()) { @@ -1498,14 +1506,13 @@ namespace hpl { renderTargetDesc.mArraySize = 1; renderTargetDesc.mClearValue = optimizedColorClearBlack; renderTargetDesc.mDepth = 1; - renderTargetDesc.mDescriptors = DESCRIPTOR_TYPE_TEXTURE; renderTargetDesc.mWidth = updateDatum->m_size.x; renderTargetDesc.mHeight = updateDatum->m_size.y; renderTargetDesc.mSampleCount = SAMPLE_COUNT_1; renderTargetDesc.mSampleQuality = 0; renderTargetDesc.mStartState = RESOURCE_STATE_SHADER_RESOURCE; renderTargetDesc.mFormat = TinyImageFormat_R8G8B8A8_UNORM; - renderTargetDesc.mDescriptors = DESCRIPTOR_TYPE_TEXTURE; + renderTargetDesc.mDescriptors = DESCRIPTOR_TYPE_TEXTURE | DESCRIPTOR_TYPE_RW_TEXTURE; renderTargetDesc.pName = "output RT"; addRenderTarget(forgeRenderer->Rend(), &renderTargetDesc, target); return true; @@ -1561,6 +1568,25 @@ namespace hpl { return true; }); + updateDatum->m_refractionImage[i].Load([&](Texture** texture) { + TextureLoadDesc loadDesc = {}; + loadDesc.ppTexture = texture; + TextureDesc refractionImageDesc = {}; + refractionImageDesc.mArraySize = 1; + refractionImageDesc.mDepth = 1; + refractionImageDesc.mMipLevels = 1; + refractionImageDesc.mFormat = TinyImageFormat_R8G8B8A8_UNORM; + refractionImageDesc.mDescriptors = DESCRIPTOR_TYPE_TEXTURE | DESCRIPTOR_TYPE_RW_TEXTURE; + refractionImageDesc.mWidth = updateDatum->m_size.x; + refractionImageDesc.mHeight = updateDatum->m_size.y; + refractionImageDesc.mSampleCount = SAMPLE_COUNT_1; + refractionImageDesc.mSampleQuality = 0; + refractionImageDesc.mStartState = RESOURCE_STATE_SHADER_RESOURCE; + refractionImageDesc.pName = "Refraction Image"; + loadDesc.pDesc = &refractionImageDesc; + addResource(&loadDesc, nullptr); + return true; + }); updateDatum->m_visiblityBuffer[i].Load(forgeRenderer->Rend(), [&](RenderTarget** target) { ClearValue optimizedColorClearBlack = { { 0.0f, 0.0f, 0.0f, 0.0f } }; RenderTargetDesc renderTargetDesc = {}; @@ -1572,7 +1598,7 @@ namespace hpl { renderTargetDesc.mHeight = updateDatum->m_size.y; renderTargetDesc.mSampleCount = SAMPLE_COUNT_1; renderTargetDesc.mSampleQuality = 0; - renderTargetDesc.mStartState = RESOURCE_STATE_SHADER_RESOURCE; + renderTargetDesc.mStartState = RESOURCE_STATE_RENDER_TARGET; renderTargetDesc.mFormat = TinyImageFormat_R8G8B8A8_UNORM; renderTargetDesc.mDescriptors = DESCRIPTOR_TYPE_TEXTURE; addRenderTarget(forgeRenderer->Rend(), &renderTargetDesc, target); @@ -1587,6 +1613,7 @@ namespace hpl { frame.m_resourcePool->Push(viewportDatum->m_depthBuffer[frame.m_frameIndex]); frame.m_resourcePool->Push(viewportDatum->m_outputBuffer[frame.m_frameIndex]); frame.m_resourcePool->Push(viewportDatum->m_albedoBuffer[frame.m_frameIndex]); + frame.m_resourcePool->Push(viewportDatum->m_refractionImage[frame.m_frameIndex]); // ---------------- // Setup Data // ----------------- @@ -1596,6 +1623,8 @@ namespace hpl { .ppTextures = &viewportDatum->m_visiblityBuffer[frame.m_frameIndex].m_handle->pTexture }, DescriptorData{ .pName = "albedoTexture", .ppTextures = &viewportDatum->m_albedoBuffer[frame.m_frameIndex].m_handle->pTexture }, + DescriptorData{ .pName = "refractionTexture", + .ppTextures = &viewportDatum->m_refractionImage[frame.m_frameIndex].m_handle }, }; updateDescriptorSet( forgeRenderer->Rend(), 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle, params.size(), params.data()); @@ -2131,16 +2160,17 @@ namespace hpl { // ----------------- { cmdBindRenderTargets(cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); - std::array rtBarriers = { - RenderTargetBarrier{ viewportDatum->m_visiblityBuffer[frame.m_frameIndex].m_handle, - RESOURCE_STATE_SHADER_RESOURCE, - RESOURCE_STATE_RENDER_TARGET }, - }; - cmdResourceBarrier(cmd, 0, nullptr, 0, nullptr, rtBarriers.size(), rtBarriers.data()); + std::array barriers = { BufferBarrier{ m_lightClusterCountBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_UNORDERED_ACCESS, + RESOURCE_STATE_SHADER_RESOURCE }, + BufferBarrier{ m_lightClustersBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_UNORDERED_ACCESS, + RESOURCE_STATE_SHADER_RESOURCE} }; + cmdResourceBarrier(cmd, barriers.size(), barriers.data(), 0, nullptr, 0, nullptr); } { auto& opaqueSet = graphicsAllocator->resolveSet(GraphicsAllocator::AllocationSet::OpaqueSet); - cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Buffer Pass"); + //cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Buffer Pass"); { std::array semantics = { ShaderSemantic::SEMANTIC_POSITION }; LoadActionsDesc loadActions = {}; @@ -2219,31 +2249,21 @@ namespace hpl { nullptr, 0); } - cmdEndDebugMarker(cmd); } { cmdBindRenderTargets(cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); - std::array barriers = { BufferBarrier{ m_lightClusterCountBuffer[frame.m_frameIndex].m_handle, - RESOURCE_STATE_UNORDERED_ACCESS, - RESOURCE_STATE_SHADER_RESOURCE }, - BufferBarrier{ m_lightClustersBuffer[frame.m_frameIndex].m_handle, - RESOURCE_STATE_UNORDERED_ACCESS, - RESOURCE_STATE_SHADER_RESOURCE } }; std::array rtBarriers = { RenderTargetBarrier{ viewportDatum->m_visiblityBuffer[frame.m_frameIndex].m_handle, RESOURCE_STATE_RENDER_TARGET, - RESOURCE_STATE_SHADER_RESOURCE }, + RESOURCE_STATE_PIXEL_SHADER_RESOURCE}, RenderTargetBarrier{ viewportDatum->m_albedoBuffer[frame.m_frameIndex].m_handle, RESOURCE_STATE_SHADER_RESOURCE, - RESOURCE_STATE_RENDER_TARGET }, - RenderTargetBarrier{ viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, - RESOURCE_STATE_SHADER_RESOURCE, - RESOURCE_STATE_RENDER_TARGET }, + RESOURCE_STATE_RENDER_TARGET}, }; - cmdResourceBarrier(cmd, barriers.size(), barriers.data(), 0, nullptr, rtBarriers.size(), rtBarriers.data()); + cmdResourceBarrier(cmd, 0, nullptr, 0, nullptr, rtBarriers.size(), rtBarriers.data()); } { - cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Emit Buffer Pass"); + //cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Emit Buffer Pass"); LoadActionsDesc loadActions = {}; loadActions.mLoadActionsColor[0] = LOAD_ACTION_CLEAR; loadActions.mClearColorValues[0] = { .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 0.0f }; @@ -2257,10 +2277,10 @@ namespace hpl { cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorConstSet.m_handle); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle); cmdDraw(cmd, 3, 0); - cmdEndDebugMarker(cmd); + //cmdEndDebugMarker(cmd); } { - cmdBeginDebugMarker(cmd, 0, 1, 0, "Decal Output Buffer Pass"); + //cmdBeginDebugMarker(cmd, 0, 1, 0, "Decal Output Buffer Pass"); auto& opaqueSet = graphicsAllocator->resolveSet(GraphicsAllocator::AllocationSet::OpaqueSet); std::array semantics = { ShaderSemantic::SEMANTIC_POSITION, ShaderSemantic::SEMANTIC_TEXCOORD0, @@ -2310,36 +2330,69 @@ namespace hpl { 0); } - cmdEndDebugMarker(cmd); + //cmdEndDebugMarker(cmd); } { cmdBindRenderTargets(cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); std::array rtBarriers = { RenderTargetBarrier{ viewportDatum->m_albedoBuffer[frame.m_frameIndex].m_handle, RESOURCE_STATE_RENDER_TARGET, - RESOURCE_STATE_SHADER_RESOURCE }, + RESOURCE_STATE_SHADER_RESOURCE}, + RenderTargetBarrier{ viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_SHADER_RESOURCE, + RESOURCE_STATE_RENDER_TARGET}, }; cmdResourceBarrier(cmd, 0, nullptr, 0, nullptr, rtBarriers.size(), rtBarriers.data()); } { - cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Output Buffer Pass"); + //cmdBeginDebugMarker(cmd, 0, 1, 0, "Visibility Output Buffer Pass"); LoadActionsDesc loadActions = {}; - loadActions.mLoadActionsColor[0] = LOAD_ACTION_CLEAR; - loadActions.mClearColorValues[0] = { .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 0.0f }; + loadActions.mLoadActionsColor[0] = LOAD_ACTION_LOAD; loadActions.mClearDepth = { .depth = 1.0f, .stencil = 0 }; loadActions.mLoadActionDepth = LOAD_ACTION_DONTCARE; - std::array targets = { viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, - viewportDatum->m_testBuffer[frame.m_frameIndex].m_handle }; + std::array targets = { viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle}; cmdBindRenderTargets(cmd, targets.size(), targets.data(), nullptr, &loadActions, NULL, NULL, -1, -1); cmdSetViewport(cmd, 0.0f, 0.0f, viewportDatum->m_size.x, viewportDatum->m_size.y, 0.0f, 1.0f); cmdSetScissor(cmd, 0, 0, viewportDatum->m_size.x, viewportDatum->m_size.y); - cmdBindPipeline(cmd, m_visiblityShadePass.m_handle); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorConstSet.m_handle); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle); + cmdBindPipeline(cmd, m_visiblityShadePass.m_handle); cmdDraw(cmd, 3, 0); - cmdEndDebugMarker(cmd); + // cmdEndDebugMarker(cmd); + } + { + cmdBindRenderTargets(cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); + std::array textureBarriers = { + TextureBarrier{ viewportDatum->m_refractionImage[frame.m_frameIndex].m_handle, + RESOURCE_STATE_SHADER_RESOURCE, + RESOURCE_STATE_UNORDERED_ACCESS }, + }; + std::array rtBarriers = { + RenderTargetBarrier{ viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_RENDER_TARGET, + RESOURCE_STATE_SHADER_RESOURCE }, + }; + cmdResourceBarrier(frame.m_cmd, 0, NULL, textureBarriers.size(), textureBarriers.data(), rtBarriers.size(), rtBarriers.data()); + } + m_copySubpass.Dispatch( + frame, + viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle->pTexture, + viewportDatum->m_refractionImage[frame.m_frameIndex].m_handle); + { + std::array textureBarriers = { + TextureBarrier{ viewportDatum->m_refractionImage[frame.m_frameIndex].m_handle, + RESOURCE_STATE_UNORDERED_ACCESS, + RESOURCE_STATE_SHADER_RESOURCE }, + }; + std::array rtBarriers = { + RenderTargetBarrier{ + viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_SHADER_RESOURCE, + RESOURCE_STATE_RENDER_TARGET, + }, + }; + cmdResourceBarrier(frame.m_cmd, 0, NULL, textureBarriers.size(), textureBarriers.data(), rtBarriers.size(), rtBarriers.data()); } - { auto& particleSet = graphicsAllocator->resolveSet(GraphicsAllocator::AllocationSet::ParticleSet); auto& opaqueSet = graphicsAllocator->resolveSet(GraphicsAllocator::AllocationSet::OpaqueSet); @@ -2449,12 +2502,17 @@ namespace hpl { RESOURCE_STATE_SHADER_RESOURCE, RESOURCE_STATE_UNORDERED_ACCESS } }; std::array rtBarriers = { + RenderTargetBarrier{ viewportDatum->m_visiblityBuffer[frame.m_frameIndex].m_handle, + RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + RESOURCE_STATE_RENDER_TARGET}, RenderTargetBarrier{ viewportDatum->m_outputBuffer[frame.m_frameIndex].m_handle, RESOURCE_STATE_RENDER_TARGET, RESOURCE_STATE_SHADER_RESOURCE }, }; cmdResourceBarrier(cmd, barriers.size(), barriers.data(), 0, nullptr, rtBarriers.size(), rtBarriers.data()); } + + } } // namespace hpl diff --git a/HPL2/sources/graphics/RendererWireFrame.cpp b/HPL2/sources/graphics/RendererWireFrame.cpp index cf99a6a0c..0056d1e0a 100644 --- a/HPL2/sources/graphics/RendererWireFrame.cpp +++ b/HPL2/sources/graphics/RendererWireFrame.cpp @@ -221,16 +221,15 @@ namespace hpl { void cRendererWireFrame::Draw( Cmd* cmd, - const ForgeRenderer::Frame& frame, + ForgeRenderer::Frame& frame, cViewport& viewport, float afFrameTime, cFrustum* apFrustum, cWorld* apWorld, - cRenderSettings* apSettings, - bool abSendFrameBufferToPostEffects) { + cRenderSettings* apSettings) { auto* forgeRenderer = Interface::Get(); // keep around for the moment ... - BeginRendering(afFrameTime, apFrustum, apWorld, apSettings, abSendFrameBufferToPostEffects); + BeginRendering(afFrameTime, apFrustum, apWorld, apSettings, false); if (frame.m_currentFrame != m_activeFrame) { m_objectIndex = 0; diff --git a/HPL2/sources/graphics/ScopedBarrier.cpp b/HPL2/sources/graphics/ScopedBarrier.cpp new file mode 100644 index 000000000..3364433ba --- /dev/null +++ b/HPL2/sources/graphics/ScopedBarrier.cpp @@ -0,0 +1,64 @@ +#include "graphics/ScopedBarrier.h" +#include "Common_3/Graphics/Interfaces/IGraphics.h" + +#include + +namespace hpl { + RenderTargetScopedBarrier::RenderTargetScopedBarrier(): m_target(nullptr) { + } + + RenderTargetScopedBarrier::RenderTargetScopedBarrier(RenderTarget* target, ResourceState start, ResourceState end) + : m_target(target) + , m_startState(start) + , m_endState(end) + , m_currentState(start) { + } + void RenderTargetScopedBarrier::Set(RenderTarget* target, ResourceState start, ResourceState end) { + ASSERT(m_target == nullptr); // the scope can't be set twice + m_target = target; + m_startState = start; + m_currentState = start; + m_endState = end; + } + RenderTargetScopedBarrier::RenderTargetScopedBarrier(RenderTargetScopedBarrier&& barrier) + : m_target(barrier.m_target) + , m_startState(barrier.m_startState) + , m_currentState(barrier.m_currentState) { + barrier.m_target = nullptr; + } + void RenderTargetScopedBarrier::operator=(RenderTargetScopedBarrier&& barrier) { + m_target = barrier.m_target; + m_startState = barrier.m_startState; + m_currentState = barrier.m_currentState; + m_endState = barrier.m_endState; + barrier.m_target = nullptr; + } + namespace ScopedBarrier { + void End(Cmd* cmd, std::span barriers) { + std::vector rtBarriers; + for (auto& barrier : barriers) { + if (barrier->m_currentState != barrier->m_endState && barrier->IsValid()) { + rtBarriers.push_back(RenderTargetBarrier{ barrier->m_target, barrier->m_currentState, barrier->m_endState }); + barrier->m_target = nullptr; + } + } + cmdResourceBarrier(cmd, 0, nullptr, 0, nullptr, rtBarriers.size(), rtBarriers.data()); + } + + void Transition( + Cmd* cmd, + std::span transitions + ) { + std::vector rtBarriers; + + for(auto& tran: transitions) { + if(tran.m_newState != tran.m_resource->m_currentState && tran.m_resource->m_target != nullptr) { + rtBarriers.push_back(RenderTargetBarrier{ tran.m_resource->m_target, tran.m_resource->m_currentState, tran.m_newState}); + tran.m_resource->m_currentState = tran.m_newState; + } + } + cmdResourceBarrier(cmd, 0, nullptr, 0, nullptr, rtBarriers.size(), rtBarriers.data()); + } + } // namespace ScopedBarrier + +} // namespace hpl diff --git a/HPL2/sources/scene/Scene.cpp b/HPL2/sources/scene/Scene.cpp index 03413b1ad..5acd6f5f4 100644 --- a/HPL2/sources/scene/Scene.cpp +++ b/HPL2/sources/scene/Scene.cpp @@ -19,9 +19,11 @@ #include "scene/Scene.h" +#include "Common_3/Graphics/Interfaces/IGraphics.h" #include "engine/IUpdateEventLoop.h" #include "engine/Interface.h" #include "graphics/RenderTarget.h" +#include "graphics/ScopedBarrier.h" #include "math/MathTypes.h" #include "scene/Camera.h" #include "scene/Viewport.h" @@ -172,7 +174,7 @@ namespace hpl { } } - void cScene::Render(const ForgeRenderer::Frame& frame, float afFrameTime, tFlag alFlags) { + void cScene::Render(ForgeRenderer::Frame& frame, float afFrameTime, tFlag alFlags) { // Increase the frame count (do this at top, so render count is valid until this Render is called again!) iRenderer::IncRenderFrameCount(); @@ -193,7 +195,7 @@ namespace hpl { iRenderer* pRenderer = pViewPort->GetRenderer(); cCamera* pCamera = pViewPort->GetCamera(); cFrustum* pFrustum = pCamera ? pCamera->GetFrustum() : NULL; - ////////////////////////////////////////////// + // Render world and call callbacks if (alFlags & tSceneRenderFlag_World) { pViewPort->RunViewportCallbackMessage(eViewportMessage_OnPreWorldDraw); @@ -211,8 +213,7 @@ namespace hpl { afFrameTime, pFrustum, pViewPort->GetWorld(), - pViewPort->GetRenderSettings(), - bPostEffects); + pViewPort->GetRenderSettings()); STOP_TIMING(RenderWorld) } else { // If no renderer sets up viewport do that by our selves. @@ -234,13 +235,12 @@ namespace hpl { auto forgeRenderer = Interface::Get(); - ////////////////////////////////////////////// // Render Post effects auto outputImage = pRenderer->GetOutputImage(frame.m_frameIndex, *pViewPort); - if(outputImage.IsValid()) { + const bool isViewportTarget = pViewPort->Target().IsValid(); - auto& target = isViewportTarget ? pViewPort->Target().m_handle : frame.m_finalRenderTarget; + auto target = isViewportTarget ? pViewPort->Target().m_handle : frame.finalTarget(); if (bPostEffects) { START_TIMING(RenderPostEffects) @@ -271,7 +271,13 @@ namespace hpl { forgeRenderer->cmdCopyTexture(frame.m_cmd, outputImage.m_handle->pTexture, target); } } - + //if(outputImage.IsValid()) { + // cmdBindRenderTargets(frame.m_cmd, 0, NULL, NULL, NULL, NULL, NULL, -1, -1); + // std::array rtBarriers = { + // RenderTargetBarrier{ outputImage.m_handle, RESOURCE_STATE_SHADER_RESOURCE, RESOURCE_STATE_RENDER_TARGET }, + // }; + // cmdResourceBarrier(frame.m_cmd, 0, NULL, 0, NULL, rtBarriers.size(), rtBarriers.data()); + //} ////////////////////////////////////////////// // Render Screen GUI if (alFlags & tSceneRenderFlag_Gui) { diff --git a/HPL2/sources/system/Bootstrap.cpp b/HPL2/sources/system/Bootstrap.cpp index fb98bbab9..8594d855c 100644 --- a/HPL2/sources/system/Bootstrap.cpp +++ b/HPL2/sources/system/Bootstrap.cpp @@ -49,14 +49,14 @@ namespace hpl { { return; } - + FileSystemInitDesc fsDesc = {}; fsDesc.pAppName = "HPL2"; if (!initFileSystem(&fsDesc)) { LOGF(eERROR, "Filesystem failed to initialize."); } - + initLog("HPL2", DEFAULT_LOG_LEVEL); fsSetPathForResourceDir(pSystemFileIO, RM_CONTENT, RD_SHADER_BINARIES, "./CompiledShaders"); @@ -88,7 +88,6 @@ namespace hpl { // graphics allocator m_graphicsAlloc = std::make_unique(&m_renderer); - m_renderer.InitializeResource(); gui::InitializeGui(m_renderer); // this is safe because the render target is scheduled on the api thread diff --git a/amnesia/CMakeLists.txt b/amnesia/CMakeLists.txt index a81227770..5a5403261 100644 --- a/amnesia/CMakeLists.txt +++ b/amnesia/CMakeLists.txt @@ -144,6 +144,10 @@ endif() ## ARGS -E copy_directory "${_HPL2_COMPILEDSHADER_}" "$/CompiledShaders" ##) copy_shader_to_target_dir(Amnesia) +add_custom_command ( TARGET Amnesia POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/gpu.cfg $ + ) target_compile_definitions(Amnesia PUBLIC AMNESIA_TDD_VERSION="${AMNESIA_TDD_VERSION}") target_compile_definitions(Amnesia PUBLIC AMNESIA_TDD_TAG="${AMNESIA_TDD_TAG}") diff --git a/amnesia/gpu.cfg b/amnesia/gpu.cfg new file mode 100644 index 000000000..f3b5e0abe --- /dev/null +++ b/amnesia/gpu.cfg @@ -0,0 +1,29 @@ +#version: 0.1 + +BEGIN_GPU_SELECTION; +CHOICE; GraphicQueueSupported == 1; +CHOICE; isHeadLess != 1; +CHOICE; deviceid == PreferredGPU; +CHOICE; GpuPresetLevel; +# Intel vendor: 0x8086 && 0x8087 +CHOICE; VendorID != 0x8086, VendorID != 0x8087; +CHOICE; DirectXFeatureLevel; +CHOICE; VRAM; +END_GPU_SELECTION; + +# Check for INTEL Integrated families. +# There is missing support for boolean logic, so while the following line is preferred, the 3 lines that follow do the same job. +#RULE; IsIntegratedGPU; VendorID == 0x163C || VendorID == 0x8086 || VendorID == 0x8087; 1 +RULE; IsIntegratedGPU; VendorID == 0x163C; 1 +RULE; IsIntegratedGPU; VendorID == 0x8086; 1 +RULE; IsIntegratedGPU; VendorID == 0x8087; 1 + +OPT; MSAASampleCount; Low 4 +OPT; DisableAO; Low 1, Medium 0 +OPT; DisableGodRays; Low 1, Medium 0 + +RULE; BindlessSupported ; MaxBoundTextures < 3075; 0 + +# glPrimitiveID artefacts on steam deck +# VendorID amd = 0x1002, AMD Custom GPU +RULE; AddGeometryPassThrough; DeviceID == 0x163f; 1 \ No newline at end of file diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index a81ab6252..a9c281d9b 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -57,7 +57,7 @@ file(GLOB ZSTD_FILESYSTEM_SOURCES ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd/common/*.c ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd/compress/*.c ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd/decompress/*.c - ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd/decompress/huf_decompress_amd64.S + # ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd/decompress/huf_decompress_amd64.S ) add_library(zstd_filesystem OBJECT ${ZSTD_FILESYSTEM_SOURCES}) target_include_directories(zstd_filesystem PUBLIC ${THE_FORGE_DIR}/Common_3/Utilities/ThirdParty/OpenSource/zstd)