]> git.seodisparate.com - blue_noise_generation/commitdiff
WIP vulkan compute: create compute pipeline, fixes
authorStephen Seo <seo.disparate@gmail.com>
Wed, 20 Mar 2024 02:54:38 +0000 (11:54 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 20 Mar 2024 02:54:38 +0000 (11:54 +0900)
Fix Cleanup class.

Implement setting up compute pipeline.

src/blue_noise.cpp
src/utility.cpp
src/utility.hpp

index 001ed09abf3e1071f8d0e394550a6e58053f6c51..eab89186979029a092381eb8ab5f8b4dd58d4a83 100644 (file)
@@ -343,6 +343,91 @@ image::Bl dither::blue_noise(int width, int height, int threads,
         goto ENDOF_VULKAN;
       }
     }
+
+    // Load shader.
+    std::vector<char> shader;
+    {
+      std::ifstream ifs("compute.spv");
+      if (!ifs.good()) {
+        std::clog << "WARNING: Failed to find compute.spv!\n";
+        goto ENDOF_VULKAN;
+      }
+      ifs.seekg(0, std::ios_base::end);
+      auto size = ifs.tellg();
+      shader.resize(size);
+
+      ifs.seekg(0);
+      ifs.read(shader.data(), size);
+      ifs.close();
+    }
+
+    // create compute pipeline.
+    VkPipelineLayout compute_pipeline_layout;
+    VkPipeline compute_pipeline;
+    utility::Cleanup cleanup_pipeline_layout(utility::Cleanup::Nop{});
+    utility::Cleanup cleanup_pipeline(utility::Cleanup::Nop{});
+    {
+      VkShaderModuleCreateInfo shader_module_create_info{};
+      shader_module_create_info.sType =
+          VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+      shader_module_create_info.codeSize = shader.size();
+      shader_module_create_info.pCode =
+          reinterpret_cast<const uint32_t *>(shader.data());
+
+      VkShaderModule compute_shader_module;
+      if (vkCreateShaderModule(device, &shader_module_create_info, nullptr,
+                               &compute_shader_module) != VK_SUCCESS) {
+        std::clog << "WARNING: Failed to create shader module!\n";
+        goto ENDOF_VULKAN;
+      }
+
+      utility::Cleanup cleanup_shader_module(
+          [device](void *ptr) {
+            vkDestroyShaderModule(device, *((VkShaderModule *)ptr), nullptr);
+          },
+          &compute_shader_module);
+
+      VkPipelineShaderStageCreateInfo compute_shader_stage_info{};
+      compute_shader_stage_info.sType =
+          VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+      compute_shader_stage_info.stage = VK_SHADER_STAGE_COMPUTE_BIT;
+      compute_shader_stage_info.module = compute_shader_module;
+      compute_shader_stage_info.pName = "main";
+
+      VkPipelineLayoutCreateInfo pipeline_layout_info{};
+      pipeline_layout_info.sType =
+          VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+      pipeline_layout_info.setLayoutCount = 1;
+      pipeline_layout_info.pSetLayouts = &compute_desc_set_layout;
+
+      if (vkCreatePipelineLayout(device, &pipeline_layout_info, nullptr,
+                                 &compute_pipeline_layout) != VK_SUCCESS) {
+        std::clog << "WARNING: Failed to create compute pipeline layout!\n";
+        goto ENDOF_VULKAN;
+      }
+      cleanup_pipeline_layout = utility::Cleanup(
+          [device](void *ptr) {
+            vkDestroyPipelineLayout(device, *((VkPipelineLayout *)ptr),
+                                    nullptr);
+          },
+          &compute_pipeline_layout);
+
+      VkComputePipelineCreateInfo pipeline_info{};
+      pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
+      pipeline_info.layout = compute_pipeline_layout;
+      pipeline_info.stage = compute_shader_stage_info;
+
+      if (vkCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipeline_info,
+                                   nullptr, &compute_pipeline) != VK_SUCCESS) {
+        std::clog << "WARNING: Failed to create compute pipeline!\n";
+        goto ENDOF_VULKAN;
+      }
+      cleanup_pipeline = utility::Cleanup(
+          [device](void *ptr) {
+            vkDestroyPipeline(device, *((VkPipeline *)ptr), nullptr);
+          },
+          &compute_pipeline);
+    }
   }
 ENDOF_VULKAN:
   std::clog << "TODO: Remove this once Vulkan support is implemented.\n";
index 58dbebb6069311835c19d4ea759932852aa0ee95..ea72296753f917615acef073797377fcc4d2ce85 100644 (file)
@@ -3,4 +3,29 @@
 utility::Cleanup::Cleanup(std::function<void(void *)> fn, void *ptr)
     : fn(fn), ptr(ptr) {}
 
-utility::Cleanup::~Cleanup() { this->fn(this->ptr); }
+utility::Cleanup::Cleanup(Nop) : fn(), ptr(nullptr) {}
+
+utility::Cleanup::~Cleanup() {
+  if (this->fn.has_value()) {
+    this->fn.value()(this->ptr);
+  }
+}
+
+utility::Cleanup::Cleanup(Cleanup &&other) : fn(other.fn), ptr(other.ptr) {
+  other.fn = std::nullopt;
+  other.ptr = nullptr;
+}
+
+utility::Cleanup &utility::Cleanup::operator=(utility::Cleanup &&other) {
+  if (this->fn.has_value()) {
+    this->fn.value()(this->ptr);
+  }
+
+  this->fn = other.fn;
+  this->ptr = other.ptr;
+
+  other.fn = std::nullopt;
+  other.ptr = nullptr;
+
+  return *this;
+}
index 6da17d9bf78f2bbe1e0b528fe9eec605ec59b4bf..fe152bdfe6ffcc21cdea416ff31d25cb17a86a50 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <cmath>
 #include <functional>
+#include <optional>
 #include <utility>
 
 namespace utility {
@@ -32,19 +33,22 @@ inline float dist(int a, int b, int width) {
 
 class Cleanup {
  public:
+  struct Nop {};
+
   Cleanup(std::function<void(void *)> fn, void *ptr);
+  Cleanup(Nop nop);
   ~Cleanup();
 
   // allow move
-  Cleanup(Cleanup &&) = default;
-  Cleanup &operator=(Cleanup &&) = default;
+  Cleanup(Cleanup &&);
+  Cleanup &operator=(Cleanup &&);
 
   // deny copy
   Cleanup(const Cleanup &) = delete;
   Cleanup &operator=(const Cleanup &) = delete;
 
  private:
-  std::function<void(void *)> fn;
+  std::optional<std::function<void(void *)>> fn;
   void *ptr;
 };
 }  // namespace utility