Skip to content

Commit

Permalink
PBR Renderer: reworked PSO keys
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Oct 8, 2023
1 parent 612a3d1 commit e72464b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 61 deletions.
122 changes: 70 additions & 52 deletions PBR/interface/PBR_Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,102 +237,103 @@ class PBR_Renderer
PSO_FLAG_ALL = PSO_FLAG_LAST * 2u - 1u,
};

struct PbrPSOKey
struct PSOKey
{
PSO_FLAGS Flags = PSO_FLAG_NONE;
ALPHA_MODE AlphaMode = ALPHA_MODE_OPAQUE;
bool DoubleSided = false;
PSO_FLAGS Flags = PSO_FLAG_NONE;
bool DoubleSided = false;

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

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

struct Hasher
{
size_t operator()(const PbrPSOKey& Key) const noexcept
size_t operator()(const PSOKey& Key) const noexcept
{
return ComputeHash(Key.Flags, Key.AlphaMode, Key.DoubleSided);
return ComputeHash(Key.Flags, Key.DoubleSided);
}
};
};
IPipelineState* GetPbrPSO(const PbrPSOKey& Key, bool CreateIfNull);


struct WireframePSOKey
struct PbrPSOKey : PSOKey
{
PSO_FLAGS Flags = PSO_FLAG_NONE;
PRIMITIVE_TOPOLOGY Topology = PRIMITIVE_TOPOLOGY_UNDEFINED;
bool DoubleSided = false;
static const PSO_FLAGS SupportedFlags;

WireframePSOKey() noexcept {};
WireframePSOKey(PSO_FLAGS _Flags, PRIMITIVE_TOPOLOGY _Topology, bool _DoubleSided) noexcept :
Flags{_Flags},
Topology{_Topology},
DoubleSided{_DoubleSided}
{}
ALPHA_MODE AlphaMode = ALPHA_MODE_OPAQUE;

bool operator==(const WireframePSOKey& rhs) const noexcept
PbrPSOKey() noexcept {};
PbrPSOKey(PSO_FLAGS _Flags, ALPHA_MODE _AlphaMode, bool _DoubleSided) noexcept;

bool operator==(const PbrPSOKey& rhs) const noexcept
{
return Flags == rhs.Flags && Topology == rhs.Topology && DoubleSided == rhs.DoubleSided;
return PSOKey::operator==(rhs) && AlphaMode == rhs.AlphaMode;
}

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

struct Hasher
{
size_t operator()(const WireframePSOKey& Key) const noexcept
size_t operator()(const PbrPSOKey& Key) const noexcept
{
return ComputeHash(Key.Flags, Key.Topology, Key.DoubleSided);
size_t Hash = PSOKey::Hasher{}(Key);
HashCombine(Hash, Key.AlphaMode);
return Hash;
}
};
};
IPipelineState* GetWireframePSO(const WireframePSOKey& Key, bool CreateIfNull);
IPipelineState* GetPbrPSO(const PbrPSOKey& Key, bool CreateIfNull);


struct MeshIdPSOKey
struct WireframePSOKey : PSOKey
{
PSO_FLAGS Flags = PSO_FLAG_NONE;
bool DoubleSided = false;
static const PSO_FLAGS SupportedFlags;

MeshIdPSOKey() noexcept {};
MeshIdPSOKey(PSO_FLAGS _Flags, bool _DoubleSided) noexcept :
Flags{_Flags},
DoubleSided{_DoubleSided}
{}
PRIMITIVE_TOPOLOGY Topology = PRIMITIVE_TOPOLOGY_UNDEFINED;

bool operator==(const MeshIdPSOKey& rhs) const noexcept
WireframePSOKey() noexcept {};
WireframePSOKey(PSO_FLAGS _Flags, PRIMITIVE_TOPOLOGY _Topology, bool _DoubleSided) noexcept;

bool operator==(const WireframePSOKey& rhs) const noexcept
{
return Flags == rhs.Flags && DoubleSided == rhs.DoubleSided;
return PSOKey::operator==(rhs) && Topology == rhs.Topology;
}

bool operator!=(const MeshIdPSOKey& rhs) const noexcept
bool operator!=(const WireframePSOKey& rhs) const noexcept
{
return Flags != rhs.Flags || DoubleSided != rhs.DoubleSided;
return PSOKey::operator!=(rhs) || Topology != rhs.Topology;
}

struct Hasher
{
size_t operator()(const MeshIdPSOKey& Key) const noexcept
size_t operator()(const WireframePSOKey& Key) const noexcept
{
return ComputeHash(Key.Flags, Key.DoubleSided);
size_t Hash = PSOKey::Hasher{}(Key);
HashCombine(Hash, Key.Topology);
return Hash;
}
};
};
IPipelineState* GetWireframePSO(const WireframePSOKey& Key, bool CreateIfNull);

struct MeshIdPSOKey : PSOKey
{
static const PSO_FLAGS SupportedFlags;

MeshIdPSOKey() noexcept {};
MeshIdPSOKey(PSO_FLAGS _Flags, bool _DoubleSided) noexcept;
};
IPipelineState* GetMeshIdPSO(const MeshIdPSOKey& Key, bool CreateIfNull);

void InitCommonSRBVars(IShaderResourceBinding* pSRB,
Expand All @@ -347,7 +348,6 @@ class PBR_Renderer
template <typename KeyType, class CreatePSOType>
IPipelineState* GetPSO(std::unordered_map<KeyType, RefCntAutoPtr<IPipelineState>, typename KeyType::Hasher>& PSOCache,
KeyType Key,
PSO_FLAGS SupportedFlags,
bool CreateIfNull,
CreatePSOType&& CreatePSO);

Expand Down Expand Up @@ -410,14 +410,32 @@ class PBR_Renderer

DEFINE_FLAG_ENUM_OPERATORS(PBR_Renderer::PSO_FLAGS)

inline PBR_Renderer::PbrPSOKey::PbrPSOKey(PSO_FLAGS _Flags,
ALPHA_MODE _AlphaMode,
bool _DoubleSided) noexcept :
PSOKey{_Flags & SupportedFlags, _DoubleSided},
AlphaMode{_AlphaMode}
{}

inline PBR_Renderer::WireframePSOKey::WireframePSOKey(PSO_FLAGS _Flags,
PRIMITIVE_TOPOLOGY _Topology,
bool _DoubleSided) noexcept :
PSOKey{_Flags & SupportedFlags, _DoubleSided},
Topology{_Topology}
{}

inline PBR_Renderer::MeshIdPSOKey::MeshIdPSOKey(PSO_FLAGS _Flags,
bool _DoubleSided) noexcept :
PSOKey{_Flags & SupportedFlags, _DoubleSided}
{}

template <typename KeyType, class CreatePSOType>
IPipelineState* PBR_Renderer::GetPSO(std::unordered_map<KeyType, RefCntAutoPtr<IPipelineState>, typename KeyType::Hasher>& PSOCache,
KeyType Key,
PSO_FLAGS SupportedFlags,
bool CreateIfNull,
CreatePSOType&& CreatePSO)
{
Key.Flags &= SupportedFlags;
Key.Flags &= KeyType::SupportedFlags;

if (!m_Settings.EnableIBL)
{
Expand Down
22 changes: 13 additions & 9 deletions PBR/src/PBR_Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ namespace Diligent

const SamplerDesc PBR_Renderer::CreateInfo::DefaultSampler = Sam_LinearWrap;

const PBR_Renderer::PSO_FLAGS PBR_Renderer::PbrPSOKey::SupportedFlags = PSO_FLAG_ALL;

const PBR_Renderer::PSO_FLAGS PBR_Renderer::WireframePSOKey::SupportedFlags =
PSO_FLAG_USE_JOINTS |
PSO_FLAG_FRONT_CCW;

const PBR_Renderer::PSO_FLAGS PBR_Renderer::MeshIdPSOKey::SupportedFlags =
PSO_FLAG_USE_JOINTS |
PSO_FLAG_FRONT_CCW;

namespace
{

Expand Down Expand Up @@ -963,23 +973,17 @@ void PBR_Renderer::CreateResourceBinding(IShaderResourceBinding** ppSRB)

IPipelineState* PBR_Renderer::GetPbrPSO(const PbrPSOKey& Key, bool CreateIfNull)
{
return GetPSO(m_PbrPSOs, Key, PSO_FLAG_ALL, CreateIfNull, std::mem_fn(&PBR_Renderer::CreatePbrPSO));
return GetPSO(m_PbrPSOs, Key, CreateIfNull, std::mem_fn(&PBR_Renderer::CreatePbrPSO));
}

IPipelineState* PBR_Renderer::GetMeshIdPSO(const MeshIdPSOKey& Key, bool CreateIfNull)
{
constexpr auto MeshIdPsoFlags =
PSO_FLAG_USE_JOINTS |
PSO_FLAG_FRONT_CCW;
return GetPSO(m_MeshIdPSOs, Key, MeshIdPsoFlags, CreateIfNull, std::mem_fn(&PBR_Renderer::CreateMeshIdPSO));
return GetPSO(m_MeshIdPSOs, Key, CreateIfNull, std::mem_fn(&PBR_Renderer::CreateMeshIdPSO));
}

IPipelineState* PBR_Renderer::GetWireframePSO(const WireframePSOKey& Key, bool CreateIfNull)
{
constexpr auto WireframePsoFlags =
PSO_FLAG_USE_JOINTS |
PSO_FLAG_FRONT_CCW;
return GetPSO(m_WireframePSOs, Key, WireframePsoFlags, CreateIfNull, std::mem_fn(&PBR_Renderer::CreateWireframePSO));
return GetPSO(m_WireframePSOs, Key, CreateIfNull, std::mem_fn(&PBR_Renderer::CreateWireframePSO));
}

} // namespace Diligent

0 comments on commit e72464b

Please sign in to comment.