From 1ec9085d88b893b56ae78df43237d9e66ecae1d7 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sun, 31 May 2026 23:38:38 -0700 Subject: [PATCH] Implemented image binding reflection Now using image binding reflection for the KRCamera debug font texture --- kraken/KRPipeline.cpp | 104 ++++++++++++------ kraken/KRPipeline.h | 1 + kraken/KRShaderReflection.cpp | 5 + kraken/KRShaderReflection.h | 4 + kraken/nodes/KRCamera.cpp | 32 +++--- kraken/nodes/KRCamera.h | 1 + kraken/resources/KRResourceBinding.cpp | 2 +- kraken/resources/KRResourceBinding.h | 2 +- kraken/resources/texture/KRTextureBinding.cpp | 2 +- kraken/resources/texture/KRTextureBinding.h | 2 +- 10 files changed, 104 insertions(+), 51 deletions(-) diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index 973f430..9adaf69 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -533,6 +533,42 @@ bool KRPipeline::hasPushConstant(ShaderValue location) const } +bool KRPipeline::setImageBindings(const std::vector objects) +{ + bool success = true; + + for (int stage = 0; stage < static_cast(ShaderStage::ShaderStageCount); stage++) { + StageInfo& stageInfo = m_stages[stage]; + for (DescriptorSetInfo& descriptorSetInfo : stageInfo.descriptorSets) { + for (DescriptorBinding& binding : descriptorSetInfo.bindings) { + ImageDescriptorInfo* image = std::get_if(&binding); + if (image) { + bool found = false; + const KRTextureBinding* binding = nullptr; + for (const KRReflectedObject* object : objects) { + KRSampler* sampler = nullptr; + if (object->getImageBinding(image->name, &binding, &sampler)) { + if (binding->isBound() && binding->get()->getStreamLevel() > kraken_stream_level::STREAM_LEVEL_OUT) { + image->texture = binding->get(); + image->sampler = sampler; + found = true; + } + break; + } + } + + if (!found) { + success = false; + KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Image binding not found: %s", image->name.c_str()); + } + } + } + } + } + + return success; +} + bool KRPipeline::setPushConstants(const std::vector objects) { bool success = true; @@ -642,31 +678,10 @@ void KRPipeline::updateDescriptorBinding() bool KRPipeline::updatePushConstants(KRNode::RenderInfo& ri, const Matrix4& matModel) { - KRDirectionalLight* directionalLight = nullptr; - if (ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && ri.renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP) { - if (!ri.directional_lights.empty()) - { - directionalLight = ri.directional_lights.front(); - } - } - - KRModelView modelView(ri.viewport, matModel, directionalLight); - - ri.reflectedObjects.push_back(&modelView); - ri.reflectedObjects.push_back(ri.viewport); - ri.reflectedObjects.push_back(&ri.camera->settings); - - bool success = setPushConstants(ri.reflectedObjects); - - ri.reflectedObjects.pop_back(); - ri.reflectedObjects.pop_back(); - ri.reflectedObjects.pop_back(); - - setPushConstant(ShaderValue::absolute_time, getContext().getAbsoluteTime()); - - if (!success) { + if (!setPushConstants(ri.reflectedObjects)) { return false; } + setPushConstant(ShaderValue::absolute_time, getContext().getAbsoluteTime()); for (StageInfo& stageInfo : m_stages) { PushConstantInfo& pushConstants = stageInfo.pushConstants; @@ -680,19 +695,44 @@ bool KRPipeline::updatePushConstants(KRNode::RenderInfo& ri, const Matrix4& matM bool KRPipeline::bind(KRNode::RenderInfo& ri, const Matrix4& matModel) { - updateDescriptorBinding(); - updateDescriptorSets(); - bindDescriptorSets(ri.commandBuffer); - if (!updatePushConstants(ri, matModel)) { - return false; + bool success = true; + KRDirectionalLight* directionalLight = nullptr; + if (ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_LIGHTS && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_GBUFFER && ri.renderPass->getType() != RenderPassType::RENDER_PASS_DEFERRED_OPAQUE && ri.renderPass->getType() != RenderPassType::RENDER_PASS_SHADOWMAP) { + if (!ri.directional_lights.empty()) { + directionalLight = ri.directional_lights.front(); + } } - if (ri.pipeline != this) { - vkCmdBindPipeline(ri.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); - ri.pipeline = this; + KRModelView modelView(ri.viewport, matModel, directionalLight); + + ri.reflectedObjects.push_back(&modelView); + ri.reflectedObjects.push_back(ri.viewport); + ri.reflectedObjects.push_back(&ri.camera->settings); + + if (success) { + success = updatePushConstants(ri, matModel); } - return true; + if (success) { + success = setImageBindings(ri.reflectedObjects); + } + + if (success) { + updateDescriptorBinding(); + updateDescriptorSets(); + bindDescriptorSets(ri.commandBuffer); + + if (ri.pipeline != this) { + vkCmdBindPipeline(ri.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); + ri.pipeline = this; + } + } + + ri.reflectedObjects.pop_back(); + ri.reflectedObjects.pop_back(); + ri.reflectedObjects.pop_back(); + + return success; } void KRPipeline::updateDescriptorSets() diff --git a/kraken/KRPipeline.h b/kraken/KRPipeline.h index 0bc50cb..6edb8b8 100644 --- a/kraken/KRPipeline.h +++ b/kraken/KRPipeline.h @@ -221,6 +221,7 @@ public: static const size_t kPushConstantCount = static_cast(ShaderValue::NUM_SHADER_VALUES); + bool setImageBindings(const std::vector objects); bool setPushConstants(const std::vector objects); bool hasPushConstant(ShaderValue location) const; void setPushConstant(ShaderValue location, float value); diff --git a/kraken/KRShaderReflection.cpp b/kraken/KRShaderReflection.cpp index e4e5184..2b70cbb 100644 --- a/kraken/KRShaderReflection.cpp +++ b/kraken/KRShaderReflection.cpp @@ -308,3 +308,8 @@ bool KRReflectedObject::getShaderValue(ShaderValue value, KRResourceBinding* out { return false; } + +bool KRReflectedObject::getImageBinding(const std::string& name, const KRTextureBinding** binding, KRSampler** sample) const +{ + return false; +} \ No newline at end of file diff --git a/kraken/KRShaderReflection.h b/kraken/KRShaderReflection.h index 44efc9d..2fc10b4 100644 --- a/kraken/KRShaderReflection.h +++ b/kraken/KRShaderReflection.h @@ -33,9 +33,12 @@ #pragma once #include +#include #include "hydra.h" class KRResourceBinding; +class KRSampler; +class KRTextureBinding; enum class ShaderValueType : uint8_t { @@ -221,6 +224,7 @@ class KRReflectedObject { public: bool getShaderValue(ShaderValue value, ShaderValueType type, void* output) const; + virtual bool getImageBinding(const std::string& name, const KRTextureBinding** binding, KRSampler** sample) const; protected: virtual bool getShaderValue(ShaderValue value, bool* output) const; virtual bool getShaderValue(ShaderValue value, int32_t* output) const; diff --git a/kraken/nodes/KRCamera.cpp b/kraken/nodes/KRCamera.cpp index 8424d1b..fb08479 100755 --- a/kraken/nodes/KRCamera.cpp +++ b/kraken/nodes/KRCamera.cpp @@ -90,7 +90,6 @@ KRCamera::KRCamera(KRScene& scene, std::string name) m_frame_times_filled = 0; m_fade_color = Vector4::Zero(); - m_fontTexture.set("font"); m_debug_text_vbo_data.init(m_pContext->getMeshManager(), &m_debug_text_vertices, nullptr, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true, KRMeshManager::KRVBOData::IMMEDIATE #if KRENGINE_DEBUG_GPU_LABELS @@ -146,13 +145,13 @@ void KRCamera::getResourceBindings(std::list& bindings) void KRCamera::render(KRNode::RenderInfo& ri) { - KRScene& scene = getScene(); + ri.reflectedObjects.push_back(this); switch (ri.renderPass->getType()) { case RenderPassType::RENDER_PASS_FORWARD_OPAQUE: { // ----====---- Sky Box ----====---- - + GL_PUSH_GROUP_MARKER("Sky Box"); if (m_skyBox.val.isBound()) { @@ -210,7 +209,10 @@ void KRCamera::render(KRNode::RenderInfo& ri) default: break; } + + ri.reflectedObjects.pop_back(); + KRScene& scene = getScene(); scene.render(ri); switch (ri.renderPass->getType()) { @@ -479,6 +481,8 @@ void KRCamera::renderPost(RenderInfo& ri) void KRCamera::renderDebug(RenderInfo& ri) { + settings.m_debug_text = "Font Test"; // FNIDME!! KIPG!! HACK!! Debug text debugging... + const char* szText = settings.m_debug_text.c_str(); if (*szText == '\0') { if (m_debug_text_vertices.getSize() > 0) { @@ -487,16 +491,6 @@ void KRCamera::renderDebug(RenderInfo& ri) return; } - if (!m_fontTexture.isBound()) - { - return; - } - - KRTexture* fontTexture = m_fontTexture.get(); - if (fontTexture->getStreamLevel() == kraken_stream_level::STREAM_LEVEL_OUT) { - return; - } - std::string debug_text; if (settings.debug_display != KRRenderSettings::KRENGINE_DEBUG_DISPLAY_NONE) { debug_text = getDebugText();; @@ -631,7 +625,6 @@ void KRCamera::renderDebug(RenderInfo& ri) info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; KRPipeline* fontShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info); - fontShader->setImageBinding("fontTexture", fontTexture, getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER); if (fontShader->bind(ri, Matrix4())) { m_debug_text_vbo_data.bind(ri.commandBuffer); @@ -859,8 +852,17 @@ bool KRCamera::getShaderValue(ShaderValue value, hydra::Vector4* output) const default: return KRNode::getShaderValue(value, output); } +} - +bool KRCamera::getImageBinding(const std::string& name, const KRTextureBinding** binding, KRSampler** sample) const +{ + if (name == "fontTexture") { + *binding = &m_fontTexture; + *sample = getContext().getSamplerManager()->DEFAULT_CLAMPED_SAMPLER; + return true; + } else { + return KRNode::getImageBinding(name, binding, sample); + } } bool KRCamera::alwaysStreamResources() diff --git a/kraken/nodes/KRCamera.h b/kraken/nodes/KRCamera.h index 51d8106..5a2ce06 100755 --- a/kraken/nodes/KRCamera.h +++ b/kraken/nodes/KRCamera.h @@ -86,6 +86,7 @@ public: protected: bool getShaderValue(ShaderValue value, hydra::Vector4* output) const override; + bool getImageBinding(const std::string& name, const KRTextureBinding** binding, KRSampler** sample) const override; private: void createBuffers(int renderBufferWidth, int renderBufferHeight); diff --git a/kraken/resources/KRResourceBinding.cpp b/kraken/resources/KRResourceBinding.cpp index c80a081..d72285b 100644 --- a/kraken/resources/KRResourceBinding.cpp +++ b/kraken/resources/KRResourceBinding.cpp @@ -60,7 +60,7 @@ void KRResourceBinding::submitRequest(KRContext* context, std::list& resourceRequests, float lodCoverage = 0.f); - KRResource* get(); + KRResource* get() const; void set(KRResource* resource); void set(const std::string& name); bool isSet() const; diff --git a/kraken/resources/texture/KRTextureBinding.cpp b/kraken/resources/texture/KRTextureBinding.cpp index 8e4e9b2..74faae3 100644 --- a/kraken/resources/texture/KRTextureBinding.cpp +++ b/kraken/resources/texture/KRTextureBinding.cpp @@ -46,7 +46,7 @@ KRTextureBinding::KRTextureBinding(KRTexture::texture_usage_t usage) } -KRTexture* KRTextureBinding::get() +KRTexture* KRTextureBinding::get() const { return static_cast(m_resource); } diff --git a/kraken/resources/texture/KRTextureBinding.h b/kraken/resources/texture/KRTextureBinding.h index e3be64f..1a7a49a 100644 --- a/kraken/resources/texture/KRTextureBinding.h +++ b/kraken/resources/texture/KRTextureBinding.h @@ -42,7 +42,7 @@ class KRTextureBinding : public KRResourceBinding public: KRTextureBinding(const std::string& name, KRTexture::texture_usage_t usage); KRTextureBinding(KRTexture::texture_usage_t usage); - KRTexture* get(); + KRTexture* get() const; bool bind(KRContext* context) override final; private: