diff --git a/openVulkanoCpp/Scene/Shader/Shader.hpp b/openVulkanoCpp/Scene/Shader/Shader.hpp index ed1da7d..e89cb9a 100644 --- a/openVulkanoCpp/Scene/Shader/Shader.hpp +++ b/openVulkanoCpp/Scene/Shader/Shader.hpp @@ -8,6 +8,7 @@ #include "Base/ICloseable.hpp" #include "Base/Utils.hpp" +#include "Base/Render/RenderResource.hpp" #include "VertexInputDescription.hpp" #include "ShaderProgramType.hpp" #include "DescriptorInputDescription.hpp" @@ -79,7 +80,7 @@ namespace OpenVulkano::Scene - class Shader final : public ICloseable + class Shader final : public RenderResourceHolder, public ICloseable { public: std::vector shaderPrograms{}; @@ -88,7 +89,6 @@ namespace OpenVulkano::Scene std::vector pushConstantRanges; Topology topology = Topology::TRIANGLE_LIST; CullMode cullMode = CullMode::BACK; - ICloseable* renderShader = nullptr; CompareOp depthCompareOp = CompareOp::LESS; bool alphaBlend = false; // TODO allow fine control over blending bool depthTest = true; @@ -96,7 +96,7 @@ namespace OpenVulkano::Scene bool dynamicViewport = true; // If disabled the swapchains fullscreen viewport will always be used, regardless of framebuffer or viewport Shader() = default; - ~Shader() override { if (renderShader) Shader::Close(); } + ~Shader() override { Shader::Close(); } Shader& AddShaderProgram(const ShaderProgram& shaderProgram) { @@ -163,14 +163,14 @@ namespace OpenVulkano::Scene void Close() override { - renderShader->Close(); - renderShader = nullptr; + if (HasRenderResource()) + GetRenderResource().Release(); } private: void CheckShaderInitState() const { - if (renderShader) throw std::runtime_error("Shader already initialized!"); + if (HasRenderResource()) throw std::runtime_error("Shader already initialized!"); } }; } diff --git a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp index e370336..1d9042a 100644 --- a/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp +++ b/openVulkanoCpp/Vulkan/Resources/ResourceManager.cpp @@ -277,6 +277,7 @@ namespace OpenVulkano::Vulkan find_if(shaders.begin(), shaders.end(), [&](auto& obj){ return obj.get() == shader; } ); + object->get()->owner = nullptr; shaders.erase(object); } @@ -308,9 +309,8 @@ namespace OpenVulkano::Vulkan VulkanShader* ResourceManager::CreateShader(Scene::Shader* shader) { const std::unique_lock lock(mutex); - if (shader->renderShader) return static_cast(shader->renderShader); - VulkanShader* vkShader = new VulkanShader(); - vkShader->Init(context, shader, this); + if (shader->HasRenderResource()) return static_cast(shader->GetRenderResource()); + VulkanShader* vkShader = new VulkanShader(context, shader, this); shaders.emplace_back(vkShader); return vkShader; } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp index fc851aa..e7bc334 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.cpp @@ -17,7 +17,8 @@ namespace OpenVulkano::Vulkan VulkanShader::~VulkanShader() { - if (shader) Close(); + if (owner) owner->RemoveShader(this); + owner = nullptr; device.destroyPipeline(pipeline); for(auto& shaderModule : shaderModules) { @@ -28,12 +29,9 @@ namespace OpenVulkano::Vulkan device.destroyDescriptorSetLayout(descriptorSetLayout); } - void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner) + VulkanShader::VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner) + : IRenderResource(shader), device(context->device->device), owner(owner), context(context) { - this->device = context->device->device; - this->shader = shader; - this->owner = owner; - this->context = context; shaderModules.reserve(shader->shaderPrograms.size()); shaderStageCreateInfo.resize(shader->shaderPrograms.size()); int i = 0; @@ -45,11 +43,11 @@ namespace OpenVulkano::Vulkan i++; } BuildPipeline(); - shader->renderShader = this; } void VulkanShader::BuildPipeline() { + Scene::Shader* shader = GetOwner(); std::vector vertexBindDesc; std::vector attributeDescriptions; vertexBindDesc.reserve(shader->vertexInputDescriptions.size()); @@ -129,14 +127,6 @@ namespace OpenVulkano::Vulkan context->commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); } - void VulkanShader::Close() - { - shader->renderShader = nullptr; - shader = nullptr; - if (owner) owner->RemoveShader(this); - owner = nullptr; - } - void VulkanShader::CreatePipelineLayout() { if (!descriptorSetLayouts.empty()) @@ -150,6 +140,7 @@ namespace OpenVulkano::Vulkan descriptorSetLayouts.push_back(device.createDescriptorSetLayout({ {}, layoutBindings1.size(), layoutBindings1.data() })); descriptorSetLayouts.push_back(device.createDescriptorSetLayout({ {}, layoutBindings2.size(), layoutBindings2.data() })); + Scene::Shader* shader = GetOwner(); for(const auto& set : shader->descriptorSets) { vk::DescriptorSetLayoutCreateInfo createInfo { {}, static_cast(set.size()), reinterpret_cast(set.data()) }; @@ -159,4 +150,9 @@ namespace OpenVulkano::Vulkan vk::PipelineLayoutCreateInfo plci = {{}, static_cast(descriptorSetLayouts.size()), descriptorSetLayouts.data(), static_cast(shader->pushConstantRanges.size()), pcRanges }; pipelineLayout = this->device.createPipelineLayout(plci); } + + void VulkanShader::Release() + { + if (owner) owner->RemoveShader(this); + } } diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp index af41830..738e0c2 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanShader.hpp @@ -7,26 +7,20 @@ #pragma once #include "IRecordable.hpp" -#include "Base/ICloseable.hpp" +#include "Scene/Shader/Shader.hpp" #include #include namespace OpenVulkano { - namespace Scene - { - class Shader; - } - namespace Vulkan { class Context; class IShaderOwner; - class VulkanShader final : public ICloseable, public IRecordable + class VulkanShader final : public IRenderResource, public IRecordable { public: - Scene::Shader* shader = nullptr; vk::Device device; std::vector shaderModules; // TODO manage live time somewhere else to allow sharing of shader programs std::vector shaderStageCreateInfo; @@ -36,17 +30,15 @@ namespace OpenVulkano IShaderOwner* owner = nullptr; Context* context = nullptr; - VulkanShader() = default; + VulkanShader(Context* context, Scene::Shader* shader, IShaderOwner* owner); ~VulkanShader() override; - void Init(Context* context, Scene::Shader* shader, IShaderOwner* owner); - void Resize(); void Record(VulkanDrawContext* context) override; - void Close() override; + void Release() override; private: void BuildPipeline(); diff --git a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp index 84e3530..c57aa81 100644 --- a/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp +++ b/openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp @@ -76,7 +76,7 @@ namespace OpenVulkano::Vulkan void Record(VulkanDrawContext* context) override { int setId = -1, i = 0; - for (const auto& descriptorSet : context->GetShader()->shader->descriptorSets) + for (const auto& descriptorSet : context->GetShader()->GetOwner()->descriptorSets) { for (const auto& descriptor : descriptorSet) { diff --git a/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp b/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp index bc02e80..935bdd5 100644 --- a/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp +++ b/openVulkanoCpp/Vulkan/VulkanDrawContext.cpp @@ -14,7 +14,7 @@ namespace OpenVulkano::Vulkan { void VulkanDrawContext::EncodeShader(Scene::Shader* shader) { - VulkanShader* vkShader = static_cast(shader->renderShader); + VulkanShader* vkShader = shader->GetRenderResource(); if (!vkShader) { vkShader = renderer->GetResourceManager().CreateShader(shader);