mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 06:55:02 +01:00
182 lines
6.2 KiB
C++
182 lines
6.2 KiB
C++
#include "nvrenderer/resource_registry.h"
|
|
|
|
#include "utilities/Logs.h"
|
|
#include "fmt/compile.h"
|
|
#include "nvtexture.h"
|
|
#include "nvrenderer/nvrenderer.h"
|
|
|
|
MaResourceMappingSet& MaResourceMappingSet::Add(
|
|
const MaResourceMapping& mapping) {
|
|
m_mappings.push_back(mapping);
|
|
return *this;
|
|
}
|
|
|
|
void MaResourceMappingSet::ToBindingLayout(
|
|
nvrhi::BindingLayoutDesc& desc) const {
|
|
for (const auto& [slot, size, key, type] : m_mappings) {
|
|
nvrhi::BindingLayoutItem item{};
|
|
item.type = type;
|
|
item.slot = slot;
|
|
item.size = size;
|
|
desc.addItem(item);
|
|
}
|
|
}
|
|
|
|
bool MaResourceMappingSet::ToBindingSet(
|
|
nvrhi::BindingSetDesc& desc, const MaResourceRegistry* registry,
|
|
const nvrhi::BindingLayoutDesc* reference_layout) const {
|
|
bool is_valid = true;
|
|
for (const auto& [slot, size, key, type] : m_mappings) {
|
|
MaResourceView resource{};
|
|
switch (type) {
|
|
case nvrhi::ResourceType::PushConstants:
|
|
case nvrhi::ResourceType::None:
|
|
break;
|
|
default:
|
|
resource = registry->GetResource(key, type);
|
|
}
|
|
bool item_is_valid = resource.IsValid();
|
|
bool item_is_present = true;
|
|
nvrhi::BindingSetItem item{};
|
|
item.slot = slot;
|
|
item.type = type;
|
|
item.resourceHandle = resource.m_resource;
|
|
item.dimension = nvrhi::TextureDimension::Unknown;
|
|
item.format = nvrhi::Format::UNKNOWN;
|
|
switch (type) {
|
|
case nvrhi::ResourceType::PushConstants:
|
|
item.range.byteOffset = 0;
|
|
item.range.byteSize = size;
|
|
item_is_valid = true;
|
|
break;
|
|
case nvrhi::ResourceType::RawBuffer_SRV:
|
|
case nvrhi::ResourceType::RawBuffer_UAV:
|
|
case nvrhi::ResourceType::StructuredBuffer_SRV:
|
|
case nvrhi::ResourceType::StructuredBuffer_UAV:
|
|
case nvrhi::ResourceType::TypedBuffer_SRV:
|
|
case nvrhi::ResourceType::TypedBuffer_UAV:
|
|
case nvrhi::ResourceType::ConstantBuffer:
|
|
case nvrhi::ResourceType::VolatileConstantBuffer:
|
|
item.range = nvrhi::EntireBuffer;
|
|
break;
|
|
case nvrhi::ResourceType::Texture_SRV:
|
|
case nvrhi::ResourceType::Texture_UAV:
|
|
item.subresources = nvrhi::AllSubresources;
|
|
default:;
|
|
}
|
|
if (reference_layout) {
|
|
item_is_present = false;
|
|
for (const auto& binding : reference_layout->bindings) {
|
|
if (binding.type != item.type || binding.slot != item.slot) continue;
|
|
item_is_present = true;
|
|
break;
|
|
}
|
|
}
|
|
if (item_is_valid && item_is_present) desc.addItem(item);
|
|
is_valid &= item_is_valid;
|
|
}
|
|
return is_valid;
|
|
}
|
|
|
|
MaResourceView MaResourceRegistry::GetResource(
|
|
const entt::hashed_string& key,
|
|
const nvrhi::ResourceType requested_type) const {
|
|
auto registry = this;
|
|
while (registry) {
|
|
if (const auto resource = registry->GetResourceLocal(key, requested_type);
|
|
resource.IsValid())
|
|
return resource;
|
|
registry = registry->m_parent;
|
|
}
|
|
std::string what = fmt::format("Unable to locate resource {:s} [{:#x}]",
|
|
key.data(), key.value());
|
|
ErrorLog(fmt::format("Unable to locate resource {:s} [{:#x}]", key.data(),
|
|
key.value()));
|
|
throw std::runtime_error(what.c_str());
|
|
return {};
|
|
}
|
|
|
|
MaResourceRegistry::MaResourceRegistry(MaResourceRegistry* parent)
|
|
: m_parent(parent) {}
|
|
|
|
void MaResourceRegistry::InitResourceRegistry() {
|
|
if (m_parent) {
|
|
m_texture_manager =
|
|
std::shared_ptr<NvTextureManager>(m_parent->GetTextureManager());
|
|
} else {
|
|
m_texture_manager =
|
|
std::make_shared<NvTextureManager>(dynamic_cast<NvRenderer*>(this));
|
|
}
|
|
}
|
|
|
|
void MaResourceRegistry::RegisterResource(const bool global,
|
|
const entt::hashed_string& key,
|
|
nvrhi::IResource* resource,
|
|
const nvrhi::ResourceType type) {
|
|
auto registry = this;
|
|
while (global && registry->m_parent) registry = registry->m_parent;
|
|
registry->m_resource_views[key] = {resource, type};
|
|
}
|
|
|
|
void MaResourceRegistry::RegisterTexture(const entt::hashed_string& key,
|
|
const size_t handle) {
|
|
m_streaming_textures[key] = handle;
|
|
}
|
|
|
|
void MaResourceRegistry::RegisterResource(const bool global, const char* key,
|
|
nvrhi::IResource* resource,
|
|
const nvrhi::ResourceType type) {
|
|
RegisterResource(global, static_cast<entt::hashed_string>(key), resource,
|
|
type);
|
|
}
|
|
|
|
void MaResourceRegistry::RegisterTexture(const char* key, const size_t handle) {
|
|
RegisterTexture(static_cast<entt::hashed_string>(key), handle);
|
|
}
|
|
|
|
MaResourceView MaResourceRegistry::GetResourceLocal(
|
|
const entt::hashed_string& key,
|
|
const nvrhi::ResourceType requested_type) const {
|
|
// Attempt to fetch streaming texture
|
|
if (requested_type == nvrhi::ResourceType::Texture_SRV) {
|
|
if (const auto it = m_streaming_textures.find(key);
|
|
it != m_streaming_textures.end()) {
|
|
if (const auto texture_manager = GetTextureManager();
|
|
texture_manager && texture_manager->IsValidHandle(it->second))
|
|
return {texture_manager->GetRhiTexture(it->second),
|
|
nvrhi::ResourceType::Texture_SRV};
|
|
}
|
|
}
|
|
// Attempt to fetch static resource
|
|
if (const auto it = m_resource_views.find(key);
|
|
it != m_resource_views.end() && requested_type == it->second.m_type) {
|
|
return it->second;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
NvTextureManager* MaResourceRegistry::GetTextureManager() const {
|
|
auto registry = this;
|
|
while (!registry->m_texture_manager && registry->m_parent)
|
|
registry = registry->m_parent;
|
|
return registry->m_texture_manager.get();
|
|
}
|
|
|
|
uint64_t MaResourceRegistry::GetLastStreamingTextureUpdate() const {
|
|
uint64_t last_update = 1;
|
|
const auto texture_manager = GetTextureManager();
|
|
for (const auto& [key, texture] : m_streaming_textures) {
|
|
if (!texture_manager->IsValidHandle(texture)) continue;
|
|
last_update = std::max(last_update,
|
|
texture_manager->GetTexture(texture)->m_last_change);
|
|
}
|
|
return last_update;
|
|
}
|
|
void MaResourceRegistry::UpdateLastStreamingTextureUse(
|
|
const glm::dvec3& location) const {
|
|
const auto texture_manager = GetTextureManager();
|
|
for (const auto& [key, texture] : m_streaming_textures) {
|
|
texture_manager->UpdateLastUse(texture, location);
|
|
}
|
|
}
|