WIP vulkan compute: create compute pipeline, fixes

Fix Cleanup class.

Implement setting up compute pipeline.
This commit is contained in:
Stephen Seo 2024-03-20 11:54:38 +09:00
parent 8c1190d923
commit bc02b924e2
3 changed files with 118 additions and 4 deletions

View file

@ -343,6 +343,91 @@ image::Bl dither::blue_noise(int width, int height, int threads,
goto ENDOF_VULKAN; 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: ENDOF_VULKAN:
std::clog << "TODO: Remove this once Vulkan support is implemented.\n"; std::clog << "TODO: Remove this once Vulkan support is implemented.\n";

View file

@ -3,4 +3,29 @@
utility::Cleanup::Cleanup(std::function<void(void *)> fn, void *ptr) utility::Cleanup::Cleanup(std::function<void(void *)> fn, void *ptr)
: fn(fn), ptr(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;
}

View file

@ -3,6 +3,7 @@
#include <cmath> #include <cmath>
#include <functional> #include <functional>
#include <optional>
#include <utility> #include <utility>
namespace utility { namespace utility {
@ -32,19 +33,22 @@ inline float dist(int a, int b, int width) {
class Cleanup { class Cleanup {
public: public:
struct Nop {};
Cleanup(std::function<void(void *)> fn, void *ptr); Cleanup(std::function<void(void *)> fn, void *ptr);
Cleanup(Nop nop);
~Cleanup(); ~Cleanup();
// allow move // allow move
Cleanup(Cleanup &&) = default; Cleanup(Cleanup &&);
Cleanup &operator=(Cleanup &&) = default; Cleanup &operator=(Cleanup &&);
// deny copy // deny copy
Cleanup(const Cleanup &) = delete; Cleanup(const Cleanup &) = delete;
Cleanup &operator=(const Cleanup &) = delete; Cleanup &operator=(const Cleanup &) = delete;
private: private:
std::function<void(void *)> fn; std::optional<std::function<void(void *)>> fn;
void *ptr; void *ptr;
}; };
} // namespace utility } // namespace utility