WIP refactoring to move resource streaming to use KRResourceRequest lists

This commit is contained in:
2025-11-14 22:30:08 -08:00
parent d664e670f4
commit dec5872cf6
15 changed files with 95 additions and 21 deletions

View File

@@ -143,14 +143,14 @@ const std::string KRCamera::getSkyBox() const
return m_skyBox.getName();
}
void KRCamera::preStream(const KRViewport& viewport)
void KRCamera::preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests)
{
KRNode::preStream(viewport);
KRNode::preStream(viewport, resourceRequests);
m_skyBox.bind(&getContext());
if (m_skyBox.isBound()) {
m_skyBox.get()->requestResidency(0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE);
resourceRequests.emplace_back(m_skyBox.get(), KRTexture::TEXTURE_USAGE_SKY_CUBE);
}
}

View File

@@ -61,7 +61,7 @@ public:
void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface, KRRenderGraph& renderGraph);
void preStream(const KRViewport& viewport) final;
void preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests) final;
void render(KRNode::RenderInfo& ri) final;
KRRenderSettings settings;

View File

@@ -313,9 +313,9 @@ void KRModel::render(KRNode::RenderInfo& ri)
}
}
void KRModel::preStream(const KRViewport& viewport)
void KRModel::preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests)
{
KRNode::preStream(viewport);
KRNode::preStream(viewport, resourceRequests);
loadModel();
float lod_coverage = viewport.coverage(getBounds());

View File

@@ -63,7 +63,7 @@ public:
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
virtual void render(KRNode::RenderInfo& ri) override;
virtual void preStream(const KRViewport& viewport) override;
virtual void preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests) override;
virtual hydra::AABB getBounds();

View File

@@ -684,7 +684,7 @@ KRNode* KRNode::LoadXML(KRScene& scene, tinyxml2::XMLElement* e)
return new_node;
}
void KRNode::preStream(const KRViewport& viewport)
void KRNode::preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests)
{
}

View File

@@ -32,6 +32,7 @@
#pragma once
#include "resources/KRResource.h"
#include "resources/KRResourceRequest.h"
#include "KRViewport.h"
#include "KROctreeNode.h"
#include "KRBehavior.h"
@@ -216,7 +217,7 @@ public:
KRScene& getScene();
virtual void preStream(const KRViewport& viewport);
virtual void preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests);
virtual void render(RenderInfo& ri);
virtual void physicsUpdate(float deltaTime);

View File

@@ -112,15 +112,15 @@ AABB KRSprite::getBounds()
}
void KRSprite::preStream(const KRViewport& viewport)
void KRSprite::preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests)
{
KRNode::preStream(viewport);
KRNode::preStream(viewport, resourceRequests);
// Pre-stream sprites, even if the alpha is zero
m_spriteTexture.bind(&getContext());
if (m_spriteTexture.isBound()) {
m_spriteTexture.get()->requestResidency(0.0f, KRTexture::TEXTURE_USAGE_SPRITE);
resourceRequests.emplace_back(m_spriteTexture.get(), KRTexture::TEXTURE_USAGE_SPRITE);
}
}

View File

@@ -52,7 +52,7 @@ public:
void setSpriteAlpha(float alpha);
float getSpriteAlpha() const;
virtual void preStream(const KRViewport& viewport) override;
virtual void preStream(const KRViewport& viewport, std::list<KRResourceRequest>& resourceRequests) override;
virtual void render(RenderInfo& ri) override;
virtual hydra::AABB getBounds() override;

View File

@@ -71,3 +71,8 @@ KrResult KRResource::moveToBundle(KRBundle* bundle)
delete data;
return KR_SUCCESS;
}
void KRResource::requestResidency(uint32_t usage, float lodCoverage)
{
}

View File

@@ -48,6 +48,10 @@ public:
KrResult moveToBundle(KRBundle* bundle);
// TODO: requestResidency is a temporary interface until the streaming system is updated
// to directly balance memory from KRResourceRequest's
virtual void requestResidency(uint32_t usage, float lodCoverage);
virtual ~KRResource();
static KRMesh* LoadObj(KRContext& context, const std::string& path);

View File

@@ -0,0 +1,50 @@
//
// KRResource.h
// Kraken Engine
//
// Copyright 2025 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#pragma once
#include "KREngine-common.h"
class KRResource;
class KRResourceRequest
{
public:
KRResourceRequest(KRResource* resource, uint32_t usage, float lodCoverage = 0.0f)
: resource(resource)
, usage(usage)
, coverage(static_cast<uint8_t>(KRCLAMP(lodCoverage / 1.0f * 255.f, 0, 255.f)))
{
}
KRResource* resource;
unsigned int usage : 24;
uint8_t coverage : 8;
};

View File

@@ -39,6 +39,7 @@
#include "nodes/KRSpotLight.h"
#include "nodes/KRPointLight.h"
#include "resources/audio/KRAudioManager.h"
#include "resources/KRResourceRequest.h"
#include "KRRenderPass.h"
using namespace mimir;
@@ -103,6 +104,7 @@ std::set<KRLight*>& KRScene::getLights()
void KRScene::render(KRNode::RenderInfo& ri)
{
std::list<KRResourceRequest> resourceRequests;
// ---------- Start: Vulkan Debug Code ----------
/*
@@ -153,7 +155,7 @@ void KRScene::render(KRNode::RenderInfo& ri)
KRNode* node = (*itr);
if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_PRESTREAM) {
if ((*itr)->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) {
node->preStream(*ri.viewport);
node->preStream(*ri.viewport, resourceRequests);
}
} else {
if ((*itr)->getLODVisibility() > KRNode::LOD_VISIBILITY_PRESTREAM) {
@@ -177,10 +179,10 @@ void KRScene::render(KRNode::RenderInfo& ri)
newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear();
for (std::vector<KROctreeNode*>::iterator octree_itr = remainingOctrees.begin(); octree_itr != remainingOctrees.end(); octree_itr++) {
render(ri, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
render(ri, resourceRequests, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
}
for (std::vector<KROctreeNode*>::iterator octree_itr = remainingOctreesTestResults.begin(); octree_itr != remainingOctreesTestResults.end(); octree_itr++) {
render(ri, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false);
render(ri, resourceRequests, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, false);
}
remainingOctrees = newRemainingOctrees;
remainingOctreesTestResults = newRemainingOctreesTestResults;
@@ -189,11 +191,16 @@ void KRScene::render(KRNode::RenderInfo& ri)
newRemainingOctrees.clear();
newRemainingOctreesTestResults.clear();
for (std::vector<KROctreeNode*>::iterator octree_itr = remainingOctreesTestResultsOnly.begin(); octree_itr != remainingOctreesTestResultsOnly.end(); octree_itr++) {
render(ri, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true);
render(ri, resourceRequests, *octree_itr, newRemainingOctrees, newRemainingOctreesTestResults, remainingOctreesTestResultsOnly, true, true);
}
// TODO: WIP Refactoring, this will be moved to the streaming system
for (KRResourceRequest request : resourceRequests) {
request.resource->requestResidency(request.usage, static_cast<float>(request.coverage) / 255.f);
}
}
void KRScene::render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, std::vector<KROctreeNode*>& remainingOctrees, std::vector<KROctreeNode*>& remainingOctreesTestResults, std::vector<KROctreeNode*>& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
void KRScene::render(KRNode::RenderInfo& ri, std::list<KRResourceRequest>& resourceRequests, KROctreeNode* pOctreeNode, std::vector<KROctreeNode*>& remainingOctrees, std::vector<KROctreeNode*>& remainingOctreesTestResults, std::vector<KROctreeNode*>& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly)
{
unordered_map<AABB, int>& visibleBounds = ri.viewport->getVisibleBounds();
if (pOctreeNode) {
@@ -358,7 +365,7 @@ void KRScene::render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, std::vec
//assert(pOctreeNode->getBounds().contains((*itr)->getBounds())); // Sanity check
if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_PRESTREAM) {
if ((*itr)->getLODVisibility() >= KRNode::LOD_VISIBILITY_PRESTREAM) {
(*itr)->preStream(*ri.viewport);
(*itr)->preStream(*ri.viewport, resourceRequests);
}
} else {
if ((*itr)->getLODVisibility() > KRNode::LOD_VISIBILITY_PRESTREAM)
@@ -374,7 +381,7 @@ void KRScene::render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, std::vec
const int* childOctreeOrder = ri.renderPass->getType() == RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT || ri.renderPass->getType() == RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES || ri.renderPass->getType() == RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE ? ri.viewport->getBackToFrontOrder() : ri.viewport->getFrontToBackOrder();
for (int i = 0; i < 8; i++) {
render(ri, pOctreeNode->getChildren()[childOctreeOrder[i]], remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
render(ri, resourceRequests, pOctreeNode->getChildren()[childOctreeOrder[i]], remainingOctrees, remainingOctreesTestResults, remainingOctreesTestResultsOnly, false, false);
}
// Remove lights added at this octree level from the stack

View File

@@ -92,7 +92,7 @@ public:
std::set<KRLight*>& getLights();
private:
void render(KRNode::RenderInfo& ri, KROctreeNode* pOctreeNode, std::vector<KROctreeNode*>& remainingOctrees, std::vector<KROctreeNode*>& remainingOctreesTestResults, std::vector<KROctreeNode*>& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
void render(KRNode::RenderInfo& ri, std::list<KRResourceRequest>& resourceRequests, KROctreeNode* pOctreeNode, std::vector<KROctreeNode*>& remainingOctrees, std::vector<KROctreeNode*>& remainingOctreesTestResults, std::vector<KROctreeNode*>& remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
KRNode* m_pRootNode;
KRLight* m_pFirstLight;

View File

@@ -146,6 +146,12 @@ void KRTexture::resize(int max_dim)
m_handle_lock.clear();
}
void KRTexture::requestResidency(uint32_t usage, float lodCoverage)
{
KRResource::requestResidency(usage, lodCoverage);
requestResidency(lodCoverage, static_cast<KRTexture::texture_usage_t>(usage));
}
void KRTexture::requestResidency(float lodCoverage, KRTexture::texture_usage_t textureUsage)
{
long current_frame = getContext().getCurrentFrame();

View File

@@ -78,6 +78,7 @@ public:
float getStreamPriority();
virtual void requestResidency(float lodCoverage, texture_usage_t textureUsage);
void requestResidency(uint32_t usage, float lodCoverage = 0.0f) override;
virtual bool isAnimated();
virtual KRTexture* compress(bool premultiply_alpha = false);