From 6da5165a99778c366c2ff95e8dbbc58975190161 Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 14:35:43 +0900 Subject: [PATCH 1/6] core --- src/graphics/core/core.cpp | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/graphics/core/core.cpp b/src/graphics/core/core.cpp index 759bdff..a5b6305 100644 --- a/src/graphics/core/core.cpp +++ b/src/graphics/core/core.cpp @@ -23,7 +23,7 @@ std::vector getInstanceLayers() { #endif } -vk::Instance createInstance() { +vk::UniqueInstance createInstance() { #ifdef __APPLE__ const auto flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR; #else @@ -39,7 +39,7 @@ vk::Instance createInstance() { .setPApplicationInfo(&ai) .setPEnabledExtensionNames(extensions) .setPEnabledLayerNames(layers); - return vk::createInstance(ci); + return vk::createInstanceUnique(ci); } vk::PhysicalDevice selectPhysicalDevice(const vk::Instance &instance) { @@ -64,7 +64,7 @@ uint32_t getQueueFamilyIndex(const vk::PhysicalDevice &physicalDevice) { return static_cast(std::distance(props.cbegin(), iter)); } -vk::Device createDevice(const vk::PhysicalDevice &physicalDevice, uint32_t queueFamilyIndex) { +vk::UniqueDevice createDevice(const vk::PhysicalDevice &physicalDevice, uint32_t queueFamilyIndex) { #ifdef __APPLE__ const std::array extensions{"VK_KHR_swapchain", "VK_KHR_portability_subset"}; #else @@ -77,7 +77,7 @@ vk::Device createDevice(const vk::PhysicalDevice &physicalDevice, uint32_t queue const auto ci = vk::DeviceCreateInfo() .setQueueCreateInfos(qci) .setPEnabledExtensionNames(extensions); - return physicalDevice.createDevice(ci); + return physicalDevice.createDeviceUnique(ci); } } // namespace @@ -85,12 +85,12 @@ vk::Device createDevice(const vk::PhysicalDevice &physicalDevice, uint32_t queue namespace graphics::core { struct Core { - const vk::Instance instance; + const vk::UniqueInstance instance; const vk::PhysicalDevice physicalDevice; const uint32_t queueFamilyIndex; - const vk::Device device; + const vk::UniqueDevice device; const vk::Queue queue; - const vk::CommandPool commandPool; + const vk::UniqueCommandPool commandPool; Core(const Core &) = delete; Core(const Core &&) = delete; @@ -99,23 +99,16 @@ struct Core { Core(): instance(createInstance()), - physicalDevice(selectPhysicalDevice(instance)), + physicalDevice(selectPhysicalDevice(instance.get())), queueFamilyIndex(getQueueFamilyIndex(physicalDevice)), device(createDevice(physicalDevice, queueFamilyIndex)), - queue(device.getQueue(queueFamilyIndex, 0)), - commandPool(device.createCommandPool( + queue(device->getQueue(queueFamilyIndex, 0)), + commandPool(device->createCommandPoolUnique( vk::CommandPoolCreateInfo() .setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer) .setQueueFamilyIndex(queueFamilyIndex) )) {} - - ~Core() { - device.waitIdle(); - device.destroy(commandPool); - device.destroy(); - instance.destroy(); - } }; std::optional g_core; @@ -139,7 +132,7 @@ void destroyCore() noexcept { const vk::Instance &instance() { ensureCoreInitialized(); - return g_core->instance; + return g_core->instance.get(); } const vk::PhysicalDevice &physicalDevice() { @@ -149,7 +142,7 @@ const vk::PhysicalDevice &physicalDevice() { const vk::Device &device() { ensureCoreInitialized(); - return g_core->device; + return g_core->device.get(); } const vk::Queue &queue() { @@ -159,7 +152,7 @@ const vk::Queue &queue() { const vk::CommandPool &commandPool() { ensureCoreInitialized(); - return g_core->commandPool; + return g_core->commandPool.get(); } } // namespace graphics::core From 973921eac5184c5ec896525ee2053e2518940189 Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 14:46:05 +0900 Subject: [PATCH 2/6] renderer --- src/graphics/renderer/renderer.cpp | 58 ++++++++++++++---------------- src/graphics/renderer/renderer.hpp | 9 +++-- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/graphics/renderer/renderer.cpp b/src/graphics/renderer/renderer.cpp index 4cde788..932a9e2 100644 --- a/src/graphics/renderer/renderer.cpp +++ b/src/graphics/renderer/renderer.cpp @@ -7,50 +7,46 @@ namespace graphics::renderer { -vk::CommandBuffer createCommandBuffer() { +vk::UniqueCommandBuffer createCommandBuffer() { const auto ai = vk::CommandBufferAllocateInfo() .setCommandPool(core::commandPool()) .setLevel(vk::CommandBufferLevel::ePrimary) .setCommandBufferCount(1); - return error::at(core::device().allocateCommandBuffers(ai), 0, "command buffers allocated"); + auto commandBuffers = core::device().allocateCommandBuffersUnique(ai); + if (commandBuffers.empty()) { + throw "failed to allocate a command buffer."; + } + return std::move(commandBuffers[0]); } -std::vector createSemaphores() { +std::vector createSemaphores() { const auto count = window::swapchain().getImages().size(); - std::vector semaphores; + std::vector semaphores; semaphores.reserve(count); for (size_t i = 0; i < count; ++i) { - semaphores.push_back(core::device().createSemaphore({})); + semaphores.push_back(core::device().createSemaphoreUnique({})); } return semaphores; } Renderer::Renderer(): _commandBuffer(createCommandBuffer()), - _semaphoreForImageEnabled(core::device().createSemaphore({})), + _semaphoreForImageEnabled(core::device().createSemaphoreUnique({})), _semaphoreForRenderFinisheds(createSemaphores()), - _frameInFlightFence(core::device().createFence({vk::FenceCreateFlagBits::eSignaled})) + _frameInFlightFence(core::device().createFenceUnique({vk::FenceCreateFlagBits::eSignaled})) {} -Renderer::~Renderer() { - core::device().destroy(_frameInFlightFence); - for (const auto &n: _semaphoreForRenderFinisheds) { - core::device().destroy(n); - } - core::device().destroy(_semaphoreForImageEnabled); -} - void Renderer::begin() { _context.reset(); - const auto index = window::swapchain().acquireNextImageIndex(_semaphoreForImageEnabled); + const auto index = window::swapchain().acquireNextImageIndex(_semaphoreForImageEnabled.get()); - _commandBuffer.reset(); + _commandBuffer->reset(); const auto cbi = vk::CommandBufferBeginInfo() .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - _commandBuffer.begin(cbi); + _commandBuffer->begin(cbi); - _context.emplace(index, _commandBuffer); + _context.emplace(index, _commandBuffer.get()); } void Renderer::end() { @@ -59,9 +55,9 @@ void Renderer::end() { } // TODO: レンダーパス終了忘れも検知したい。 - _commandBuffer.end(); + _commandBuffer->end(); - core::device().resetFences({_frameInFlightFence}); + core::device().resetFences({_frameInFlightFence.get()}); const vk::PipelineStageFlags waitStage = vk::PipelineStageFlagBits::eColorAttachmentOutput; const auto &semaphore = error::at( @@ -70,16 +66,16 @@ void Renderer::end() { "semaphores for waiting for rendering finished" ); const auto si = vk::SubmitInfo() - .setWaitSemaphores({_semaphoreForImageEnabled}) + .setWaitSemaphores({_semaphoreForImageEnabled.get()}) .setWaitDstStageMask({waitStage}) - .setCommandBuffers({_commandBuffer}) - .setSignalSemaphores({semaphore}); - core::queue().submit(si, _frameInFlightFence); + .setCommandBuffers({_commandBuffer.get()}) + .setSignalSemaphores({semaphore.get()}); + core::queue().submit(si, _frameInFlightFence.get()); - window::swapchain().present(semaphore, _context->currentIndex()); + window::swapchain().present(semaphore.get(), _context->currentIndex()); // 前のフレームのGPU処理が完全に終了するまで待機 - if (core::device().waitForFences({_frameInFlightFence}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { + if (core::device().waitForFences({_frameInFlightFence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { throw "failed to wait for rendering comletion."; } @@ -88,18 +84,16 @@ void Renderer::end() { } void Renderer::reset() { - _commandBuffer.reset(); + _commandBuffer->reset(); _context.reset(); text::clearLayoutContext(); for (auto &n: _semaphoreForRenderFinisheds) { - core::device().destroySemaphore(n); - n = core::device().createSemaphore({}); + n = core::device().createSemaphoreUnique({}); } } void Renderer::recreateSemaphoreForImageEnabled() { - core::device().destroy(_semaphoreForImageEnabled); - _semaphoreForImageEnabled = core::device().createSemaphore({}); + _semaphoreForImageEnabled = core::device().createSemaphoreUnique({}); } std::optional g_renderer; diff --git a/src/graphics/renderer/renderer.hpp b/src/graphics/renderer/renderer.hpp index 852deed..9b488c8 100644 --- a/src/graphics/renderer/renderer.hpp +++ b/src/graphics/renderer/renderer.hpp @@ -10,22 +10,21 @@ class Renderer { private: /// 描画処理コマンド用のコマンドバッファ /// orgeは描画完了まで待機するので1個で十分 - const vk::CommandBuffer _commandBuffer; + const vk::UniqueCommandBuffer _commandBuffer; /// スワップチェインイメージ取得の完了を知るためのセマフォ /// コマンドバッファ提出を待機させるために使う - vk::Semaphore _semaphoreForImageEnabled; + vk::UniqueSemaphore _semaphoreForImageEnabled; /// コマンドバッファ実行の完了を知るためのセマフォ /// プレゼンテーション開始を待機させるために使う - std::vector _semaphoreForRenderFinisheds; + std::vector _semaphoreForRenderFinisheds; /// フレーム完了を監視するフェンス /// 次フレーム開始前にGPU処理完了を待機するために使う - const vk::Fence _frameInFlightFence; + const vk::UniqueFence _frameInFlightFence; /// レンダリング中の必要な情報をまとめたもの std::optional _context; public: Renderer(); - ~Renderer(); RenderContext &getContext() { if (_context) { From 3edc98aa8d1500873b385cfe34e266bbb40f2d7f Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 17:32:43 +0900 Subject: [PATCH 3/6] renderpass --- src/graphics/renderpass/framebuffer.cpp | 9 ++-- src/graphics/renderpass/framebuffer.hpp | 5 ++- src/graphics/renderpass/pipeline-text.cpp | 49 +++++++++++----------- src/graphics/renderpass/pipeline-text.hpp | 5 +++ src/graphics/renderpass/pipeline-user.cpp | 43 +++++++++---------- src/graphics/renderpass/pipeline-utils.hpp | 4 +- src/graphics/renderpass/pipeline.cpp | 22 ++++------ src/graphics/renderpass/pipeline.hpp | 23 +++++----- src/graphics/renderpass/renderpass.cpp | 31 +++++--------- src/graphics/renderpass/renderpass.hpp | 5 +-- 10 files changed, 94 insertions(+), 102 deletions(-) diff --git a/src/graphics/renderpass/framebuffer.cpp b/src/graphics/renderpass/framebuffer.cpp index 498741e..ab3260d 100644 --- a/src/graphics/renderpass/framebuffer.cpp +++ b/src/graphics/renderpass/framebuffer.cpp @@ -7,10 +7,13 @@ namespace graphics::renderpass { -std::vector createFramebuffers(const vk::RenderPass &renderPass, const std::string renderPassId) { +std::vector createFramebuffers( + const vk::RenderPass &renderPass, + const std::string &renderPassId +) { const auto &swapchain = window::swapchain(); - std::vector framebuffers; + std::vector framebuffers; framebuffers.reserve(swapchain.getImages().size()); for (size_t i = 0; i < swapchain.getImages().size(); ++i) { @@ -29,7 +32,7 @@ std::vector createFramebuffers(const vk::RenderPass &renderPass .setWidth(extent.width) .setHeight(extent.height) .setLayers(1); - framebuffers.push_back(core::device().createFramebuffer(ci)); + framebuffers.push_back(core::device().createFramebufferUnique(ci)); } return framebuffers; diff --git a/src/graphics/renderpass/framebuffer.hpp b/src/graphics/renderpass/framebuffer.hpp index f0b9cb1..025b02c 100644 --- a/src/graphics/renderpass/framebuffer.hpp +++ b/src/graphics/renderpass/framebuffer.hpp @@ -4,6 +4,9 @@ namespace graphics::renderpass { -std::vector createFramebuffers(const vk::RenderPass &renderPass, const std::string renderPassId); +std::vector createFramebuffers( + const vk::RenderPass &renderPass, + const std::string &renderPassId +); } // namespace graphics::renderpass diff --git a/src/graphics/renderpass/pipeline-text.cpp b/src/graphics/renderpass/pipeline-text.cpp index c0b9aa3..590d26a 100644 --- a/src/graphics/renderpass/pipeline-text.cpp +++ b/src/graphics/renderpass/pipeline-text.cpp @@ -25,8 +25,8 @@ void createTextRenderingPipeline( const auto fspi = vk::SpecializationInfo(1, &fspme, sizeof(uint32_t), &fontCount); std::vector shaderStages; shaderStages.reserve(2); - shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vs, "main"); - shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fs, "main", &fspi); + shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vs.get(), "main"); + shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fs.get(), "main", &fspi); // 頂点入力 std::vector viads; @@ -73,7 +73,7 @@ void createTextRenderingPipeline( .setAttachments(cbass); // ディスクリプタセットレイアウト - std::vector descSetLayouts; + std::vector descSetLayouts; descSetLayouts.reserve(2); std::vector bindings; bindings.reserve(2); @@ -84,7 +84,7 @@ void createTextRenderingPipeline( vk::ShaderStageFlagBits::eVertex, nullptr ); - descSetLayouts.push_back(device.createDescriptorSetLayout( + descSetLayouts.push_back(device.createDescriptorSetLayoutUnique( vk::DescriptorSetLayoutCreateInfo().setBindings(bindings) )); bindings.clear(); @@ -102,34 +102,38 @@ void createTextRenderingPipeline( vk::ShaderStageFlagBits::eFragment, nullptr ); - descSetLayouts.push_back(device.createDescriptorSetLayout( + descSetLayouts.push_back(device.createDescriptorSetLayoutUnique( vk::DescriptorSetLayoutCreateInfo().setBindings(bindings) )); - // パイプラインレイアウト - const auto plci = vk::PipelineLayoutCreateInfo() - .setSetLayouts(descSetLayouts); - const auto pipelineLayout = device.createPipelineLayout(plci); - // ディスクリプタセット確保 - std::vector> descSets; - descSets.reserve(2); + std::vector> descSetss; + descSetss.reserve(2); std::vector layouts; layouts.reserve(1); - layouts.push_back(descSetLayouts[0]); - descSets.push_back(device.allocateDescriptorSets( + layouts.push_back(descSetLayouts[0].get()); + descSetss.push_back(device.allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo() .setDescriptorPool(resource::descpool()) .setSetLayouts(layouts) )); layouts.clear(); - layouts.push_back(descSetLayouts[1]); - descSets.push_back(device.allocateDescriptorSets( + layouts.push_back(descSetLayouts[1].get()); + descSetss.push_back(device.allocateDescriptorSetsUnique( vk::DescriptorSetAllocateInfo() .setDescriptorPool(resource::descpool()) .setSetLayouts(layouts) )); + // パイプラインレイアウト + std::vector rawDescSetLayouts; + for (const auto& m: descSetLayouts) { + rawDescSetLayouts.push_back(m.get()); + } + const auto plci = vk::PipelineLayoutCreateInfo() + .setSetLayouts(rawDescSetLayouts); + auto pipelineLayout = device.createPipelineLayoutUnique(plci); + // 他 const auto viewportState = createPipelineViewStateCreateInfo(); const auto multisampleState = createPipelineMultisampleStateCreateInfo(); @@ -147,25 +151,22 @@ void createTextRenderingPipeline( .setPMultisampleState(&multisampleState) .setPDepthStencilState(&depthStencilState) .setPColorBlendState(&colorBlendState) - .setLayout(pipelineLayout) + .setLayout(pipelineLayout.get()) .setRenderPass(renderPass) .setSubpass(subpassIndex) ); - const auto createds = device.createGraphicsPipelines(nullptr, cis).value; + auto createds = device.createGraphicsPipelinesUnique(nullptr, cis).value; if (createds.empty()) { throw "failed to create a text rendering pipeline."; } - core::device().destroy(vs); - core::device().destroy(fs); - pipelines.try_emplace( subpassIndex, "@text@", - createds[0], - pipelineLayout, + std::move(createds[0]), + std::move(pipelineLayout), std::move(descSetLayouts), - std::move(descSets) + std::move(descSetss) ); } diff --git a/src/graphics/renderpass/pipeline-text.hpp b/src/graphics/renderpass/pipeline-text.hpp index b32920d..74f2820 100644 --- a/src/graphics/renderpass/pipeline-text.hpp +++ b/src/graphics/renderpass/pipeline-text.hpp @@ -4,6 +4,11 @@ namespace graphics::renderpass { +// NOTE: 本当はGraphicsPipelinesを返したいが、 +// unordered_mapでemplaceできなくてデストラクタが呼ばれてしまうので、 +// 仕方なく最後の引数に格納先を渡す。 +// ムーブコンストラクタ定義したりunique_ptrで管理すれば解決するんだけど、 +// なんか嫌だ。 void createTextRenderingPipeline( const vk::RenderPass &renderPass, uint32_t subpassIndex, diff --git a/src/graphics/renderpass/pipeline-user.cpp b/src/graphics/renderpass/pipeline-user.cpp index 8f95c1c..94a6701 100644 --- a/src/graphics/renderpass/pipeline-user.cpp +++ b/src/graphics/renderpass/pipeline-user.cpp @@ -28,8 +28,8 @@ void createGraphicsPipeline( const auto fs = createShaderModule(fsRaw.data(), fsRaw.size()); std::vector shaderStages; shaderStages.reserve(2); - shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vs, "main"); - shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fs, "main"); + shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eVertex, vs.get(), "main"); + shaderStages.emplace_back(vk::PipelineShaderStageCreateFlags(), vk::ShaderStageFlagBits::eFragment, fs.get(), "main"); // 頂点入力 std::vector viads; @@ -95,7 +95,7 @@ void createGraphicsPipeline( .setAttachments(cbass); // ディスクリプタセットレイアウト - std::vector descSetLayouts; + std::vector descSetLayouts; descSetLayouts.reserve(n.descSets.size()); for (const auto &m: n.descSets) { std::vector bindings; @@ -110,27 +110,31 @@ void createGraphicsPipeline( } const auto ci = vk::DescriptorSetLayoutCreateInfo() .setBindings(bindings); - descSetLayouts.push_back(device.createDescriptorSetLayout(ci)); + descSetLayouts.push_back(device.createDescriptorSetLayoutUnique(ci)); } - // パイプラインレイアウト - const auto plci = vk::PipelineLayoutCreateInfo() - .setSetLayouts(descSetLayouts); - const auto pipelineLayout = device.createPipelineLayout(plci); - // ディスクリプタセット確保 - std::vector> descSets; - descSets.reserve(n.descSets.size()); + std::vector> descSetss; + descSetss.reserve(n.descSets.size()); for (size_t i = 0; i < n.descSets.size(); ++i) { std::vector layouts; for (size_t j = 0; j < n.descSets[i].count; ++j) { - layouts.push_back(descSetLayouts[i]); + layouts.push_back(descSetLayouts[i].get()); } const auto ai = vk::DescriptorSetAllocateInfo() .setDescriptorPool(resource::descpool()) .setSetLayouts(layouts); - descSets.push_back(device.allocateDescriptorSets(ai)); + descSetss.push_back(device.allocateDescriptorSetsUnique(ai)); + } + + // パイプラインレイアウト + std::vector rawDescSetLayouts; + for (const auto& m: descSetLayouts) { + rawDescSetLayouts.push_back(m.get()); } + const auto plci = vk::PipelineLayoutCreateInfo() + .setSetLayouts(rawDescSetLayouts); + auto pipelineLayout = device.createPipelineLayoutUnique(plci); // 他 const auto viewportState = createPipelineViewStateCreateInfo(); @@ -149,25 +153,22 @@ void createGraphicsPipeline( .setPMultisampleState(&multisampleState) .setPDepthStencilState(&depthStencilState) .setPColorBlendState(&colorBlendState) - .setLayout(pipelineLayout) + .setLayout(pipelineLayout.get()) .setRenderPass(renderPass) .setSubpass(subpassIndex) ); - const auto createds = device.createGraphicsPipelines(nullptr, cis).value; + auto createds = device.createGraphicsPipelinesUnique(nullptr, cis).value; if (createds.empty()) { throw std::format("failed to create a pipeline, '{}'.", pipelineId); } - core::device().destroy(vs); - core::device().destroy(fs); - pipelines.try_emplace( pipelineId, pipelineId, - createds[0], - pipelineLayout, + std::move(createds[0]), + std::move(pipelineLayout), std::move(descSetLayouts), - std::move(descSets) + std::move(descSetss) ); } diff --git a/src/graphics/renderpass/pipeline-utils.hpp b/src/graphics/renderpass/pipeline-utils.hpp index c3fdc29..327c018 100644 --- a/src/graphics/renderpass/pipeline-utils.hpp +++ b/src/graphics/renderpass/pipeline-utils.hpp @@ -44,14 +44,14 @@ inline vk::PipelineMultisampleStateCreateInfo createPipelineMultisampleStateCrea .setRasterizationSamples(vk::SampleCountFlagBits::e1); } -inline vk::ShaderModule createShaderModule(const unsigned char *data, size_t length) { +inline vk::UniqueShaderModule createShaderModule(const unsigned char *data, size_t length) { const auto code = std::vector( reinterpret_cast(data), reinterpret_cast(data + length) ); const auto ci = vk::ShaderModuleCreateInfo() .setCode(code); - return core::device().createShaderModule(ci); + return core::device().createShaderModuleUnique(ci); } } // namespace graphics::renderpass diff --git a/src/graphics/renderpass/pipeline.cpp b/src/graphics/renderpass/pipeline.cpp index c8c241e..eb75614 100644 --- a/src/graphics/renderpass/pipeline.cpp +++ b/src/graphics/renderpass/pipeline.cpp @@ -13,23 +13,15 @@ namespace graphics::renderpass { -GraphicsPipeline::~GraphicsPipeline() { - for (const auto &n: _descSetLayouts) { - core::device().destroyDescriptorSetLayout(n); - } - core::device().destroyPipelineLayout(_pipelineLayout); - core::device().destroyPipeline(_pipeline); -} - void GraphicsPipeline::bindDescriptorSets(const vk::CommandBuffer &commandBuffer, uint32_t const *indices) const { std::vector sets; sets.reserve(_descSets.size()); for (size_t i = 0; i < _descSets.size(); ++i) { - sets.push_back(error::at(_descSets[i], indices[i], "descriptor sets allocated")); + sets.push_back(error::at(_descSets[i], indices[i], "descriptor sets allocated").get()); } commandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, - _pipelineLayout, + _pipelineLayout.get(), 0, static_cast(sets.size()), sets.data(), @@ -53,7 +45,7 @@ DECLARE_UPDATE_DESC_METHOD(updateBufferDescriptor) { const auto &buffer = resource::getBuffer(id); const auto bi = vk::DescriptorBufferInfo(buffer.get(), 0, vk::WholeSize); const auto ds = vk::WriteDescriptorSet() - .setDstSet(descSet) + .setDstSet(descSet.get()) .setDstBinding(binding) .setDstArrayElement(offset) .setDescriptorCount(1) @@ -68,7 +60,7 @@ DECLARE_UPDATE_DESC_METHOD(updateUserImageDescriptor) { const auto &image = resource::getUserImage(id); const auto ii = vk::DescriptorImageInfo(nullptr, image.get(), vk::ImageLayout::eShaderReadOnlyOptimal); const auto ds = vk::WriteDescriptorSet() - .setDstSet(descSet) + .setDstSet(descSet.get()) .setDstBinding(binding) .setDstArrayElement(offset) .setDescriptorCount(1) @@ -83,7 +75,7 @@ DECLARE_UPDATE_DESC_METHOD(updateSamplerDescriptor) { const auto &sampler = resource::getSampler(id); const auto ii = vk::DescriptorImageInfo(sampler, nullptr, vk::ImageLayout::eShaderReadOnlyOptimal); const auto ds = vk::WriteDescriptorSet() - .setDstSet(descSet) + .setDstSet(descSet.get()) .setDstBinding(binding) .setDstArrayElement(offset) .setDescriptorCount(1) @@ -113,7 +105,7 @@ void GraphicsPipeline::updateInputAttachmentDescriptor( const auto &image = resource::getAttachmentImage(frameIndex, id); const auto ii = vk::DescriptorImageInfo(nullptr, image.get(), vk::ImageLayout::eShaderReadOnlyOptimal); const auto ds = vk::WriteDescriptorSet() - .setDstSet(descSet) + .setDstSet(descSet.get()) .setDstBinding(binding) .setDstArrayElement(offset) .setDescriptorCount(1) @@ -132,7 +124,7 @@ void GraphicsPipeline::updateCharatlusDescriptors() const { const auto ii = vk::DescriptorImageInfo(nullptr, n.get(), vk::ImageLayout::eShaderReadOnlyOptimal); sets.push_back( vk::WriteDescriptorSet() - .setDstSet(descSet) + .setDstSet(descSet.get()) .setDstBinding(0) .setDstArrayElement(offset) .setDescriptorCount(1) diff --git a/src/graphics/renderpass/pipeline.hpp b/src/graphics/renderpass/pipeline.hpp index 6538855..15a0350 100644 --- a/src/graphics/renderpass/pipeline.hpp +++ b/src/graphics/renderpass/pipeline.hpp @@ -8,10 +8,10 @@ namespace graphics::renderpass { class GraphicsPipeline { private: const std::string _id; - const vk::Pipeline _pipeline; - const vk::PipelineLayout _pipelineLayout; - const std::vector _descSetLayouts; - const std::vector> _descSets; + const vk::UniquePipeline _pipeline; + const vk::UniquePipelineLayout _pipelineLayout; + const std::vector _descSetLayouts; + const std::vector> _descSets; public: GraphicsPipeline() = delete; @@ -20,25 +20,24 @@ class GraphicsPipeline { GraphicsPipeline( const std::string &id, - const vk::Pipeline &pipeline, - const vk::PipelineLayout &pipelineLayout, - const std::vector &&descSetLayouts, - const std::vector> &&descSets + vk::UniquePipeline &&pipeline, + vk::UniquePipelineLayout &&pipelineLayout, + std::vector &&descSetLayouts, + std::vector> &&descSets ): _id(id), - _pipeline(pipeline), - _pipelineLayout(pipelineLayout), + _pipeline(std::move(pipeline)), + _pipelineLayout(std::move(pipelineLayout)), _descSetLayouts(std::move(descSetLayouts)), _descSets(std::move(descSets)) {} - ~GraphicsPipeline(); const std::string &id() const noexcept { return _id; } void bind(const vk::CommandBuffer &commandBuffer) const noexcept { - commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, _pipeline); + commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, _pipeline.get()); } void bindDescriptorSets(const vk::CommandBuffer &commandBuffer, uint32_t const *indices) const; diff --git a/src/graphics/renderpass/renderpass.cpp b/src/graphics/renderpass/renderpass.cpp index a0dd745..6d346ae 100644 --- a/src/graphics/renderpass/renderpass.cpp +++ b/src/graphics/renderpass/renderpass.cpp @@ -10,7 +10,7 @@ namespace graphics::renderpass { -vk::RenderPass createRenderPass(const std::string &id) { +vk::UniqueRenderPass createRenderPass(const std::string &id) { const auto &rpconfig = config::config().renderPasses.at(id); const auto &swapchain = window::swapchain(); @@ -60,7 +60,7 @@ vk::RenderPass createRenderPass(const std::string &id) { .setAttachments(attachments) .setSubpasses(subpasses) .setDependencies(dependencies); - return core::device().createRenderPass(ci); + return core::device().createRenderPassUnique(ci); } std::vector collectClearValues(const std::string &id) { @@ -82,42 +82,31 @@ RenderPass::RenderPass(const std::string &id): _id(id), _renderPass(createRenderPass(id)), _clearValues(collectClearValues(id)), - _framebuffers(createFramebuffers(_renderPass, id)), - _pipelines(createPipelines(_renderPass, _id)), - _trPipelines(createTextRenderingPipelines(_renderPass, _id)) + _framebuffers(createFramebuffers(_renderPass.get(), id)), + _pipelines(createPipelines(_renderPass.get(), _id)), + _trPipelines(createTextRenderingPipelines(_renderPass.get(), _id)) {} -RenderPass::~RenderPass() { - _pipelines.clear(); - for (const auto &n: _framebuffers) { - core::device().destroy(n); - } - core::device().destroy(_renderPass); -} - void RenderPass::begin(const vk::CommandBuffer &commandBuffer, uint32_t index) const noexcept { const auto &extent = window::swapchain().getExtent(); const auto rbi = vk::RenderPassBeginInfo() - .setRenderPass(_renderPass) - .setFramebuffer(_framebuffers[index]) + .setRenderPass(_renderPass.get()) + .setFramebuffer(_framebuffers[index].get()) .setRenderArea(vk::Rect2D({0, 0}, extent)) .setClearValues(_clearValues); commandBuffer.beginRenderPass(rbi, vk::SubpassContents::eInline); } void RenderPass::destroyFramebuffersAndPipelines() noexcept { - for (const auto &n: _framebuffers) { - core::device().destroy(n); - } _framebuffers.clear(); _pipelines.clear(); _trPipelines.clear(); } void RenderPass::createFramebuffersAndPipelines() { - _framebuffers = createFramebuffers(_renderPass, _id); - _pipelines = createPipelines(_renderPass, _id); - _trPipelines = createTextRenderingPipelines(_renderPass, _id); + _framebuffers = createFramebuffers(_renderPass.get(), _id); + _pipelines = createPipelines(_renderPass.get(), _id); + _trPipelines = createTextRenderingPipelines(_renderPass.get(), _id); } std::unordered_map g_renderPasses; diff --git a/src/graphics/renderpass/renderpass.hpp b/src/graphics/renderpass/renderpass.hpp index 7481dd5..861d951 100644 --- a/src/graphics/renderpass/renderpass.hpp +++ b/src/graphics/renderpass/renderpass.hpp @@ -11,9 +11,9 @@ namespace graphics::renderpass { class RenderPass { private: const std::string _id; - const vk::RenderPass _renderPass; + const vk::UniqueRenderPass _renderPass; const std::vector _clearValues; - std::vector _framebuffers; + std::vector _framebuffers; std::unordered_map _pipelines; std::unordered_map _trPipelines; @@ -23,7 +23,6 @@ class RenderPass { RenderPass &operator =(const RenderPass &) = delete; RenderPass(const std::string &id); - ~RenderPass(); const std::string &id() const noexcept { return _id; From 328265c57d3858e7a77f4256c87e1af196bd4dab Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 20:33:23 +0900 Subject: [PATCH 4/6] resource --- src/graphics/resource/buffer.cpp | 9 +-- src/graphics/resource/buffer.hpp | 13 ++--- src/graphics/resource/descpool.cpp | 7 +-- src/graphics/resource/image.hpp | 4 +- src/graphics/resource/mesh.cpp | 19 ++----- src/graphics/resource/mesh.hpp | 13 ++--- src/graphics/resource/sampler.cpp | 10 +--- src/graphics/utils.cpp | 88 +++++++++++++++--------------- src/graphics/utils.hpp | 6 +- 9 files changed, 74 insertions(+), 95 deletions(-) diff --git a/src/graphics/resource/buffer.cpp b/src/graphics/resource/buffer.cpp index c07eb24..6b45736 100644 --- a/src/graphics/resource/buffer.cpp +++ b/src/graphics/resource/buffer.cpp @@ -11,25 +11,20 @@ namespace graphics::resource { Buffer::Buffer(uint64_t size, bool isStorage, bool isHostCoherent): _isStorage(isStorage), _size(static_cast(size)), - _buffer(core::device().createBuffer( + _buffer(core::device().createBufferUnique( vk::BufferCreateInfo() .setSize(size) .setUsage(_isStorage ? vk::BufferUsageFlagBits::eStorageBuffer : vk::BufferUsageFlagBits::eUniformBuffer) .setSharingMode(vk::SharingMode::eExclusive) )), _memory(allocateMemory( - _buffer, + _buffer.get(), isHostCoherent ? vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent : vk::MemoryPropertyFlagBits::eHostVisible )) {} -Buffer::~Buffer() { - core::device().free(_memory); - core::device().destroy(_buffer); -} - std::unordered_map g_buffers; void destroyAllBuffers() noexcept { diff --git a/src/graphics/resource/buffer.hpp b/src/graphics/resource/buffer.hpp index 901589a..4af1908 100644 --- a/src/graphics/resource/buffer.hpp +++ b/src/graphics/resource/buffer.hpp @@ -8,8 +8,8 @@ class Buffer { private: const bool _isStorage; const vk::DeviceSize _size; - const vk::Buffer _buffer; - const vk::DeviceMemory _memory; + const vk::UniqueBuffer _buffer; + const vk::UniqueDeviceMemory _memory; public: Buffer() = delete; @@ -17,10 +17,9 @@ class Buffer { Buffer &operator =(const Buffer &) = delete; Buffer(uint64_t size, bool isStorage, bool isHostCoherent); - ~Buffer(); const vk::Buffer &get() const noexcept { - return _buffer; + return _buffer.get(); } bool isStorage() const noexcept { @@ -29,17 +28,17 @@ class Buffer { template void update(const T *data) const { - copyDataToMemory(_memory, data, _size); + copyDataToMemory(_memory.get(), data, _size); } template void update(const T *data, size_t size, size_t offset) const { - copyDataToMemory(_memory, data, size, offset); + copyDataToMemory(_memory.get(), data, size, offset); } template void copyTo(T *data) const { - copyMemotyToData(data, _memory, _size); + copyMemotyToData(data, _memory.get(), _size); } }; diff --git a/src/graphics/resource/descpool.cpp b/src/graphics/resource/descpool.cpp index 8cfc6ab..8b8c206 100644 --- a/src/graphics/resource/descpool.cpp +++ b/src/graphics/resource/descpool.cpp @@ -6,7 +6,7 @@ namespace graphics::resource { -std::optional g_descpool; +std::optional g_descpool; void initializeDescriptorPool() { if (g_descpool) { @@ -75,19 +75,18 @@ void initializeDescriptorPool() { .setFlags(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet) .setMaxSets(maxSets) .setPoolSizes(poolSizes); - g_descpool = core::device().createDescriptorPool(ci); + g_descpool = core::device().createDescriptorPoolUnique(ci); } void destroyDescriptorPool() noexcept { if (g_descpool) { - core::device().destroy(g_descpool.value()); g_descpool.reset(); } } const vk::DescriptorPool &descpool() { if (g_descpool) { - return g_descpool.value(); + return g_descpool.value().get(); } else { throw "descriptor pool not initialized."; } diff --git a/src/graphics/resource/image.hpp b/src/graphics/resource/image.hpp index a97d7f4..f92617b 100644 --- a/src/graphics/resource/image.hpp +++ b/src/graphics/resource/image.hpp @@ -12,9 +12,7 @@ class Image { const uint32_t _chCount; public: - // Image() = delete; - // Image(const Image &) = delete; - // Image &operator =(const Image &) = delete; + Image() = delete; Image( const vk::Image &image, diff --git a/src/graphics/resource/mesh.cpp b/src/graphics/resource/mesh.cpp index 515b7be..6a875d7 100644 --- a/src/graphics/resource/mesh.cpp +++ b/src/graphics/resource/mesh.cpp @@ -25,40 +25,33 @@ const std::span getIndicesData(const std::string &id) { Mesh::Mesh(const std::string &id): _id(id), _iCount(static_cast(getIndicesData(id).size() / sizeof(uint32_t))), - _vb(core::device().createBuffer( + _vb(core::device().createBufferUnique( vk::BufferCreateInfo() .setSize(static_cast(getVerticesData(id).size())) .setUsage(vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst) )), - _ib(core::device().createBuffer( + _ib(core::device().createBufferUnique( vk::BufferCreateInfo() .setSize(static_cast(getIndicesData(id).size())) .setUsage(vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst) )), - _vbMemory(allocateMemory(_vb, vk::MemoryPropertyFlagBits::eDeviceLocal)), - _ibMemory(allocateMemory(_ib, vk::MemoryPropertyFlagBits::eDeviceLocal)) + _vbMemory(allocateMemory(_vb.get(), vk::MemoryPropertyFlagBits::eDeviceLocal)), + _ibMemory(allocateMemory(_ib.get(), vk::MemoryPropertyFlagBits::eDeviceLocal)) { uploadBuffer( - _vb, + _vb.get(), static_cast(getVerticesData(id).data()), getVerticesData(id).size(), vk::PipelineStageFlagBits::eVertexShader ); uploadBuffer( - _ib, + _ib.get(), static_cast(getIndicesData(id).data()), getIndicesData(id).size(), vk::PipelineStageFlagBits::eVertexShader ); } -Mesh::~Mesh() { - core::device().free(_ibMemory); - core::device().free(_vbMemory); - core::device().destroy(_ib); - core::device().destroy(_vb); -} - std::unordered_map g_meshes; void destroyAllMeshes() noexcept { diff --git a/src/graphics/resource/mesh.hpp b/src/graphics/resource/mesh.hpp index 467194a..d6d2ffb 100644 --- a/src/graphics/resource/mesh.hpp +++ b/src/graphics/resource/mesh.hpp @@ -8,10 +8,10 @@ class Mesh { private: const std::string &_id; const uint32_t _iCount; - const vk::Buffer _vb; - const vk::Buffer _ib; - const vk::DeviceMemory _vbMemory; - const vk::DeviceMemory _ibMemory; + const vk::UniqueBuffer _vb; + const vk::UniqueBuffer _ib; + const vk::UniqueDeviceMemory _vbMemory; + const vk::UniqueDeviceMemory _ibMemory; public: Mesh() = delete; @@ -19,7 +19,6 @@ class Mesh { Mesh &operator =(const Mesh &) = delete; Mesh(const std::string &id); - ~Mesh(); const std::string &id() const noexcept { return _id; @@ -31,8 +30,8 @@ class Mesh { void bind(const vk::CommandBuffer &commandBuffer) const noexcept { const VkDeviceSize offset = 0; - commandBuffer.bindVertexBuffers(0, 1, &_vb, &offset); - commandBuffer.bindIndexBuffer(_ib, offset, vk::IndexType::eUint32); + commandBuffer.bindVertexBuffers(0, 1, &_vb.get(), &offset); + commandBuffer.bindIndexBuffer(_ib.get(), offset, vk::IndexType::eUint32); } }; diff --git a/src/graphics/resource/sampler.cpp b/src/graphics/resource/sampler.cpp index cea41e2..2a27785 100644 --- a/src/graphics/resource/sampler.cpp +++ b/src/graphics/resource/sampler.cpp @@ -7,12 +7,9 @@ namespace graphics::resource { -std::unordered_map g_samplers; +std::unordered_map g_samplers; void destroyAllSamplers() noexcept { - for (const auto &[_, n]: g_samplers) { - core::device().destroy(n); - } g_samplers.clear(); } @@ -20,7 +17,7 @@ void addSampler(const std::string &id, bool linearMagFilter, bool linearMinFilte if (g_samplers.contains(id)) { throw std::format("sampler '{}' already created.", id); } - g_samplers.emplace(id, core::device().createSampler( + g_samplers.emplace(id, core::device().createSamplerUnique( vk::SamplerCreateInfo() .setMagFilter(linearMagFilter ? vk::Filter::eLinear : vk::Filter::eNearest) .setMinFilter(linearMinFilter ? vk::Filter::eLinear : vk::Filter::eNearest) @@ -33,13 +30,12 @@ void addSampler(const std::string &id, bool linearMagFilter, bool linearMinFilte void destroySampler(const std::string &id) noexcept { if (g_samplers.contains(id)) { - core::device().destroy(g_samplers[id]); g_samplers.erase(id); } } const vk::Sampler &getSampler(const std::string &id) { - return error::at(g_samplers, id, "samplers"); + return error::at(g_samplers, id, "samplers").get(); } } // namespace graphics::resource diff --git a/src/graphics/utils.cpp b/src/graphics/utils.cpp index c18ee9f..a5e18ec 100644 --- a/src/graphics/utils.cpp +++ b/src/graphics/utils.cpp @@ -1,20 +1,20 @@ #include "utils.hpp" -#include "../error/error.hpp" +#include namespace graphics { -vk::CommandBuffer g_commandBuffer; -vk::Fence g_fence; +std::optional g_commandBuffer; +std::optional g_fence; void terminateUtils() { if (g_fence) { - core::device().destroyFence(g_fence); - g_fence = nullptr; + g_fence.reset(); + } + if (g_commandBuffer) { + // NOTE: コマンドプール全体を破棄するので個別に解放する必要はない。 + g_commandBuffer.reset(); } - - // NOTE: コマンドプール全体を破棄するので個別に解放する必要はない。 - g_commandBuffer = nullptr; } void initializeUtils() { @@ -22,30 +22,36 @@ void initializeUtils() { .setCommandPool(core::commandPool()) .setLevel(vk::CommandBufferLevel::ePrimary) .setCommandBufferCount(1); - g_commandBuffer = error::at(core::device().allocateCommandBuffers(ai), 0, "command buffers allocated"); + auto commandBuffers = core::device().allocateCommandBuffersUnique(ai); + if (commandBuffers.empty()) { + throw "failed to allocate a command buffer for utility."; + } + g_commandBuffer = std::move(commandBuffers[0]); - g_fence = core::device().createFence({}); + g_fence = core::device().createFenceUnique({}); } void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::PipelineStageFlags visibleStages) { const auto &device = core::device(); + const auto &fence = g_fence.value(); + const auto &commandBuffer = g_commandBuffer.value(); // ステージングバッファ作成 const auto bci = vk::BufferCreateInfo() .setSize(static_cast(size)) .setUsage(vk::BufferUsageFlagBits::eTransferSrc) .setSharingMode(vk::SharingMode::eExclusive); - const auto buffer = device.createBuffer(bci); - const auto bufferMemory = allocateMemory(buffer, vk::MemoryPropertyFlagBits::eHostVisible); + const auto buffer = device.createBufferUnique(bci); + const auto bufferMemory = allocateMemory(buffer.get(), vk::MemoryPropertyFlagBits::eHostVisible); // ステージングバッファへアップロード - copyDataToMemory(bufferMemory, src, size); + copyDataToMemory(bufferMemory.get(), src, size); // アップロード準備 - g_commandBuffer.reset(); + commandBuffer->reset(); const auto cbi = vk::CommandBufferBeginInfo() .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - g_commandBuffer.begin(cbi); + commandBuffer->begin(cbi); // メモリバリア (undegined -> transferDstOptimal) const auto bmb = vk::BufferMemoryBarrier( @@ -57,7 +63,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel 0, size ); - g_commandBuffer.pipelineBarrier( + commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlags(), @@ -68,7 +74,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel // アップロード const auto cr = vk::BufferCopy(0, 0, size); - g_commandBuffer.copyBuffer(buffer, dst, {cr}); + commandBuffer->copyBuffer(buffer.get(), dst, {cr}); // メモリバリア (transferDstOptimal -> shaderReadOnlyOptimal) const auto amb = vk::BufferMemoryBarrier( @@ -80,7 +86,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel 0, size ); - g_commandBuffer.pipelineBarrier( + commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, visibleStages, vk::DependencyFlags(), @@ -90,20 +96,16 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel ); // アップロード提出 - g_commandBuffer.end(); - device.resetFences({g_fence}); + commandBuffer->end(); + device.resetFences({fence.get()}); const auto si = vk::SubmitInfo() - .setCommandBuffers({g_commandBuffer}); - core::queue().submit(si, g_fence); + .setCommandBuffers({commandBuffer.get()}); + core::queue().submit(si, fence.get()); // 完了まで待機 - if (device.waitForFences({g_fence}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { + if (device.waitForFences({fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { throw "failed to wait for uploading a buffer."; } - - // ステージングバッファ削除 - device.free(bufferMemory); - device.destroy(buffer); } void uploadImage( @@ -116,6 +118,8 @@ void uploadImage( const uint8_t *src ) { const auto &device = core::device(); + const auto &fence = g_fence.value(); + const auto &commandBuffer = g_commandBuffer.value(); const auto extent = vk::Extent3D(width, height, 1); const auto subresRange = vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1); @@ -125,17 +129,17 @@ void uploadImage( .setSize(bufferSize) .setUsage(vk::BufferUsageFlagBits::eTransferSrc) .setSharingMode(vk::SharingMode::eExclusive); - const auto buffer = device.createBuffer(bci); - const auto bufferMemory = allocateMemory(buffer, vk::MemoryPropertyFlagBits::eHostVisible); + const auto buffer = device.createBufferUnique(bci); + const auto bufferMemory = allocateMemory(buffer.get(), vk::MemoryPropertyFlagBits::eHostVisible); // ステージングバッファへアップロード - copyDataToMemory(bufferMemory, src, bufferSize); + copyDataToMemory(bufferMemory.get(), src, bufferSize); // アップロード準備 - g_commandBuffer.reset(); + commandBuffer->reset(); const auto cbi = vk::CommandBufferBeginInfo() .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - g_commandBuffer.begin(cbi); + commandBuffer->begin(cbi); // メモリバリア (undegined -> transferDstOptimal) const auto bmb = vk::ImageMemoryBarrier( @@ -148,7 +152,7 @@ void uploadImage( dst, subresRange ); - g_commandBuffer.pipelineBarrier( + commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlags(), @@ -162,7 +166,7 @@ void uploadImage( .setImageSubresource(vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1)) .setImageOffset(vk::Offset3D(offsetX, offsetY, 0)) .setImageExtent(extent); - g_commandBuffer.copyBufferToImage(buffer, dst, vk::ImageLayout::eTransferDstOptimal, {cr}); + commandBuffer->copyBufferToImage(buffer.get(), dst, vk::ImageLayout::eTransferDstOptimal, {cr}); // メモリバリア (transferDstOptimal -> shaderReadOnlyOptimal) const auto amb = vk::ImageMemoryBarrier( @@ -175,7 +179,7 @@ void uploadImage( dst, subresRange ); - g_commandBuffer.pipelineBarrier( + commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, vk::DependencyFlags(), @@ -185,20 +189,16 @@ void uploadImage( ); // アップロード提出 - g_commandBuffer.end(); - device.resetFences({g_fence}); + commandBuffer->end(); + device.resetFences({fence.get()}); const auto si = vk::SubmitInfo() - .setCommandBuffers({g_commandBuffer}); - core::queue().submit(si, g_fence); + .setCommandBuffers({commandBuffer.get()}); + core::queue().submit(si, fence.get()); // 完了まで待機 - if (device.waitForFences({g_fence}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { + if (device.waitForFences({fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { throw "failed to wait for uploading an image."; } - - // ステージングバッファ削除 - device.free(bufferMemory); - device.destroy(buffer); } } // namespace graphics diff --git a/src/graphics/utils.hpp b/src/graphics/utils.hpp index 1337685..1a573d9 100644 --- a/src/graphics/utils.hpp +++ b/src/graphics/utils.hpp @@ -26,12 +26,12 @@ inline uint32_t findMemoryType(uint32_t typeBits, vk::MemoryPropertyFlags mask) return result; } -inline vk::DeviceMemory allocateMemory(const vk::Buffer &buffer, vk::MemoryPropertyFlags mask) { +inline vk::UniqueDeviceMemory allocateMemory(const vk::Buffer &buffer, vk::MemoryPropertyFlags mask) { const auto &device = core::device(); const auto reqs = device.getBufferMemoryRequirements(buffer); const auto type = findMemoryType(reqs.memoryTypeBits, mask); - const auto memory = device.allocateMemory(vk::MemoryAllocateInfo(reqs.size, type)); - device.bindBufferMemory(buffer, memory, 0); + auto memory = device.allocateMemoryUnique(vk::MemoryAllocateInfo(reqs.size, type)); + device.bindBufferMemory(buffer, memory.get(), 0); return memory; } From dcc6a562c8e8455ffe80005ad55cf45183d9e9b4 Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 20:35:05 +0900 Subject: [PATCH 5/6] refacto --- src/graphics/utils.cpp | 60 ++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/src/graphics/utils.cpp b/src/graphics/utils.cpp index a5e18ec..efb6ad2 100644 --- a/src/graphics/utils.cpp +++ b/src/graphics/utils.cpp @@ -1,20 +1,14 @@ #include "utils.hpp" -#include - namespace graphics { -std::optional g_commandBuffer; -std::optional g_fence; +vk::UniqueCommandBuffer g_commandBuffer; +vk::UniqueFence g_fence; void terminateUtils() { - if (g_fence) { - g_fence.reset(); - } - if (g_commandBuffer) { - // NOTE: コマンドプール全体を破棄するので個別に解放する必要はない。 - g_commandBuffer.reset(); - } + g_fence.reset(); + // NOTE: コマンドプール全体を破棄するので個別に解放する必要はない。 + g_commandBuffer.reset(); } void initializeUtils() { @@ -33,8 +27,6 @@ void initializeUtils() { void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::PipelineStageFlags visibleStages) { const auto &device = core::device(); - const auto &fence = g_fence.value(); - const auto &commandBuffer = g_commandBuffer.value(); // ステージングバッファ作成 const auto bci = vk::BufferCreateInfo() @@ -48,10 +40,10 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel copyDataToMemory(bufferMemory.get(), src, size); // アップロード準備 - commandBuffer->reset(); + g_commandBuffer->reset(); const auto cbi = vk::CommandBufferBeginInfo() .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - commandBuffer->begin(cbi); + g_commandBuffer->begin(cbi); // メモリバリア (undegined -> transferDstOptimal) const auto bmb = vk::BufferMemoryBarrier( @@ -63,7 +55,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel 0, size ); - commandBuffer->pipelineBarrier( + g_commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlags(), @@ -74,7 +66,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel // アップロード const auto cr = vk::BufferCopy(0, 0, size); - commandBuffer->copyBuffer(buffer.get(), dst, {cr}); + g_commandBuffer->copyBuffer(buffer.get(), dst, {cr}); // メモリバリア (transferDstOptimal -> shaderReadOnlyOptimal) const auto amb = vk::BufferMemoryBarrier( @@ -86,7 +78,7 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel 0, size ); - commandBuffer->pipelineBarrier( + g_commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, visibleStages, vk::DependencyFlags(), @@ -96,14 +88,14 @@ void uploadBuffer(const vk::Buffer &dst, const void *src, size_t size, vk::Pipel ); // アップロード提出 - commandBuffer->end(); - device.resetFences({fence.get()}); + g_commandBuffer->end(); + device.resetFences({g_fence.get()}); const auto si = vk::SubmitInfo() - .setCommandBuffers({commandBuffer.get()}); - core::queue().submit(si, fence.get()); + .setCommandBuffers({g_commandBuffer.get()}); + core::queue().submit(si, g_fence.get()); // 完了まで待機 - if (device.waitForFences({fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { + if (device.waitForFences({g_fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { throw "failed to wait for uploading a buffer."; } } @@ -118,8 +110,6 @@ void uploadImage( const uint8_t *src ) { const auto &device = core::device(); - const auto &fence = g_fence.value(); - const auto &commandBuffer = g_commandBuffer.value(); const auto extent = vk::Extent3D(width, height, 1); const auto subresRange = vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1); @@ -136,10 +126,10 @@ void uploadImage( copyDataToMemory(bufferMemory.get(), src, bufferSize); // アップロード準備 - commandBuffer->reset(); + g_commandBuffer->reset(); const auto cbi = vk::CommandBufferBeginInfo() .setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); - commandBuffer->begin(cbi); + g_commandBuffer->begin(cbi); // メモリバリア (undegined -> transferDstOptimal) const auto bmb = vk::ImageMemoryBarrier( @@ -152,7 +142,7 @@ void uploadImage( dst, subresRange ); - commandBuffer->pipelineBarrier( + g_commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlags(), @@ -166,7 +156,7 @@ void uploadImage( .setImageSubresource(vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1)) .setImageOffset(vk::Offset3D(offsetX, offsetY, 0)) .setImageExtent(extent); - commandBuffer->copyBufferToImage(buffer.get(), dst, vk::ImageLayout::eTransferDstOptimal, {cr}); + g_commandBuffer->copyBufferToImage(buffer.get(), dst, vk::ImageLayout::eTransferDstOptimal, {cr}); // メモリバリア (transferDstOptimal -> shaderReadOnlyOptimal) const auto amb = vk::ImageMemoryBarrier( @@ -179,7 +169,7 @@ void uploadImage( dst, subresRange ); - commandBuffer->pipelineBarrier( + g_commandBuffer->pipelineBarrier( vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, vk::DependencyFlags(), @@ -189,14 +179,14 @@ void uploadImage( ); // アップロード提出 - commandBuffer->end(); - device.resetFences({fence.get()}); + g_commandBuffer->end(); + device.resetFences({g_fence.get()}); const auto si = vk::SubmitInfo() - .setCommandBuffers({commandBuffer.get()}); - core::queue().submit(si, fence.get()); + .setCommandBuffers({g_commandBuffer.get()}); + core::queue().submit(si, g_fence.get()); // 完了まで待機 - if (device.waitForFences({fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { + if (device.waitForFences({g_fence.get()}, VK_TRUE, UINT64_MAX) != vk::Result::eSuccess) { throw "failed to wait for uploading an image."; } } From 8a3768d033e7c6aed54143088e03618da4c3b629 Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Thu, 18 Sep 2025 21:44:38 +0900 Subject: [PATCH 6/6] swapchain --- src/graphics/window/swapchain.cpp | 39 +++++++++++++------------------ src/graphics/window/swapchain.hpp | 5 ++-- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/graphics/window/swapchain.cpp b/src/graphics/window/swapchain.cpp index 11dabc3..3fc813d 100644 --- a/src/graphics/window/swapchain.cpp +++ b/src/graphics/window/swapchain.cpp @@ -32,10 +32,10 @@ Window createWindow() { return Window(window, SDL_DestroyWindow); } -vk::SurfaceKHR createSurface(const Window &window) { +vk::UniqueSurfaceKHR createSurface(const Window &window) { VkSurfaceKHR surface; if (SDL_Vulkan_CreateSurface(window.get(), core::instance(), NULL, &surface)) { - return static_cast(surface); + return vk::UniqueSurfaceKHR(surface, core::instance()); } else { throw std::format("failed to create a surface: {}", SDL_GetError()); } @@ -60,7 +60,7 @@ vk::Format getFormatFrom(const vk::SurfaceKHR &surface) { throw "the surface format and color space are invalid."; } -vk::SwapchainKHR createSwapchain( +vk::UniqueSwapchainKHR createSwapchain( const vk::SurfaceKHR &surface, const vk::Extent2D &extent, const vk::Format &format, @@ -81,7 +81,7 @@ vk::SwapchainKHR createSwapchain( .setPresentMode(config::config().disableVsync ? vk::PresentModeKHR::eImmediate : vk::PresentModeKHR::eFifo) .setClipped(vk::True) .setOldSwapchain(oldSwapchain); - return core::device().createSwapchainKHR(ci); + return core::device().createSwapchainKHRUnique(ci); } std::vector getImagesFrom(const vk::SurfaceKHR &surface, const vk::SwapchainKHR &swapchain) { @@ -100,35 +100,28 @@ Swapchain::Swapchain(): _height(config::config().height), _window(createWindow()), _surface(createSurface(_window)), - _extent(core::physicalDevice().getSurfaceCapabilitiesKHR(_surface).currentExtent), - _format(getFormatFrom(_surface)), - _swapchain(createSwapchain(_surface, _extent, _format)), - _images(getImagesFrom(_surface, _swapchain)) + _extent(core::physicalDevice().getSurfaceCapabilitiesKHR(_surface.get()).currentExtent), + _format(getFormatFrom(_surface.get())), + _swapchain(createSwapchain(_surface.get(), _extent, _format)), + _images(getImagesFrom(_surface.get(), _swapchain.get())) {} -Swapchain::~Swapchain() { - core::device().destroySwapchainKHR(_swapchain); - core::instance().destroySurfaceKHR(_surface); -} - void Swapchain::recreateSwapchain() { - const auto old = _swapchain; - _extent = core::physicalDevice().getSurfaceCapabilitiesKHR(_surface).currentExtent; - _format = getFormatFrom(_surface); - _swapchain = createSwapchain(_surface, _extent, _format, old); - _images = getImagesFrom(_surface, _swapchain); - core::device().destroySwapchainKHR(old); + const auto old = std::move(_swapchain); + _extent = core::physicalDevice().getSurfaceCapabilitiesKHR(_surface.get()).currentExtent; + _format = getFormatFrom(_surface.get()); + _swapchain = createSwapchain(_surface.get(), _extent, _format, old.get()); + _images = getImagesFrom(_surface.get(), _swapchain.get()); } void Swapchain::recreateSurface() { - const auto old = _surface; + const auto old = std::move(_surface); _surface = createSurface(_window); recreateSwapchain(); - core::instance().destroySurfaceKHR(old); } uint32_t Swapchain::acquireNextImageIndex(const vk::Semaphore &semaphore) { - const auto result = core::device().acquireNextImageKHR(_swapchain, UINT64_MAX, semaphore, nullptr); + const auto result = core::device().acquireNextImageKHR(_swapchain.get(), UINT64_MAX, semaphore, nullptr); if (result.result == vk::Result::eSuccess) { return result.value; } else { @@ -139,7 +132,7 @@ uint32_t Swapchain::acquireNextImageIndex(const vk::Semaphore &semaphore) { void Swapchain::present(const vk::Semaphore &semaphore, uint32_t index) const { const auto pi = vk::PresentInfoKHR() .setWaitSemaphores({semaphore}) - .setSwapchains({_swapchain}) + .setSwapchains({_swapchain.get()}) .setImageIndices({index}); if (core::queue().presentKHR(pi) != vk::Result::eSuccess) { throw "failed to present the screen."; diff --git a/src/graphics/window/swapchain.hpp b/src/graphics/window/swapchain.hpp index 948dd49..151a4d1 100644 --- a/src/graphics/window/swapchain.hpp +++ b/src/graphics/window/swapchain.hpp @@ -13,10 +13,10 @@ class Swapchain { const uint32_t _width; const uint32_t _height; const Window _window; - vk::SurfaceKHR _surface; + vk::UniqueSurfaceKHR _surface; vk::Extent2D _extent; vk::Format _format; - vk::SwapchainKHR _swapchain; + vk::UniqueSwapchainKHR _swapchain; std::vector _images; public: @@ -26,7 +26,6 @@ class Swapchain { Swapchain &operator=(const Swapchain &&) = delete; Swapchain(); - ~Swapchain(); const vk::Extent2D &getExtent() const noexcept { return _extent;