diff --git a/Hydrogent/include/HnRenderDelegate.hpp b/Hydrogent/include/HnRenderDelegate.hpp index de3c5792..b28bf265 100644 --- a/Hydrogent/include/HnRenderDelegate.hpp +++ b/Hydrogent/include/HnRenderDelegate.hpp @@ -56,11 +56,11 @@ class HnRenderDelegate final : public pxr::HdRenderDelegate public: struct CreateInfo { - IRenderDevice* pDevice = nullptr; - IDeviceContext* pContext = nullptr; - IRenderStateCache* pStateCache = nullptr; - IBuffer* pCameraAttribs = nullptr; - IBuffer* pLightAttribs = nullptr; + IRenderDevice* pDevice = nullptr; + IDeviceContext* pContext = nullptr; + IRenderStateCache* pRenderStateCache = nullptr; + IBuffer* pCameraAttribs = nullptr; + IBuffer* pLightAttribs = nullptr; }; static std::unique_ptr Create(const CreateInfo& CI); @@ -199,17 +199,20 @@ class HnRenderDelegate final : public pxr::HdRenderDelegate std::shared_ptr GetUSDRenderer() { return m_USDRenderer; } - IRenderDevice* GetDevice() const { return m_pDevice; } - IDeviceContext* GetDeviceContext() const { return m_pContext; } - IBuffer* GetCameraAttribsCB() const { return m_CameraAttribsCB; } + IRenderDevice* GetDevice() const { return m_pDevice; } + IDeviceContext* GetDeviceContext() const { return m_pContext; } + IRenderStateCache* GetRenderStateCache() const { return m_pRenderStateCache; } + IBuffer* GetCameraAttribsCB() const { return m_CameraAttribsCB; } private: static const pxr::TfTokenVector SupportedRPrimTypes; static const pxr::TfTokenVector SupportedSPrimTypes; static const pxr::TfTokenVector SupportedBPrimTypes; - RefCntAutoPtr m_pDevice; - RefCntAutoPtr m_pContext; + RefCntAutoPtr m_pDevice; + RefCntAutoPtr m_pContext; + RefCntAutoPtr m_pRenderStateCache; + RefCntAutoPtr m_CameraAttribsCB; RefCntAutoPtr m_LightAttribsCB; std::shared_ptr m_USDRenderer; diff --git a/Hydrogent/include/HnRendererImpl.hpp b/Hydrogent/include/HnRendererImpl.hpp index a6e0d148..7cc35d3c 100644 --- a/Hydrogent/include/HnRendererImpl.hpp +++ b/Hydrogent/include/HnRendererImpl.hpp @@ -85,9 +85,6 @@ class HnRendererImpl final : public ObjectBase virtual const pxr::SdfPath* QueryPrimId(IDeviceContext* pCtx, Uint32 X, Uint32 Y) override final; private: - void PrepareRenderTargets(ITextureView* pDstRtv); - void PreparePostProcess(TEXTURE_FORMAT RTVFmt); - void PerformPostProcess(IDeviceContext* pCtx, const HnDrawAttribs& Attribs); void DestroyStageResources(); private: @@ -96,7 +93,6 @@ class HnRendererImpl final : public ObjectBase RefCntAutoPtr m_CameraAttribsCB; RefCntAutoPtr m_LightAttribsCB; - RefCntAutoPtr m_PostProcessAttribsCB; const bool m_ConvertOutputToSRGB; @@ -113,19 +109,8 @@ class HnRendererImpl final : public ObjectBase static constexpr TEXTURE_FORMAT MeshIdFormat = TEX_FORMAT_R32_FLOAT; static constexpr TEXTURE_FORMAT DepthFormat = TEX_FORMAT_D32_FLOAT; - RefCntAutoPtr m_ColorBuffer; - RefCntAutoPtr m_MeshIdTexture; - RefCntAutoPtr m_DepthBufferDSV; - GPUCompletionAwaitQueue> m_MeshIdReadBackQueue; - struct PostProcessState - { - RefCntAutoPtr PSO; - RefCntAutoPtr SRB; - }; - PostProcessState m_PostProcess; - HnRenderParams m_RenderParams; bool m_RenderParamsChanged = true; diff --git a/Hydrogent/include/Tasks/HnPostProcessTask.hpp b/Hydrogent/include/Tasks/HnPostProcessTask.hpp index 9b235ede..c35c7053 100644 --- a/Hydrogent/include/Tasks/HnPostProcessTask.hpp +++ b/Hydrogent/include/Tasks/HnPostProcessTask.hpp @@ -28,6 +28,12 @@ #include "HnTask.hpp" +#include "../../../../DiligentCore/Graphics/GraphicsEngine/interface/PipelineState.h" +#include "../../../../DiligentCore/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h" +#include "../../../../DiligentCore/Graphics/GraphicsEngine/interface/Buffer.h" +#include "../../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp" +#include "../../../../DiligentCore/Common/interface/BasicMath.hpp" + namespace Diligent { @@ -36,10 +42,18 @@ namespace USD struct HnPostProcessTaskParams { + bool ConvertOutputToSRGB = false; + + float4 SelectionColor = float4{0.75f, 0.75f, 0.25f, 0.5f}; + constexpr bool operator==(const HnPostProcessTaskParams& rhs) const { - return true; + // clang-format off + return ConvertOutputToSRGB == rhs.ConvertOutputToSRGB && + SelectionColor == rhs.SelectionColor; + // clang-format on } + constexpr bool operator!=(const HnPostProcessTaskParams& rhs) const { return !(*this == rhs); @@ -62,6 +76,20 @@ class HnPostProcessTask final : public HnTask virtual void Execute(pxr::HdTaskContext* TaskCtx) override final; + +private: + void PreparePSO(TEXTURE_FORMAT RTVFormat); + +private: + pxr::HdRenderIndex* m_RenderIndex = nullptr; + + HnPostProcessTaskParams m_Params; + + bool m_PsoIsDirty = true; + + RefCntAutoPtr m_PSO; + RefCntAutoPtr m_SRB; + RefCntAutoPtr m_PostProcessAttribsCB; }; } // namespace USD diff --git a/Hydrogent/include/Tasks/HnSetupRenderingTask.hpp b/Hydrogent/include/Tasks/HnSetupRenderingTask.hpp index b9440092..12d8f262 100644 --- a/Hydrogent/include/Tasks/HnSetupRenderingTask.hpp +++ b/Hydrogent/include/Tasks/HnSetupRenderingTask.hpp @@ -31,9 +31,13 @@ #include "HnTask.hpp" #include "../interface/HnTypes.hpp" +#include "../../../../DiligentCore/Common/interface/BasicMath.hpp" + namespace Diligent { +struct ITextureView; + namespace USD { @@ -53,6 +57,8 @@ struct HnSetupRenderingTaskParams OcclusionStrength == rhs.OcclusionStrength && EmissionScale == rhs.EmissionScale && IBLScale == rhs.IBLScale && + ClearColor == rhs.ClearColor && + ClearDepth == rhs.ClearDepth && Transform == rhs.Transform && DepthBias == rhs.DepthBias && SlopeScaledDepthBias == rhs.SlopeScaledDepthBias && @@ -89,6 +95,9 @@ struct HnSetupRenderingTaskParams float EmissionScale = 1; float IBLScale = 1; + float4 ClearColor; + float ClearDepth = 1.f; + float4x4 Transform = float4x4::Identity(); float DepthBias = 0; @@ -139,6 +148,15 @@ class HnSetupRenderingTask final : public HnTask pxr::SdfPath m_OffscreenColorTargetId; pxr::SdfPath m_MeshIdTargetId; pxr::SdfPath m_DepthBufferId; + + float4 m_ClearColor; + float m_ClearDepth = 1.f; + + pxr::HdRenderIndex* m_RenderIndex = nullptr; + + ITextureView* m_pFinalColorRTV = nullptr; + ITextureView* m_pMeshIdRTV = nullptr; + ITextureView* m_pDepthDSV = nullptr; }; } // namespace USD diff --git a/Hydrogent/include/Tasks/HnTask.hpp b/Hydrogent/include/Tasks/HnTask.hpp index cd801367..38f1f03a 100644 --- a/Hydrogent/include/Tasks/HnTask.hpp +++ b/Hydrogent/include/Tasks/HnTask.hpp @@ -29,10 +29,14 @@ #include #include "pxr/imaging/hd/task.h" +#include "pxr/imaging/hd/renderIndex.h" + namespace Diligent { +struct ITextureView; + namespace USD { @@ -46,6 +50,9 @@ class HnTask : public pxr::HdTask protected: std::shared_ptr GetRenderPassState(pxr::HdTaskContext* TaskCtx) const; + + static ITextureView* GetRenderBufferTarget(pxr::HdRenderIndex& RenderIndex, const pxr::SdfPath& RenderBufferId); + ITextureView* GetRenderBufferTarget(pxr::HdRenderIndex& RenderIndex, pxr::HdTaskContext* TaskCtx, const pxr::TfToken& Name) const; }; } // namespace USD diff --git a/Hydrogent/src/HnRenderDelegate.cpp b/Hydrogent/src/HnRenderDelegate.cpp index 16dd7ebc..00a1ef44 100644 --- a/Hydrogent/src/HnRenderDelegate.cpp +++ b/Hydrogent/src/HnRenderDelegate.cpp @@ -66,12 +66,13 @@ const pxr::TfTokenVector HnRenderDelegate::SupportedBPrimTypes = HnRenderDelegate::HnRenderDelegate(const CreateInfo& CI) : m_pDevice{CI.pDevice}, m_pContext{CI.pContext}, + m_pRenderStateCache{CI.pRenderStateCache}, m_CameraAttribsCB{CI.pCameraAttribs}, m_LightAttribsCB{CI.pLightAttribs}, m_USDRenderer{ std::make_shared( CI.pDevice, - CI.pStateCache, + CI.pRenderStateCache, CI.pContext, []() { USD_Renderer::CreateInfo USDRendererCI; diff --git a/Hydrogent/src/HnRendererImpl.cpp b/Hydrogent/src/HnRendererImpl.cpp index ab7ee866..14a02bdb 100644 --- a/Hydrogent/src/HnRendererImpl.cpp +++ b/Hydrogent/src/HnRendererImpl.cpp @@ -31,13 +31,13 @@ #include "HnTokens.hpp" #include "Tasks/HnTaskController.hpp" #include "Tasks/HnSetupRenderingTask.hpp" +#include "Tasks/HnPostProcessTask.hpp" #include "EngineMemory.h" #include "USD_Renderer.hpp" #include "EnvMapRenderer.hpp" #include "MapHelper.hpp" #include "CommonlyUsedStates.h" -#include "HnShaderSourceFactory.hpp" #include "HnRenderBuffer.hpp" #include "pxr/imaging/hd/task.h" @@ -50,17 +50,6 @@ namespace Diligent namespace USD { -namespace HLSL -{ - -namespace -{ -#include "Shaders/PBR/public/PBR_Structures.fxh" -#include "../shaders/HnPostProcessStructures.fxh" -} // namespace - -} // namespace HLSL - void CreateHnRenderer(IRenderDevice* pDevice, IDeviceContext* pContext, const HnRendererCreateInfo& CI, IHnRenderer** ppRenderer) { auto* pRenderer = NEW_RC_OBJ(GetRawAllocator(), "HnRenderer instance", HnRendererImpl)(pDevice, pContext, CI); @@ -76,7 +65,6 @@ HnRendererImpl::HnRendererImpl(IReferenceCounters* pRefCounters, m_Context{pContext}, m_CameraAttribsCB{CI.pCameraAttribsCB}, m_LightAttribsCB{CI.pLightAttribsCB}, - m_PostProcessAttribsCB{m_Device.CreateBuffer("Post process attribs CB", sizeof(HLSL::PostProcessAttribs))}, m_ConvertOutputToSRGB{CI.ConvertOutputToSRGB}, m_MeshIdReadBackQueue{pDevice} { @@ -115,6 +103,12 @@ void HnRendererImpl::LoadUSDStage(pxr::UsdStageRefPtr& Stage) m_FinalColorTargetId = SceneDelegateId.AppendChild(pxr::TfToken{"_HnFinalColorTarget_"}); m_RenderIndex->InsertBprim(pxr::HdPrimTypeTokens->renderBuffer, m_ImagingDelegate.get(), m_FinalColorTargetId); + + { + HnPostProcessTaskParams Params; + Params.ConvertOutputToSRGB = m_ConvertOutputToSRGB; + m_TaskController->SetTaskParams(HnTaskController::TaskUID_PostProcess, Params); + } } void HnRendererImpl::SetParams(const HnRenderParams& Params) @@ -151,102 +145,6 @@ void HnRendererImpl::Update() m_ImagingDelegate->ApplyPendingUpdates(); } -void HnRendererImpl::PrepareRenderTargets(ITextureView* pDstRtv) -{ - VERIFY(pDstRtv != nullptr, "Destination render target view must not be null"); - const auto& DstTexDesc = pDstRtv->GetTexture()->GetDesc(); - if (m_ColorBuffer) - { - const auto& ColBuffDesc = m_ColorBuffer->GetDesc(); - if (ColBuffDesc.Width != DstTexDesc.Width || ColBuffDesc.Height != DstTexDesc.Height) - { - m_ColorBuffer.Release(); - m_MeshIdTexture.Release(); - m_DepthBufferDSV.Release(); - } - } - - if (!m_ColorBuffer) - { - TextureDesc TexDesc; - TexDesc.Name = "Color buffer"; - TexDesc.Type = RESOURCE_DIM_TEX_2D; - TexDesc.Width = DstTexDesc.Width; - TexDesc.Height = DstTexDesc.Height; - TexDesc.Format = ColorBufferFormat; - TexDesc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE; - TexDesc.MipLevels = 1; - m_ColorBuffer = m_Device.CreateTexture(TexDesc); - - TexDesc.Name = "Mesh ID buffer"; - TexDesc.Format = MeshIdFormat; - TexDesc.BindFlags = BIND_RENDER_TARGET | BIND_SHADER_RESOURCE; - m_MeshIdTexture = m_Device.CreateTexture(TexDesc); - - TexDesc.Name = "Depth buffer"; - TexDesc.Format = DepthFormat; - TexDesc.BindFlags = BIND_DEPTH_STENCIL; - m_DepthBufferDSV = m_Device.CreateTexture(TexDesc)->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL); - } -} - -void HnRendererImpl::PreparePostProcess(TEXTURE_FORMAT RTVFmt) -{ - if (m_PostProcess.PSO) - { - if (m_PostProcess.PSO->GetGraphicsPipelineDesc().RTVFormats[0] != RTVFmt) - m_PostProcess.PSO.Release(); - } - - if (!m_PostProcess.PSO) - { - ShaderCreateInfo ShaderCI; - ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; - ShaderCI.pShaderSourceStreamFactory = &HnShaderSourceFactory::GetInstance(); - - ShaderMacroHelper Macros; - Macros.Add("CONVERT_OUTPUT_TO_SRGB", m_ConvertOutputToSRGB); - ShaderCI.Macros = Macros; - - RefCntAutoPtr pVS; - { - ShaderCI.Desc = {"Post process VS", SHADER_TYPE_VERTEX, true}; - ShaderCI.EntryPoint = "main"; - ShaderCI.FilePath = "HnPostProcess.vsh"; - - pVS = m_Device.CreateShader(ShaderCI); - } - - RefCntAutoPtr pPS; - { - ShaderCI.Desc = {"Post process PS", SHADER_TYPE_PIXEL, true}; - ShaderCI.EntryPoint = "main"; - ShaderCI.FilePath = "HnPostProcess.psh"; - - pPS = m_Device.CreateShader(ShaderCI); - } - - PipelineResourceLayoutDescX ResourceLauout; - ResourceLauout - .AddVariable(SHADER_TYPE_PIXEL, "g_ColorBuffer", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) - .AddVariable(SHADER_TYPE_PIXEL, "g_MeshId", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC); - - GraphicsPipelineStateCreateInfoX PsoCI{"Post process"}; - PsoCI - .AddRenderTarget(RTVFmt) - .AddShader(pVS) - .AddShader(pPS) - .SetDepthStencilDesc(DSS_DisableDepth) - .SetRasterizerDesc(RS_SolidFillNoCull) - .SetResourceLayout(ResourceLauout) - .SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - - m_PostProcess.PSO = m_Device.CreateGraphicsPipelineState(PsoCI); - m_PostProcess.PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbPostProcessAttribs")->Set(m_PostProcessAttribsCB); - m_PostProcess.PSO->CreateShaderResourceBinding(&m_PostProcess.SRB, true); - } -} - void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs) { if (!m_RenderDelegate) @@ -256,47 +154,10 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs) VERIFY_EXPR(FinalColorTarget != nullptr); FinalColorTarget->SetTarget(Attribs.pDstRTV); - PrepareRenderTargets(Attribs.pDstRTV); - PreparePostProcess(Attribs.pDstRTV->GetDesc().Format); - - { - ITextureView* pRTVs[] = - { - m_ColorBuffer->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET), - m_MeshIdTexture->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET), - }; - pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, m_DepthBufferDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - constexpr float ClearColor[] = {0.35f, 0.35f, 0.35f, 0}; - pCtx->ClearRenderTarget(pRTVs[0], ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - constexpr float Zero[] = {0, 0, 0, 0}; - pCtx->ClearRenderTarget(pRTVs[1], Zero, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - pCtx->ClearDepthStencil(m_DepthBufferDSV, CLEAR_DEPTH_FLAG, 1.f, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - } - pxr::HdTaskSharedPtrVector tasks = m_TaskController->GetTasks(); m_Engine.Execute(&m_ImagingDelegate->GetRenderIndex(), &tasks); FinalColorTarget->ReleaseTarget(); - - PerformPostProcess(pCtx, Attribs); -} - -void HnRendererImpl::PerformPostProcess(IDeviceContext* pCtx, const HnDrawAttribs& Attribs) -{ - ITextureView* pRTVs[] = {Attribs.pDstRTV}; - pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - - { - MapHelper pDstShaderAttribs{pCtx, m_PostProcessAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD}; - pDstShaderAttribs->SelectionOutlineColor = Attribs.SlectionColor; - pDstShaderAttribs->NonselectionDesaturationFactor = Attribs.SelectedPrim != nullptr && !Attribs.SelectedPrim->IsEmpty() ? 0.5f : 0.f; - } - - pCtx->SetPipelineState(m_PostProcess.PSO); - m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_ColorBuffer")->Set(m_ColorBuffer->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)); - m_PostProcess.SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_MeshId")->Set(m_MeshIdTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)); - pCtx->CommitShaderResources(m_PostProcess.SRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); - pCtx->Draw({3, DRAW_FLAG_VERIFY_ALL}); } void HnRendererImpl::SetEnvironmentMap(IDeviceContext* pCtx, ITextureView* pEnvironmentMapSRV) @@ -306,6 +167,8 @@ void HnRendererImpl::SetEnvironmentMap(IDeviceContext* pCtx, ITextureView* pEnvi const pxr::SdfPath* HnRendererImpl::QueryPrimId(IDeviceContext* pCtx, Uint32 X, Uint32 Y) { + return nullptr; +#if 0 if (!m_MeshIdTexture) return nullptr; @@ -353,6 +216,7 @@ const pxr::SdfPath* HnRendererImpl::QueryPrimId(IDeviceContext* pCtx, Uint32 X, return nullptr; else return MeshUid != 0 ? m_RenderDelegate->GetMeshPrimId(MeshUid) : &EmptyPath; +#endif } } // namespace USD diff --git a/Hydrogent/src/Tasks/HnPostProcessTask.cpp b/Hydrogent/src/Tasks/HnPostProcessTask.cpp index 266a9fea..aba6bfaf 100644 --- a/Hydrogent/src/Tasks/HnPostProcessTask.cpp +++ b/Hydrogent/src/Tasks/HnPostProcessTask.cpp @@ -26,7 +26,17 @@ #include "Tasks/HnPostProcessTask.hpp" +#include "HnTokens.hpp" +#include "HnShaderSourceFactory.hpp" +#include "HnRenderDelegate.hpp" + #include "DebugUtilities.hpp" +#include "TextureView.h" +#include "RenderStateCache.hpp" +#include "ShaderMacroHelper.hpp" +#include "CommonlyUsedStates.h" +#include "GraphicsUtilities.h" +#include "MapHelper.hpp" namespace Diligent { @@ -34,6 +44,17 @@ namespace Diligent namespace USD { +namespace HLSL +{ + +namespace +{ +#include "Shaders/PBR/public/PBR_Structures.fxh" +#include "../shaders/HnPostProcessStructures.fxh" +} // namespace + +} // namespace HLSL + HnPostProcessTask::HnPostProcessTask(pxr::HdSceneDelegate* ParamsDelegate, const pxr::SdfPath& Id) : HnTask{Id} { @@ -43,6 +64,90 @@ HnPostProcessTask::~HnPostProcessTask() { } +void HnPostProcessTask::PreparePSO(TEXTURE_FORMAT RTVFormat) +{ + if (m_PSO) + { + if (m_PsoIsDirty || m_PSO->GetGraphicsPipelineDesc().RTVFormats[0] != RTVFormat) + { + m_PSO.Release(); + m_SRB.Release(); + } + } + + if (m_PSO) + return; + + HnRenderDelegate* RenderDelegate = static_cast(m_RenderIndex->GetRenderDelegate()); + + RenderDeviceWithCache_N Device{RenderDelegate->GetDevice(), RenderDelegate->GetRenderStateCache()}; + + ShaderCreateInfo ShaderCI; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + ShaderCI.pShaderSourceStreamFactory = &HnShaderSourceFactory::GetInstance(); + + ShaderMacroHelper Macros; + Macros.Add("CONVERT_OUTPUT_TO_SRGB", m_Params.ConvertOutputToSRGB); + ShaderCI.Macros = Macros; + + RefCntAutoPtr pVS; + { + ShaderCI.Desc = {"Post process VS", SHADER_TYPE_VERTEX, true}; + ShaderCI.EntryPoint = "main"; + ShaderCI.FilePath = "HnPostProcess.vsh"; + + pVS = Device.CreateShader(ShaderCI); + if (!pVS) + { + UNEXPECTED("Failed to create post process VS"); + return; + } + } + + RefCntAutoPtr pPS; + { + ShaderCI.Desc = {"Post process PS", SHADER_TYPE_PIXEL, true}; + ShaderCI.EntryPoint = "main"; + ShaderCI.FilePath = "HnPostProcess.psh"; + + pPS = Device.CreateShader(ShaderCI); + if (!pPS) + { + UNEXPECTED("Failed to create post process PS"); + return; + } + } + + PipelineResourceLayoutDescX ResourceLauout; + ResourceLauout + .AddVariable(SHADER_TYPE_PIXEL, "g_ColorBuffer", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) + .AddVariable(SHADER_TYPE_PIXEL, "g_MeshId", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC); + + GraphicsPipelineStateCreateInfoX PsoCI{"Post process"}; + PsoCI + .AddRenderTarget(RTVFormat) + .AddShader(pVS) + .AddShader(pPS) + .SetDepthStencilDesc(DSS_DisableDepth) + .SetRasterizerDesc(RS_SolidFillNoCull) + .SetResourceLayout(ResourceLauout) + .SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + + m_PSO = Device.CreateGraphicsPipelineState(PsoCI); + if (!m_PSO) + { + UNEXPECTED("Failed to create post process PSO"); + return; + } + m_PSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "cbPostProcessAttribs")->Set(m_PostProcessAttribsCB); + + m_SRB.Release(); + m_PSO->CreateShaderResourceBinding(&m_SRB, true); + VERIFY_EXPR(m_SRB); + + m_PsoIsDirty = false; +} + void HnPostProcessTask::Sync(pxr::HdSceneDelegate* Delegate, pxr::HdTaskContext* TaskCtx, pxr::HdDirtyBits* DirtyBits) @@ -53,7 +158,14 @@ void HnPostProcessTask::Sync(pxr::HdSceneDelegate* Delegate, if (ParamsValue.IsHolding()) { HnPostProcessTaskParams Params = ParamsValue.UncheckedGet(); - (void)Params; + + if (m_Params.ConvertOutputToSRGB != Params.ConvertOutputToSRGB) + { + // In OpenGL we can't release PSO in Worker thread + m_PsoIsDirty = true; + } + + m_Params = Params; } else { @@ -67,10 +179,80 @@ void HnPostProcessTask::Sync(pxr::HdSceneDelegate* Delegate, void HnPostProcessTask::Prepare(pxr::HdTaskContext* TaskCtx, pxr::HdRenderIndex* RenderIndex) { + m_RenderIndex = RenderIndex; + + ITextureView* pFinalColorRTV = GetRenderBufferTarget(*RenderIndex, TaskCtx, HnRenderResourceTokens->finalColorTarget); + if (pFinalColorRTV == nullptr) + { + UNEXPECTED("Final color target RTV is not set in the task context"); + return; + } + + if (!m_PostProcessAttribsCB) + { + HnRenderDelegate* RenderDelegate = static_cast(m_RenderIndex->GetRenderDelegate()); + CreateUniformBuffer(RenderDelegate->GetDevice(), sizeof(HLSL::PostProcessAttribs), "Post process attribs CB", &m_PostProcessAttribsCB); + VERIFY(m_PostProcessAttribsCB, "Failed to create post process attribs CB"); + } + + PreparePSO(pFinalColorRTV->GetDesc().Format); } void HnPostProcessTask::Execute(pxr::HdTaskContext* TaskCtx) { + if (m_RenderIndex == nullptr) + { + UNEXPECTED("Render index is null. This likely indicates that Prepare() has not been called."); + return; + } + ITextureView* pFinalColorRTV = GetRenderBufferTarget(*m_RenderIndex, TaskCtx, HnRenderResourceTokens->finalColorTarget); + if (pFinalColorRTV == nullptr) + { + UNEXPECTED("Final color target RTV is not set in the task context"); + return; + } + ITextureView* pOffscreenColorRTV = GetRenderBufferTarget(*m_RenderIndex, TaskCtx, HnRenderResourceTokens->offscreenColorTarget); + if (pOffscreenColorRTV == nullptr) + { + UNEXPECTED("Offscreen color RTV is not set in the task context"); + return; + } + ITextureView* pMeshIdRTV = GetRenderBufferTarget(*m_RenderIndex, TaskCtx, HnRenderResourceTokens->meshIdTarget); + if (pMeshIdRTV == nullptr) + { + UNEXPECTED("Mesh Id RTV is not set in the task context"); + return; + } + ITextureView* pOffscreenColorSRV = pOffscreenColorRTV->GetTexture()->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + if (pOffscreenColorSRV == nullptr) + { + UNEXPECTED("Offscreen color SRV is null"); + return; + } + ITextureView* pMeshIdSRV = pMeshIdRTV->GetTexture()->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE); + if (pMeshIdSRV == nullptr) + { + UNEXPECTED("Mesh Id SRV is null"); + return; + } + + HnRenderDelegate* RenderDelegate = static_cast(m_RenderIndex->GetRenderDelegate()); + IDeviceContext* pCtx = RenderDelegate->GetDeviceContext(); + + ITextureView* pRTVs[] = {pFinalColorRTV}; + pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + + { + MapHelper pDstShaderAttribs{pCtx, m_PostProcessAttribsCB, MAP_WRITE, MAP_FLAG_DISCARD}; + pDstShaderAttribs->SelectionOutlineColor = m_Params.SelectionColor; + pDstShaderAttribs->NonselectionDesaturationFactor = 0; //Attribs.SelectedPrim != nullptr && !Attribs.SelectedPrim->IsEmpty() ? 0.5f : 0.f; + } + + pCtx->SetPipelineState(m_PSO); + m_SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_ColorBuffer")->Set(pOffscreenColorSRV); + m_SRB->GetVariableByName(SHADER_TYPE_PIXEL, "g_MeshId")->Set(pMeshIdSRV); + pCtx->CommitShaderResources(m_SRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtx->Draw({3, DRAW_FLAG_VERIFY_ALL}); } } // namespace USD diff --git a/Hydrogent/src/Tasks/HnSetupRenderingTask.cpp b/Hydrogent/src/Tasks/HnSetupRenderingTask.cpp index b4d43570..bbaa579e 100644 --- a/Hydrogent/src/Tasks/HnSetupRenderingTask.cpp +++ b/Hydrogent/src/Tasks/HnSetupRenderingTask.cpp @@ -103,6 +103,9 @@ void HnSetupRenderingTask::Sync(pxr::HdSceneDelegate* Delegate, HnSetupRenderingTaskParams Params = ParamsValue.UncheckedGet(); m_FinalColorTargetId = Params.FinalColorTargetId; + m_ClearColor = Params.ClearColor; + m_ClearDepth = Params.ClearDepth; + UpdateRenderPassState(Params); } else @@ -126,15 +129,15 @@ void HnSetupRenderingTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex, const auto& FinalRTVDesc = pFinalColorRTV->GetDesc(); const auto& FinalTargetDesc = pFinalColorRTV->GetTexture()->GetDesc(); - auto UpdateBrim = [&](const pxr::SdfPath& Id, TEXTURE_FORMAT Format, const char* Name) { + auto UpdateBrim = [&](const pxr::SdfPath& Id, TEXTURE_FORMAT Format, const char* Name) -> ITextureView* { if (Format == TEX_FORMAT_UNKNOWN) - return; + return nullptr; HnRenderBuffer* Renderbuffer = static_cast(RenderIndex->GetBprim(pxr::HdPrimTypeTokens->renderBuffer, Id)); if (Renderbuffer == nullptr) { UNEXPECTED("Render buffer is not set at Id ", Id); - return; + return nullptr; } if (auto* pView = Renderbuffer->GetTarget()) @@ -144,7 +147,7 @@ void HnSetupRenderingTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex, if (TargetDesc.GetWidth() == FinalTargetDesc.GetWidth() && TargetDesc.GetHeight() == FinalTargetDesc.GetHeight() && ViewDesc.Format == Format) - return; + return pView; } const bool IsDepth = GetTextureFormatAttribs(Format).IsDepthStencil(); @@ -160,7 +163,7 @@ void HnSetupRenderingTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex, if (!pTarget) { UNEXPECTED("Failed to create ", Name, " texture"); - return; + return nullptr; } LOG_INFO_MESSAGE("HnSetupRenderingTask: created ", TargetDesc.GetWidth(), "x", TargetDesc.GetHeight(), " ", Name, " texture"); @@ -168,39 +171,51 @@ void HnSetupRenderingTask::PrepareRenderTargets(pxr::HdRenderIndex* RenderIndex, VERIFY(pView != nullptr, "Failed to get texture view for target ", Name); Renderbuffer->SetTarget(pView); + + return pView; }; - UpdateBrim(m_OffscreenColorTargetId, m_RenderPassState->GetRenderTargetFormat(0), "Offscreen color target"); - UpdateBrim(m_MeshIdTargetId, m_RenderPassState->GetRenderTargetFormat(1), "Mesh Id target"); - UpdateBrim(m_DepthBufferId, m_RenderPassState->GetDepthStencilFormat(), "Depth buffer"); + m_pFinalColorRTV = UpdateBrim(m_OffscreenColorTargetId, m_RenderPassState->GetRenderTargetFormat(0), "Offscreen color target"); + m_pMeshIdRTV = UpdateBrim(m_MeshIdTargetId, m_RenderPassState->GetRenderTargetFormat(1), "Mesh Id target"); + m_pDepthDSV = UpdateBrim(m_DepthBufferId, m_RenderPassState->GetDepthStencilFormat(), "Depth buffer"); } void HnSetupRenderingTask::Prepare(pxr::HdTaskContext* TaskCtx, pxr::HdRenderIndex* RenderIndex) { (*TaskCtx)[HnTokens->renderPassState] = pxr::VtValue{m_RenderPassState}; + (*TaskCtx)[HnRenderResourceTokens->finalColorTarget] = pxr::VtValue{m_FinalColorTargetId}; (*TaskCtx)[HnRenderResourceTokens->offscreenColorTarget] = pxr::VtValue{m_OffscreenColorTargetId}; (*TaskCtx)[HnRenderResourceTokens->meshIdTarget] = pxr::VtValue{m_MeshIdTargetId}; - HnRenderBuffer* FinalColorTarget = static_cast(RenderIndex->GetBprim(pxr::HdPrimTypeTokens->renderBuffer, m_FinalColorTargetId)); - if (FinalColorTarget != nullptr) + if (ITextureView* pFinalColorRTV = GetRenderBufferTarget(*RenderIndex, m_FinalColorTargetId)) { - if (auto* pRTV = FinalColorTarget->GetTarget()) - { - PrepareRenderTargets(RenderIndex, TaskCtx, pRTV); - } - else - { - UNEXPECTED("Final color target is not initialized in Bprim ", m_FinalColorTargetId); - } + PrepareRenderTargets(RenderIndex, TaskCtx, pFinalColorRTV); } else { - UNEXPECTED("Final color target Bprim is not set at Id ", m_FinalColorTargetId); + UNEXPECTED("Unable to get final color target from Bprim ", m_FinalColorTargetId); } + + m_RenderIndex = RenderIndex; } void HnSetupRenderingTask::Execute(pxr::HdTaskContext* TaskCtx) { + if (m_RenderIndex == nullptr) + { + UNEXPECTED("Render index is null. This likely indicates that Prepare() has not been called."); + return; + } + + ITextureView* pRTVs[] = {m_pFinalColorRTV, m_pMeshIdRTV}; + + auto* pCtx = static_cast(m_RenderIndex->GetRenderDelegate())->GetDeviceContext(); + + pCtx->SetRenderTargets(_countof(pRTVs), pRTVs, m_pDepthDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtx->ClearRenderTarget(pRTVs[0], m_ClearColor.Data(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + constexpr float Zero[] = {0, 0, 0, 0}; + pCtx->ClearRenderTarget(pRTVs[1], Zero, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtx->ClearDepthStencil(m_pDepthDSV, CLEAR_DEPTH_FLAG, m_ClearDepth, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); } } // namespace USD diff --git a/Hydrogent/src/Tasks/HnTask.cpp b/Hydrogent/src/Tasks/HnTask.cpp index c517614b..0c56d181 100644 --- a/Hydrogent/src/Tasks/HnTask.cpp +++ b/Hydrogent/src/Tasks/HnTask.cpp @@ -26,6 +26,7 @@ #include "Tasks/HnTask.hpp" #include "HnTokens.hpp" +#include "HnRenderBuffer.hpp" namespace Diligent { @@ -45,6 +46,36 @@ std::shared_ptr HnTask::GetRenderPassState(pxr::HdTaskContext return RenderPassState; } +ITextureView* HnTask::GetRenderBufferTarget(pxr::HdRenderIndex& RenderIndex, const pxr::SdfPath& RenderBufferId) +{ + HnRenderBuffer* RenderBuffer = static_cast(RenderIndex.GetBprim(pxr::HdPrimTypeTokens->renderBuffer, RenderBufferId)); + if (RenderBuffer == nullptr) + { + UNEXPECTED("Render buffer Bprim is not set at Id ", RenderBufferId); + return nullptr; + } + + return RenderBuffer->GetTarget(); +} + +ITextureView* HnTask::GetRenderBufferTarget(pxr::HdRenderIndex& RenderIndex, pxr::HdTaskContext* TaskCtx, const pxr::TfToken& Name) const +{ + auto id_it = TaskCtx->find(Name); + if (id_it == TaskCtx->end()) + { + UNEXPECTED("Render buffer Name '", Name, "' is not set in the task context"); + return nullptr; + } + + if (!id_it->second.IsHolding()) + { + UNEXPECTED("Render buffer VtValue '", Name, "' is not holding SdfPath"); + return nullptr; + } + + return GetRenderBufferTarget(RenderIndex, id_it->second.Get()); +} + } // namespace USD } // namespace Diligent