refactor: drive builtin forward bindings from shader pass resources
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
@@ -71,9 +72,85 @@ private:
|
||||
Math::Vector4 baseColorFactor = Math::Vector4::One();
|
||||
};
|
||||
|
||||
struct CachedMaterialBindings {
|
||||
OwnedDescriptorSet constantSet = {};
|
||||
OwnedDescriptorSet textureSet = {};
|
||||
struct DescriptorBindingLocation {
|
||||
Core::uint32 set = UINT32_MAX;
|
||||
Core::uint32 binding = UINT32_MAX;
|
||||
|
||||
bool IsValid() const {
|
||||
return set != UINT32_MAX && binding != UINT32_MAX;
|
||||
}
|
||||
};
|
||||
|
||||
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 PassSetLayoutMetadata {
|
||||
std::vector<RHI::DescriptorSetLayoutBinding> bindings;
|
||||
RHI::DescriptorSetLayoutDesc layout = {};
|
||||
RHI::DescriptorHeapType heapType = RHI::DescriptorHeapType::CBV_SRV_UAV;
|
||||
bool shaderVisible = false;
|
||||
bool usesPerObject = false;
|
||||
bool usesMaterial = false;
|
||||
bool usesTexture = false;
|
||||
bool usesSampler = false;
|
||||
};
|
||||
|
||||
struct PassResourceLayout {
|
||||
RHI::RHIPipelineLayout* pipelineLayout = nullptr;
|
||||
Core::uint32 firstDescriptorSet = 0;
|
||||
Core::uint32 descriptorSetCount = 0;
|
||||
std::vector<PassSetLayoutMetadata> setLayouts;
|
||||
std::vector<OwnedDescriptorSet> staticDescriptorSets;
|
||||
DescriptorBindingLocation perObject = {};
|
||||
DescriptorBindingLocation material = {};
|
||||
DescriptorBindingLocation baseColorTexture = {};
|
||||
DescriptorBindingLocation linearClampSampler = {};
|
||||
};
|
||||
|
||||
struct DynamicDescriptorSetKey {
|
||||
PassLayoutKey passLayout = {};
|
||||
Core::uint32 setIndex = 0;
|
||||
Core::uint64 objectId = 0;
|
||||
const Resources::Material* material = nullptr;
|
||||
|
||||
bool operator==(const DynamicDescriptorSetKey& other) const {
|
||||
return passLayout == other.passLayout &&
|
||||
setIndex == other.setIndex &&
|
||||
objectId == other.objectId &&
|
||||
material == other.material;
|
||||
}
|
||||
};
|
||||
|
||||
struct DynamicDescriptorSetKeyHash {
|
||||
size_t operator()(const DynamicDescriptorSetKey& key) const noexcept {
|
||||
size_t hash = PassLayoutKeyHash()(key.passLayout);
|
||||
auto combine = [&hash](size_t value) {
|
||||
hash ^= value + 0x9e3779b9u + (hash << 6) + (hash >> 2);
|
||||
};
|
||||
|
||||
combine(std::hash<Core::uint32>{}(key.setIndex));
|
||||
combine(std::hash<Core::uint64>{}(key.objectId));
|
||||
combine(reinterpret_cast<size_t>(key.material));
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
struct CachedDescriptorSet {
|
||||
OwnedDescriptorSet descriptorSet = {};
|
||||
Core::uint64 materialVersion = 0;
|
||||
RHI::RHIResourceView* textureView = nullptr;
|
||||
};
|
||||
@@ -113,14 +190,29 @@ private:
|
||||
bool CreatePipelineResources(const RenderContext& context);
|
||||
void DestroyPipelineResources();
|
||||
ResolvedShaderPass ResolveForwardShaderPass(const Resources::Material* material) const;
|
||||
PassResourceLayout* GetOrCreatePassResourceLayout(
|
||||
const RenderContext& context,
|
||||
const ResolvedShaderPass& resolvedShaderPass);
|
||||
RHI::RHIPipelineState* GetOrCreatePipelineState(
|
||||
const RenderContext& context,
|
||||
const Resources::Material* material);
|
||||
RHI::RHIDescriptorSet* GetOrCreatePerObjectSet(Core::uint64 objectId);
|
||||
CachedMaterialBindings* GetOrCreateMaterialBindings(
|
||||
bool CreateOwnedDescriptorSet(
|
||||
const PassSetLayoutMetadata& setLayout,
|
||||
OwnedDescriptorSet& descriptorSet);
|
||||
RHI::RHIDescriptorSet* GetOrCreateStaticDescriptorSet(
|
||||
PassResourceLayout& passLayout,
|
||||
Core::uint32 setIndex);
|
||||
CachedDescriptorSet* GetOrCreateDynamicDescriptorSet(
|
||||
const PassLayoutKey& passLayoutKey,
|
||||
const PassResourceLayout& passLayout,
|
||||
const PassSetLayoutMetadata& setLayout,
|
||||
Core::uint32 setIndex,
|
||||
Core::uint64 objectId,
|
||||
const Resources::Material* material,
|
||||
const PerMaterialConstants& materialConstants,
|
||||
RHI::RHIResourceView* textureView);
|
||||
void DestroyOwnedDescriptorSet(OwnedDescriptorSet& descriptorSet);
|
||||
void DestroyPassResourceLayout(PassResourceLayout& passLayout);
|
||||
|
||||
const Resources::Texture* ResolveTexture(const Resources::Material* material) const;
|
||||
RHI::RHIResourceView* ResolveTextureView(const VisibleRenderItem& visibleItem);
|
||||
@@ -137,12 +229,9 @@ private:
|
||||
|
||||
RenderResourceCache m_resourceCache;
|
||||
|
||||
RHI::RHIDescriptorPool* m_samplerPool = nullptr;
|
||||
RHI::RHIDescriptorSet* m_samplerSet = nullptr;
|
||||
RHI::RHIPipelineLayout* m_pipelineLayout = nullptr;
|
||||
std::unordered_map<PassLayoutKey, PassResourceLayout, PassLayoutKeyHash> m_passResourceLayouts;
|
||||
std::unordered_map<PipelineStateKey, RHI::RHIPipelineState*, PipelineStateKeyHash> m_pipelineStates;
|
||||
std::unordered_map<Core::uint64, OwnedDescriptorSet> m_perObjectSets;
|
||||
std::unordered_map<const Resources::Material*, CachedMaterialBindings> m_materialBindings;
|
||||
std::unordered_map<DynamicDescriptorSetKey, CachedDescriptorSet, DynamicDescriptorSetKeyHash> m_dynamicDescriptorSets;
|
||||
RHI::RHISampler* m_sampler = nullptr;
|
||||
RHI::RHITexture* m_fallbackTexture = nullptr;
|
||||
RHI::RHIResourceView* m_fallbackTextureView = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user