181 lines
6.6 KiB
C++
181 lines
6.6 KiB
C++
#pragma once
|
|
|
|
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
|
#include <XCEngine/Core/Math/Matrix4.h>
|
|
#include <XCEngine/Rendering/BuiltinPassContract.h>
|
|
#include <XCEngine/Rendering/RenderPass.h>
|
|
#include <XCEngine/Rendering/RenderMaterialStateUtils.h>
|
|
#include <XCEngine/Rendering/RenderResourceCache.h>
|
|
#include <XCEngine/RHI/RHIDescriptorPool.h>
|
|
#include <XCEngine/RHI/RHIDescriptorSet.h>
|
|
#include <XCEngine/RHI/RHIPipelineLayout.h>
|
|
#include <XCEngine/RHI/RHIPipelineState.h>
|
|
#include <XCEngine/Resources/Shader/Shader.h>
|
|
|
|
#include <unordered_map>
|
|
|
|
namespace XCEngine {
|
|
namespace Resources {
|
|
class Material;
|
|
class Shader;
|
|
} // namespace Resources
|
|
|
|
namespace Rendering {
|
|
struct VisibleRenderItem;
|
|
|
|
namespace Passes {
|
|
|
|
class BuiltinDepthStylePassBase : public RenderPass {
|
|
public:
|
|
~BuiltinDepthStylePassBase() override;
|
|
|
|
static RHI::InputLayoutDesc BuildCommonInputLayout();
|
|
|
|
bool Initialize(const RenderContext& context) override;
|
|
void Shutdown() override;
|
|
bool Execute(const RenderPassContext& context) override;
|
|
|
|
protected:
|
|
BuiltinDepthStylePassBase(
|
|
BuiltinMaterialPass passType,
|
|
Containers::String builtinShaderPath);
|
|
|
|
virtual bool ShouldRenderVisibleItem(const VisibleRenderItem& visibleItem) const;
|
|
|
|
private:
|
|
struct PerObjectConstants {
|
|
Math::Matrix4x4 projection = Math::Matrix4x4::Identity();
|
|
Math::Matrix4x4 view = Math::Matrix4x4::Identity();
|
|
Math::Matrix4x4 model = Math::Matrix4x4::Identity();
|
|
};
|
|
|
|
struct OwnedDescriptorSet {
|
|
RHI::RHIDescriptorPool* pool = nullptr;
|
|
RHI::RHIDescriptorSet* set = nullptr;
|
|
};
|
|
|
|
struct PassLayoutKey {
|
|
const Resources::Shader* shader = nullptr;
|
|
Containers::String passName;
|
|
|
|
bool operator==(const PassLayoutKey& other) const {
|
|
return shader == other.shader && passName == other.passName;
|
|
}
|
|
};
|
|
|
|
struct PassLayoutKeyHash {
|
|
size_t operator()(const PassLayoutKey& key) const noexcept {
|
|
size_t hash = reinterpret_cast<size_t>(key.shader);
|
|
hash ^= std::hash<Containers::String>{}(key.passName) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
return hash;
|
|
}
|
|
};
|
|
|
|
struct PassResourceLayout {
|
|
RHI::RHIPipelineLayout* pipelineLayout = nullptr;
|
|
PassResourceBindingLocation perObject = {};
|
|
BuiltinPassSetLayoutMetadata perObjectSetLayout = {};
|
|
Core::uint32 firstDescriptorSet = 0;
|
|
};
|
|
|
|
struct PerObjectSetKey {
|
|
PassLayoutKey passLayout = {};
|
|
Core::uint64 objectId = 0;
|
|
|
|
bool operator==(const PerObjectSetKey& other) const {
|
|
return passLayout == other.passLayout &&
|
|
objectId == other.objectId;
|
|
}
|
|
};
|
|
|
|
struct PerObjectSetKeyHash {
|
|
size_t operator()(const PerObjectSetKey& key) const noexcept {
|
|
size_t hash = PassLayoutKeyHash()(key.passLayout);
|
|
hash ^= std::hash<Core::uint64>{}(key.objectId) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
return hash;
|
|
}
|
|
};
|
|
|
|
struct ResolvedShaderPass {
|
|
const Resources::Shader* shader = nullptr;
|
|
const Resources::ShaderPass* pass = nullptr;
|
|
Containers::String passName;
|
|
};
|
|
|
|
struct PipelineStateKey {
|
|
Resources::MaterialRenderState renderState;
|
|
const Resources::Shader* shader = nullptr;
|
|
Containers::String passName;
|
|
uint32_t renderTargetCount = 0;
|
|
uint32_t renderTargetFormat = 0;
|
|
uint32_t depthStencilFormat = 0;
|
|
|
|
bool operator==(const PipelineStateKey& other) const {
|
|
return renderState == other.renderState &&
|
|
shader == other.shader &&
|
|
passName == other.passName &&
|
|
renderTargetCount == other.renderTargetCount &&
|
|
renderTargetFormat == other.renderTargetFormat &&
|
|
depthStencilFormat == other.depthStencilFormat;
|
|
}
|
|
};
|
|
|
|
struct PipelineStateKeyHash {
|
|
size_t operator()(const PipelineStateKey& key) const noexcept {
|
|
size_t hash = MaterialRenderStateHash()(key.renderState);
|
|
hash ^= reinterpret_cast<size_t>(key.shader) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
hash ^= std::hash<Containers::String>{}(key.passName) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
hash ^= std::hash<uint32_t>{}(key.renderTargetCount) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
hash ^= std::hash<uint32_t>{}(key.renderTargetFormat) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
hash ^= std::hash<uint32_t>{}(key.depthStencilFormat) + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
|
return hash;
|
|
}
|
|
};
|
|
|
|
bool EnsureInitialized(const RenderContext& context);
|
|
bool CreateResources(const RenderContext& context);
|
|
void DestroyResources();
|
|
|
|
ResolvedShaderPass ResolveSurfaceShaderPass(const Resources::Material* material) const;
|
|
bool TryBuildSupportedBindingPlan(
|
|
const Resources::ShaderPass& shaderPass,
|
|
BuiltinPassResourceBindingPlan& outPlan,
|
|
Containers::String* outError = nullptr) const;
|
|
PassResourceLayout* GetOrCreatePassResourceLayout(
|
|
const RenderContext& context,
|
|
const ResolvedShaderPass& resolvedShaderPass);
|
|
RHI::RHIPipelineState* GetOrCreatePipelineState(
|
|
const RenderContext& context,
|
|
const RenderSurface& surface,
|
|
const Resources::Material* material);
|
|
bool CreateOwnedDescriptorSet(
|
|
const BuiltinPassSetLayoutMetadata& setLayout,
|
|
OwnedDescriptorSet& descriptorSet);
|
|
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(
|
|
const PassLayoutKey& passLayoutKey,
|
|
const PassResourceLayout& passLayout,
|
|
Core::uint64 objectId);
|
|
void DestroyOwnedDescriptorSet(OwnedDescriptorSet& descriptorSet);
|
|
void DestroyPassResourceLayout(PassResourceLayout& passLayout);
|
|
bool DrawVisibleItem(
|
|
const RenderContext& context,
|
|
const RenderSurface& surface,
|
|
const RenderSceneData& sceneData,
|
|
const VisibleRenderItem& visibleItem);
|
|
|
|
RHI::RHIDevice* m_device = nullptr;
|
|
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
|
BuiltinMaterialPass m_passType = BuiltinMaterialPass::DepthOnly;
|
|
Containers::String m_builtinShaderPath;
|
|
Resources::ResourceHandle<Resources::Shader> m_builtinShader;
|
|
RenderResourceCache m_resourceCache;
|
|
|
|
std::unordered_map<PassLayoutKey, PassResourceLayout, PassLayoutKeyHash> m_passResourceLayouts;
|
|
std::unordered_map<PipelineStateKey, RHI::RHIPipelineState*, PipelineStateKeyHash> m_pipelineStates;
|
|
std::unordered_map<PerObjectSetKey, OwnedDescriptorSet, PerObjectSetKeyHash> m_perObjectSets;
|
|
};
|
|
|
|
} // namespace Passes
|
|
} // namespace Rendering
|
|
} // namespace XCEngine
|