WIP Refactoring to move frame rendering from KRCamera to KRRenderGraph

This commit is contained in:
2025-04-10 00:35:39 -07:00
parent 7dc8a1304e
commit 5f286e185e
8 changed files with 167 additions and 97 deletions

View File

@@ -157,10 +157,23 @@ KRRenderPass* KRRenderGraph::getFinalRenderPass()
return nullptr;
}
void KRRenderGraph::render(VkCommandBuffer &commandBuffer, KRSurface& surface, KRScene* scene)
void KRRenderGraph::render(VkCommandBuffer &commandBuffer, KRSurface& surface, KRCamera* camera)
{
KRNode::RenderInfo ri(commandBuffer);
ri.camera = camera;
if (camera) {
ri.viewport = camera->getViewport();
} else {
ri.viewport = nullptr;
}
ri.surface = &surface;
for(KRRenderPass* pass : m_renderPasses) {
ri.renderPass = pass;
pass->begin(commandBuffer, surface);
if (camera) {
camera->render(ri);
}
pass->end(commandBuffer);
}
}

View File

@@ -54,7 +54,7 @@ public:
void addRenderPass(KRDevice& device, const RenderPassInfo& info);
KRRenderPass* getRenderPass(RenderPassType type);
KRRenderPass* getFinalRenderPass();
void render(VkCommandBuffer &commandBuffer, KRSurface& surface, KRScene* scene);
void render(VkCommandBuffer &commandBuffer, KRSurface& surface, KRCamera* camera);
void destroy(KRDevice& device);
private:

View File

@@ -161,6 +161,24 @@ KrResult KRRenderGraphDeferred::initialize(KRSurface &surface)
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Particle Occlusion", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Additive Particles", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Additive Volumetric Effects", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_DEBUG_OVERLAYS;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Debug Overlays", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);

View File

@@ -130,6 +130,24 @@ KrResult KRRenderGraphForward::initialize(KRSurface &surface)
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Particle Occlusion", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Additive Particles", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Additive Volumetric Effects", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);
#endif
addRenderPass(*surface.getDevice(), info);
info.type = RenderPassType::RENDER_PASS_DEBUG_OVERLAYS;
#if KRENGINE_DEBUG_GPU_LABELS
strncpy(info.debugLabel, "Debug Overlays", KRENGINE_DEBUG_GPU_LABEL_MAX_LEN);

View File

@@ -50,7 +50,7 @@ KRSurface::KRSurface(KRContext& context, KrSurfaceHandle handle, void* platformH
, m_frameIndex(0)
, m_renderGraphForward(std::make_unique<KRRenderGraphForward>(context))
, m_renderGraphDeferred(std::make_unique<KRRenderGraphDeferred>(context))
, m_blackFrameRenderGraph(std::make_unique<KRRenderGraphBlackFrame>(context))
, m_renderGraphBlackFrame(std::make_unique<KRRenderGraphBlackFrame>(context))
, m_swapChain(std::make_unique<KRSwapchain>(context))
, m_surfaceFormat{}
{
@@ -118,7 +118,7 @@ void KRSurface::destroy()
std::unique_ptr<KRDevice>& device = m_pContext->getDeviceManager()->getDevice(m_deviceHandle);
m_renderGraphForward->destroy(*device);
m_renderGraphDeferred->destroy(*device);
m_blackFrameRenderGraph->destroy(*device);
m_renderGraphBlackFrame->destroy(*device);
for (int i=0; i < KRENGINE_MAX_FRAMES_IN_FLIGHT; i++) {
if (device && m_renderFinishedSemaphores[i] != VK_NULL_HANDLE) {
@@ -180,7 +180,7 @@ KrResult KRSurface::createSwapChain()
res = m_blackFrameRenderGraph->initialize(*this);
res = m_renderGraphBlackFrame->initialize(*this);
if (res != KR_SUCCESS) {
return res;
}
@@ -262,7 +262,7 @@ void KRSurface::endFrame()
void KRSurface::renderBlackFrame(VkCommandBuffer &commandBuffer)
{
m_blackFrameRenderGraph->render(commandBuffer, *this, nullptr);
m_renderGraphBlackFrame->render(commandBuffer, *this, nullptr);
}
VkFormat KRSurface::getSurfaceFormat() const

View File

@@ -85,7 +85,7 @@ private:
KrResult createSwapChain();
std::unique_ptr<KRRenderGraphForward> m_renderGraphForward;
std::unique_ptr<KRRenderGraphDeferred> m_renderGraphDeferred;
std::unique_ptr<KRRenderGraphBlackFrame> m_blackFrameRenderGraph;
std::unique_ptr<KRRenderGraphBlackFrame> m_renderGraphBlackFrame;
VkSurfaceFormatKHR m_surfaceFormat;
};

View File

@@ -145,6 +145,92 @@ const std::string KRCamera::getSkyBox() const
return m_skyBox;
}
void KRCamera::render(KRNode::RenderInfo& ri)
{
KRScene& scene = getScene();
switch (ri.renderPass->getType()) {
case RenderPassType::RENDER_PASS_FORWARD_OPAQUE:
{
// ----====---- Sky Box ----====----
GL_PUSH_GROUP_MARKER("Sky Box");
if (!m_pSkyBoxTexture && m_skyBox.length()) {
m_pSkyBoxTexture = getContext().getTextureManager()->getTextureCube(m_skyBox.c_str());
}
if (m_pSkyBoxTexture) {
m_pSkyBoxTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE);
std::string shader_name("sky_box");
PipelineInfo info{};
info.shader_name = &shader_name;
info.pCamera = this;
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kOpaqueNoDepthWrite;
info.cullMode = CullMode::kCullNone;
KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
pPipeline->setImageBinding("diffuseTexture", m_pSkyBoxTexture, getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
pPipeline->bind(ri, Matrix4());
// Render a full screen quad
m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f);
vkCmdDraw(ri.commandBuffer, 4, 1, 0, 0);
}
GL_POP_GROUP_MARKER;
}
break;
case RenderPassType::RENDER_PASS_DEBUG_OVERLAYS:
{
// ----====---- Debug Overlays ----====----
if (settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE) {
KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES;
PipelineInfo info{};
std::string shader_name("visualize_overlay");
info.shader_name = &shader_name;
info.pCamera = this;
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kAdditive;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
KRPipeline* pVisShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &vertices, 1.0f);
for (unordered_map<AABB, int>::iterator itr = m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
Matrix4 matModel = Matrix4();
matModel.scale((*itr).first.size() * 0.5f);
matModel.translate((*itr).first.center());
pVisShader->bind(ri, matModel);
vkCmdDraw(ri.commandBuffer, 14, 1, 0, 0);
}
}
renderDebug(ri);
}
break;
case RenderPassType::RENDER_PASS_POST_COMPOSITE:
{
renderPost(ri);
}
break;
default:
break;
}
scene.render(ri);
switch (ri.renderPass->getType()) {
default:
break;
}
}
void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface)
{
if (compositeSurface.m_handle != m_surfaceHandle) {
@@ -189,13 +275,13 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PRESTREAM);
ri.surface = &compositeSurface;
scene.render(ri);
render(ri);
// ----====---- Generate Shadowmaps for Lights ----====----
if (settings.m_cShadowBuffers > 0) {
GL_PUSH_GROUP_MARKER("Generate Shadowmaps");
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_SHADOWMAP);
scene.render(ri);
render(ri);
GL_POP_GROUP_MARKER;
}
@@ -210,7 +296,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass->begin(commandBuffer, compositeSurface);
// Render the geometry
scene.render(ri);
render(ri);
// End render pass
ri.renderPass->end(commandBuffer);
@@ -236,7 +322,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render the geometry
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_DEFERRED_LIGHTS);
ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri);
render(ri);
ri.renderPass->end(commandBuffer);
GL_POP_GROUP_MARKER;
@@ -254,7 +340,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render the geometry
// TODO: At this point, we only want to render octree nodes that produced fragments during the 1st pass into the GBuffer
scene.render(ri);
render(ri);
// End render pass
ri.renderPass->end(commandBuffer);
@@ -269,44 +355,14 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass->begin(commandBuffer, compositeSurface);
// Render the geometry
scene.render(ri);
render(ri);
GL_POP_GROUP_MARKER;
ri.renderPass->end(commandBuffer);
}
// ----====---- Sky Box ----====----
GL_PUSH_GROUP_MARKER("Sky Box");
if (!m_pSkyBoxTexture && m_skyBox.length()) {
m_pSkyBoxTexture = getContext().getTextureManager()->getTextureCube(m_skyBox.c_str());
}
if (m_pSkyBoxTexture) {
m_pSkyBoxTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_SKY_CUBE);
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_OPAQUE);
std::string shader_name("sky_box");
PipelineInfo info{};
info.shader_name = &shader_name;
info.pCamera = this;
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kOpaqueNoDepthWrite;
info.cullMode = CullMode::kCullNone;
KRPipeline* pPipeline = getContext().getPipelineManager()->getPipeline(compositeSurface, info);
pPipeline->setImageBinding("diffuseTexture", m_pSkyBoxTexture, getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
pPipeline->bind(ri, Matrix4());
// Render a full screen quad
m_pContext->getMeshManager()->bindVBO(commandBuffer, &getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f);
vkCmdDraw(commandBuffer, 4, 1, 0, 0);
}
GL_POP_GROUP_MARKER;
// ----====---- Transparent Geometry, Forward Rendering ----====----
@@ -316,7 +372,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
// Render all transparent geometry
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri);
render(ri);
ri.renderPass->end(commandBuffer);
GL_POP_GROUP_MARKER;
@@ -328,7 +384,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_PARTICLE_OCCLUSION);
if (ri.renderPass) {
ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri);
render(ri);
ri.renderPass->end(commandBuffer);
}
@@ -342,7 +398,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_ADDITIVE_PARTICLES);
if (ri.renderPass) {
ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri);
render(ri);
ri.renderPass->end(commandBuffer);
}
@@ -377,7 +433,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE);
ri.viewport = &volumetricLightingViewport;
ri.renderPass->begin(commandBuffer, compositeSurface);
scene.render(ri);
render(ri);
ri.renderPass->end(commandBuffer);
ri.viewport = &m_viewport;
GL_POP_GROUP_MARKER;
@@ -389,38 +445,12 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
GL_PUSH_GROUP_MARKER("Debug Overlays");
if (settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_OCTREE) {
KRMeshManager::KRVBOData& vertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_3D_CUBE_VERTICES;
ri.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
PipelineInfo info{};
std::string shader_name("visualize_overlay");
info.shader_name = &shader_name;
info.pCamera = this;
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kAdditive;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
KRPipeline* pVisShader = getContext().getPipelineManager()->getPipeline(compositeSurface, info);
m_pContext->getMeshManager()->bindVBO(commandBuffer, &vertices, 1.0f);
for (unordered_map<AABB, int>::iterator itr = m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
Matrix4 matModel = Matrix4();
matModel.scale((*itr).first.size() * 0.5f);
matModel.translate((*itr).first.center());
pVisShader->bind(ri,matModel);
vkCmdDraw(commandBuffer, 14, 1, 0, 0);
}
}
GL_POP_GROUP_MARKER;
// fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i/%i Kbyte (active/total) Shader Handles: %i Visible Bounds: %i Max Texture LOD: %i\n", (int)m_pContext->getMeshManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getActiveMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024, (int)m_pContext->getPipelineManager()->getShaderHandlesUsed(), (int)m_visibleBounds.size(), m_pContext->getTextureManager()->getLODDimCap());
GL_PUSH_GROUP_MARKER("Debug Overlays");
renderDebug(commandBuffer, compositeSurface);
GL_POP_GROUP_MARKER;
@@ -430,7 +460,7 @@ void KRCamera::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeS
KRRenderPass* postCompositePass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_POST_COMPOSITE);
postCompositePass->begin(commandBuffer, compositeSurface);
renderPost(commandBuffer, compositeSurface);
renderPost(ri);
postCompositePass->end(commandBuffer);
@@ -597,7 +627,7 @@ void KRCamera::destroyBuffers()
*/
}
void KRCamera::renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface)
void KRCamera::renderPost(RenderInfo& ri)
{
/*
// TODO - Re-enable once post fx shader is converted for Vulkan
@@ -659,7 +689,7 @@ void KRCamera::renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface)
}
void KRCamera::renderDebug(VkCommandBuffer& commandBuffer, KRSurface& surface)
void KRCamera::renderDebug(RenderInfo& ri)
{
const char* szText = settings.m_debug_text.c_str();
@@ -785,10 +815,8 @@ void KRCamera::renderDebug(VkCommandBuffer& commandBuffer, KRSurface& surface)
}
}
m_debug_text_vbo_data.load(commandBuffer);
m_debug_text_vbo_data.load(ri.commandBuffer);
KRRenderPass* debugPass = surface.getRenderPass(RenderPassType::RENDER_PASS_DEBUG_OVERLAYS);
debugPass->begin(commandBuffer, surface);
KRTexture* fontTexture = m_pContext->getTextureManager()->getTexture("font");
fontTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_UI);
@@ -798,30 +826,21 @@ void KRCamera::renderDebug(VkCommandBuffer& commandBuffer, KRSurface& surface)
std::string shader_name("debug_font");
info.shader_name = &shader_name;
info.pCamera = this;
info.renderPass = surface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kAlphaBlendNoTest;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA);
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
KRPipeline* fontShader = m_pContext->getPipelineManager()->getPipeline(surface, info);
RenderInfo ri(commandBuffer);
ri.camera = this;
ri.renderPass = surface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
ri.surface = &surface;
ri.viewport = &m_viewport;
KRPipeline* fontShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
fontShader->setImageBinding("fontTexture", fontTexture, getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER);
fontShader->bind(ri, Matrix4());
m_debug_text_vbo_data.bind(commandBuffer);
m_debug_text_vbo_data.bind(ri.commandBuffer);
vkCmdDraw(commandBuffer, vertex_count, 1, 0, 0);
vkCmdDraw(ri.commandBuffer, vertex_count, 1, 0, 0);
}
debugPass->end(commandBuffer);
m_debug_text_vertices.unlock();
} else {
@@ -1024,9 +1043,9 @@ std::string KRCamera::getDebugText()
}
const KRViewport& KRCamera::getViewport() const
KRViewport* KRCamera::getViewport()
{
return m_viewport;
return &m_viewport;
}
void KRCamera::setFadeColor(const Vector4& fade_color)

View File

@@ -59,9 +59,11 @@ public:
void renderFrame(VkCommandBuffer& commandBuffer, KRSurface& compositeSurface);
void render(KRNode::RenderInfo& ri);
KRRenderSettings settings;
const KRViewport& getViewport() const;
KRViewport* getViewport();
virtual std::string getElementName() override;
@@ -89,8 +91,8 @@ private:
int volumetricLightAccumulationBuffer, volumetricLightAccumulationTexture;
void renderPost(VkCommandBuffer& commandBuffer, KRSurface& surface);
void renderDebug(VkCommandBuffer& commandBuffer, KRSurface& surface);
void renderPost(RenderInfo& ri);
void renderDebug(RenderInfo& ri);
void destroyBuffers();