Skip to content

Commit

Permalink
Refactoring PBR renderer to make it more flexible
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 6, 2023
1 parent 02cccd2 commit 53c53ef
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 306 deletions.
4 changes: 3 additions & 1 deletion Hydrogent/include/HnRendererImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "BasicMath.hpp"
#include "ObjectBase.hpp"
#include "GPUCompletionAwaitQueue.hpp"
#include "USD_Renderer.hpp"

#include "pxr/usd/usd/stage.h"
#include "pxr/imaging/hd/tokens.h"
Expand All @@ -47,7 +48,6 @@
namespace Diligent
{

class USD_Renderer;
class EnvMapRenderer;

namespace USD
Expand Down Expand Up @@ -109,6 +109,8 @@ class HnRendererImpl final : public ObjectBase<IHnRenderer>
RefCntAutoPtr<ITexture> m_DepthBuffer;

GPUCompletionAwaitQueue<RefCntAutoPtr<ITexture>> m_MeshIdReadBackQueue;

PBR_Renderer::PSO_FLAGS m_PSOFlags = PBR_Renderer::PSO_FLAG_NONE;
};

} // namespace USD
Expand Down
25 changes: 21 additions & 4 deletions Hydrogent/src/HnRendererImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ HnRendererImpl::HnRendererImpl(IReferenceCounters* pRefCounters,
}(CI, pDevice))},
m_MeshIdReadBackQueue{pDevice}
{
m_PSOFlags |=
PBR_Renderer::PSO_FLAG_USE_VERTEX_NORMALS |
PBR_Renderer::PSO_FLAG_USE_TEXCOORD0 |
PBR_Renderer::PSO_FLAG_USE_TEXCOORD1 |
PBR_Renderer::PSO_FLAG_USE_DIFFUSE_MAP |
PBR_Renderer::PSO_FLAG_USE_NORMAL_MAP |
PBR_Renderer::PSO_FLAG_USE_METALLIC_MAP |
PBR_Renderer::PSO_FLAG_USE_ROUGHNESS_MAP;

m_PSOFlags |=
PBR_Renderer::PSO_FLAG_USE_AO_MAP |
PBR_Renderer::PSO_FLAG_USE_EMISSIVE_MAP |
PBR_Renderer::PSO_FLAG_USE_IBL |
PBR_Renderer::PSO_FLAG_ALLOW_DEBUG_VIEW;

if (CI.ConvertOutputToSRGB)
m_PSOFlags |= PBR_Renderer::PSO_FLAG_CONVERT_TO_SRGB;
}

HnRendererImpl::~HnRendererImpl()
Expand Down Expand Up @@ -228,9 +245,9 @@ void HnRendererImpl::Draw(IDeviceContext* pCtx, const HnDrawAttribs& Attribs)
for (auto AlphaMode : {USD_Renderer::ALPHA_MODE_OPAQUE, USD_Renderer::ALPHA_MODE_MASK, USD_Renderer::ALPHA_MODE_BLEND})
{
if (Attribs.RenderMode == HN_RENDER_MODE_MESH_EDGES)
pCtx->SetPipelineState(m_USDRenderer->GetMeshEdgesPSO());
pCtx->SetPipelineState(m_USDRenderer->GetMeshEdgesPSO({m_PSOFlags, USD_Renderer::ALPHA_MODE_OPAQUE, /*DoubleSided = */ false}, true));
else
pCtx->SetPipelineState(m_USDRenderer->GetPSO({AlphaMode, /*DoubleSided = */ false}));
pCtx->SetPipelineState(m_USDRenderer->GetPSO({m_PSOFlags, AlphaMode, /*DoubleSided = */ false}, true));

for (auto mesh_it : Meshes)
{
Expand Down Expand Up @@ -335,7 +352,7 @@ void HnRendererImpl::RenderMesh(IDeviceContext* pCtx, const HnMesh& Mesh, const

void HnRendererImpl::SetEnvironmentMap(IDeviceContext* pCtx, ITextureView* pEnvironmentMapSRV)
{
m_USDRenderer->PrecomputeCubemaps(m_Device, m_Device, pCtx, pEnvironmentMapSRV);
m_USDRenderer->PrecomputeCubemaps(pCtx, pEnvironmentMapSRV);
}

const char* HnRendererImpl::QueryPrimId(IDeviceContext* pCtx, Uint32 X, Uint32 Y)
Expand Down Expand Up @@ -437,7 +454,7 @@ void HnRendererImpl::RenderPrimId(IDeviceContext* pContext, ITextureView* pDepth
if (Meshes.empty())
return;

auto* pMeshIdPSO = m_USDRenderer->GetMeshIdPSO(false);
auto* pMeshIdPSO = m_USDRenderer->GetMeshIdPSO({m_PSOFlags, USD_Renderer::ALPHA_MODE_OPAQUE, /*DoubleSided = */ false}, true);
if (pMeshIdPSO == nullptr)
return;

Expand Down
8 changes: 3 additions & 5 deletions PBR/interface/GLTF_PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,13 @@ class GLTF_PBR_Renderer : public PBR_Renderer
/// \param [in] CacheUseInfo - GLTF resource cache usage information.
/// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
/// \param [in] pLightAttribs - Light attributes constant buffer to set in the SRB.
/// \param [in] pPSO - Optional PSO object to use to create the SRB instead of the
/// default PSO. Can be null
/// \param [out] ppCacheSRB - Pointer to memory location where the pointer to the SRB object
/// will be written.
void CreateResourceCacheSRB(IRenderDevice* pDevice,
IDeviceContext* pCtx,
ResourceCacheUseInfo& CacheUseInfo,
IBuffer* pCameraAttribs,
IBuffer* pLightAttribs,
IPipelineState* pPSO,
IShaderResourceBinding** ppCacheSRB);

/// Prepares the renderer for rendering objects.
Expand All @@ -217,13 +214,14 @@ class GLTF_PBR_Renderer : public PBR_Renderer
ResourceCacheUseInfo& CacheUseInfo,
ResourceCacheBindings& Bindings,
IBuffer* pCameraAttribs,
IBuffer* pLightAttribs,
IPipelineState* pPSO = nullptr);
IBuffer* pLightAttribs);

private:
static ALPHA_MODE GltfAlphaModeToAlphaMode(GLTF::Material::ALPHA_MODE GltfAlphaMode);

RenderInfo m_RenderParams;

PSO_FLAGS m_PSOFlags = PSO_FLAG_NONE;
};

DEFINE_FLAG_ENUM_OPERATORS(GLTF_PBR_Renderer::RenderInfo::ALPHA_MODE_FLAGS)
Expand Down
107 changes: 64 additions & 43 deletions PBR/interface/PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@

#pragma once

#include <vector>
#include <array>
#include <unordered_map>
#include <functional>

#include "../../../DiligentCore/Platforms/Basic/interface/DebugUtilities.hpp"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/GraphicsTypesX.hpp"
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/RenderStateCache.h"
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/RenderStateCache.hpp"
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/ShaderMacroHelper.hpp"
#include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
#include "../../../DiligentCore/Common/interface/HashUtils.hpp"

namespace Diligent
{
Expand Down Expand Up @@ -198,80 +199,97 @@ class PBR_Renderer
// clang-format on

/// Precompute cubemaps used by IBL.
void PrecomputeCubemaps(IRenderDevice* pDevice,
IRenderStateCache* pStateCache,
IDeviceContext* pCtx,
ITextureView* pEnvironmentMap,
Uint32 NumPhiSamples = 64,
Uint32 NumThetaSamples = 32,
bool OptimizeSamples = true);
void PrecomputeCubemaps(IDeviceContext* pCtx,
ITextureView* pEnvironmentMap,
Uint32 NumPhiSamples = 64,
Uint32 NumThetaSamples = 32,
bool OptimizeSamples = true);

void CreateResourceBinding(IShaderResourceBinding** ppSRB);

enum PSO_FLAGS : Uint32
{
PSO_FLAG_NONE = 0u,
PSO_FLAG_USE_VERTEX_COLORS = 1u << 0u,
PSO_FLAG_USE_VERTEX_NORMALS = 1u << 1u,
PSO_FLAG_USE_TEXCOORD0 = 1u << 2u,
PSO_FLAG_USE_TEXCOORD1 = 1u << 3u,
PSO_FLAG_USE_JOINTS = 1u << 4u,

PSO_FLAG_USE_DIFFUSE_MAP = 1u << 5u,
PSO_FLAG_USE_NORMAL_MAP = 1u << 6u,
PSO_FLAG_USE_METALLIC_MAP = 1u << 7u,
PSO_FLAG_USE_ROUGHNESS_MAP = 1u << 8u,
PSO_FLAG_USE_PHYS_DESC_MAP = 1u << 9u,
PSO_FLAG_USE_AO_MAP = 1u << 10u,
PSO_FLAG_USE_EMISSIVE_MAP = 1u << 11u,
PSO_FLAG_USE_IBL = 1u << 12u,

PSO_FLAG_FRONT_CCW = 1u << 13u,
PSO_FLAG_ALLOW_DEBUG_VIEW = 1u << 14u,
PSO_FLAG_USE_TEXTURE_ATLAS = 1u << 15u,
PSO_FLAG_CONVERT_TO_SRGB = 1u << 16u,
};

struct PSOKey
{
PSOKey() noexcept {};
PSOKey(ALPHA_MODE _AlphaMode, bool _DoubleSided) :
PSOKey(PSO_FLAGS _Flags, ALPHA_MODE _AlphaMode, bool _DoubleSided) noexcept :
Flags{_Flags},
AlphaMode{_AlphaMode},
DoubleSided{_DoubleSided}
{}

bool operator==(const PSOKey& rhs) const noexcept
{
return AlphaMode == rhs.AlphaMode && DoubleSided == rhs.DoubleSided;
return Flags == rhs.Flags && AlphaMode == rhs.AlphaMode && DoubleSided == rhs.DoubleSided;
}
bool operator!=(const PSOKey& rhs) const noexcept
{
return AlphaMode != rhs.AlphaMode || DoubleSided != rhs.DoubleSided;
return Flags != rhs.Flags || AlphaMode != rhs.AlphaMode || DoubleSided != rhs.DoubleSided;
}

PSO_FLAGS Flags = PSO_FLAG_NONE;
ALPHA_MODE AlphaMode = ALPHA_MODE_OPAQUE;
bool DoubleSided = false;
};

IPipelineState* GetPSO(const PSOKey& Key) const
{
auto Idx = GetPSOIdx(Key);
VERIFY_EXPR(Idx < m_PSOCache.size());
return Idx < m_PSOCache.size() ? m_PSOCache[Idx].RawPtr() : nullptr;
}
struct Hasher
{
size_t operator()(const PSOKey& Key) const noexcept
{
return ComputeHash(Key.Flags, Key.AlphaMode, Key.DoubleSided);
}
};
};

IPipelineState* GetMeshIdPSO(bool DoubleSided) const
{
return m_MeshIdPSO[DoubleSided ? 1 : 0];
}
IPipelineState* GetPSO(const PSOKey& Key, bool CreateIfNull);
IPipelineState* GetMeshIdPSO(const PSOKey& Key, bool CreateIfNull);

void InitCommonSRBVars(IShaderResourceBinding* pSRB,
IBuffer* pCameraAttribs,
IBuffer* pLightAttribs);

protected:
ShaderMacroHelper DefineMacros() const;
InputLayoutDescX GetInputLayout() const;
ShaderMacroHelper DefineMacros(PSO_FLAGS PSOFlags) const;

static size_t GetPSOIdx(const PSOKey& Key)
{
size_t PSOIdx;
void GetVSInputStructAndLayout(PSO_FLAGS PSOFlags, std::string& VSInputStruct, InputLayoutDescX& InputLayout) const;

PSOIdx = Key.AlphaMode == ALPHA_MODE_BLEND ? 1 : 0;
PSOIdx = PSOIdx * 2 + (Key.DoubleSided ? 1 : 0);
return PSOIdx;
}
using PSOCacheType = std::unordered_map<PSOKey, RefCntAutoPtr<IPipelineState>, PSOKey::Hasher>;

void AddPSO(const PSOKey& Key, RefCntAutoPtr<IPipelineState> pPSO);
static IPipelineState* GetPSO(PSOCacheType& PSOCache, const PSOKey& Key, std::function<void()> CreatePSO);

private:
void PrecomputeBRDF(IRenderDevice* pDevice,
IRenderStateCache* pStateCache,
IDeviceContext* pCtx,
Uint32 NumBRDFSamples = 512);
void PrecomputeBRDF(IDeviceContext* pCtx,
Uint32 NumBRDFSamples = 512);

void CreatePSO(IRenderDevice* pDevice, IRenderStateCache* pStateCache);
void CreateSignature(IRenderDevice* pDevice, IRenderStateCache* pStateCache);
void CreatePSO(PSO_FLAGS PSOFlags, TEXTURE_FORMAT RTVFmt, TEXTURE_FORMAT DSVFmt);
void CreateSignature();

protected:
const CreateInfo m_Settings;

RenderDeviceWithCache_N m_Device;

static constexpr Uint32 BRDF_LUT_Dim = 512;
RefCntAutoPtr<ITextureView> m_pBRDF_LUT_SRV;

Expand All @@ -298,9 +316,12 @@ class PBR_Renderer
RefCntAutoPtr<IBuffer> m_PrecomputeEnvMapAttribsCB;
RefCntAutoPtr<IBuffer> m_JointsBuffer;

RefCntAutoPtr<IPipelineResourceSignature> m_ResourceSignature;
std::vector<RefCntAutoPtr<IPipelineState>> m_PSOCache;
std::array<RefCntAutoPtr<IPipelineState>, 2> m_MeshIdPSO;
RefCntAutoPtr<IPipelineResourceSignature> m_ResourceSignature;

PSOCacheType m_PSOs;
PSOCacheType m_MeshIdPSOs;
};

DEFINE_FLAG_ENUM_OPERATORS(PBR_Renderer::PSO_FLAGS)

} // namespace Diligent
6 changes: 3 additions & 3 deletions PBR/interface/USD_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ class USD_Renderer : public PBR_Renderer
IDeviceContext* pCtx,
const CreateInfo& CI);

IPipelineState* GetMeshEdgesPSO() const { return m_MeshEdgesPSO; }
IPipelineState* GetMeshEdgesPSO(const PSOKey& Key, bool CreateIfNull);

private:
void CreatMeshEdgesPSO(IRenderDevice* pDevice, IRenderStateCache* pStateCache);
void CreateMeshEdgesPSO(PSO_FLAGS PSOFlags, TEXTURE_FORMAT RTVFmt, TEXTURE_FORMAT DSVFmt);

private:
RefCntAutoPtr<IPipelineState> m_MeshEdgesPSO;
PSOCacheType m_MeshEdgesPSOs;
};

} // namespace Diligent
Loading

0 comments on commit 53c53ef

Please sign in to comment.