Skip to content

Commit

Permalink
MAINT: refactor Vulkan code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Odd Kiva committed Nov 27, 2023
1 parent 5166d84 commit 8b4eba4
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 73 deletions.
63 changes: 63 additions & 0 deletions cpp/examples/Shakti/Vulkan/hello_vulkan_image/Geometry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// ========================================================================== //
// This file is part of Sara, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2023 David Ok <[email protected]>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#pragma once

#include <vulkan/vulkan.h>

#include <Eigen/Core>

#include <vector>


struct Vertex
{
Eigen::Vector2f pos;
Eigen::Vector3f color;
Eigen::Vector2f uv;

static auto get_binding_description() -> VkVertexInputBindingDescription
{
VkVertexInputBindingDescription binding_description{};
binding_description.binding = 0;
binding_description.stride = sizeof(Vertex);
binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

return binding_description;
}

static auto get_attribute_descriptions()
-> std::vector<VkVertexInputAttributeDescription>
{
auto attribute_descriptions =
std::vector<VkVertexInputAttributeDescription>(3);

// Position
attribute_descriptions[0].binding = 0;
attribute_descriptions[0].location = 0;
attribute_descriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[0].offset = offsetof(Vertex, pos);

// Color
attribute_descriptions[1].binding = 0;
attribute_descriptions[1].location = 1;
attribute_descriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attribute_descriptions[1].offset = offsetof(Vertex, color);

// UV texture coords
attribute_descriptions[2].binding = 0;
attribute_descriptions[2].location = 2;
attribute_descriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[2].offset = offsetof(Vertex, uv);

return attribute_descriptions;
}
};
49 changes: 40 additions & 9 deletions cpp/examples/Shakti/Vulkan/hello_vulkan_image/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <DO/Shakti/Vulkan/DescriptorSet.hpp>
#include <DO/Shakti/Vulkan/DeviceMemory.hpp>
#include <DO/Shakti/Vulkan/EasyGLFW.hpp>
#include <DO/Shakti/Vulkan/Geometry.hpp>
#include <DO/Shakti/Vulkan/GraphicsBackend.hpp>

#include <DO/Sara/Core/DebugUtilities.hpp>
Expand All @@ -30,6 +29,8 @@
#include <limits>
#include <stdexcept>

#include "Geometry.hpp"


namespace glfw = DO::Kalpana::GLFW;
namespace kvk = DO::Kalpana::Vulkan;
Expand Down Expand Up @@ -92,10 +93,10 @@ struct ModelViewProjectionStack

// clang-format off
static const auto vertices = std::vector<Vertex>{
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{ 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
{{ 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.f, 0.f}},
{{ 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.f, 0.f}},
{{ 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.f, 1.f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.f, 1.f}}
};
// clang-format on

Expand All @@ -111,11 +112,20 @@ class VulkanImageRenderer : public kvk::GraphicsBackend
VulkanImageRenderer(GLFWwindow* window, const std::string& app_name,
const std::filesystem::path& shader_dirpath,
const bool debug_vulkan = true)
: kvk::GraphicsBackend{window, app_name, //
shader_dirpath / "vert.spv", //
shader_dirpath / "frag.spv", //
debug_vulkan}
{
init_instance(app_name, debug_vulkan);
init_surface(window);
init_physical_device();
init_device_and_queues();
init_swapchain(window);
init_render_pass();
init_framebuffers();
init_graphics_pipeline(window, //
shader_dirpath / "vert.spv",
shader_dirpath / "frag.spv");
init_command_pool_and_buffers();
init_synchronization_objects();

transfer_vertex_data_to_vulkan(vertices);
transfer_element_data_to_vulkan(indices);

Expand All @@ -124,6 +134,27 @@ class VulkanImageRenderer : public kvk::GraphicsBackend
initialize_model_view_projection_ubos();
}

auto init_graphics_pipeline(GLFWwindow* window, //
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path)
-> void override
{
auto w = int{};
auto h = int{};
glfwGetWindowSize(window, &w, &h);

_graphics_pipeline =
kvk::GraphicsPipeline::Builder{_device, _render_pass}
.vertex_shader_path(vertex_shader_path)
.fragment_shader_path(fragment_shader_path)
.vbo_data_format<Vertex>()
.input_assembly_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.viewport_sizes(static_cast<float>(w), static_cast<float>(h))
.scissor_sizes(w, h)
.create();
}


auto transfer_vertex_data_to_vulkan(const std::vector<Vertex>& vertices)
-> void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ struct Vertex
}

static auto get_attribute_descriptions()
-> std::array<VkVertexInputAttributeDescription, 2>
-> std::vector<VkVertexInputAttributeDescription>
{
auto attribute_descriptions =
std::array<VkVertexInputAttributeDescription, 2>{};
std::vector<VkVertexInputAttributeDescription>(2);

// Position
attribute_descriptions[0].binding = 0;
Expand Down
43 changes: 37 additions & 6 deletions cpp/examples/Shakti/Vulkan/hello_vulkan_triangle/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <DO/Shakti/Vulkan/DescriptorSet.hpp>
#include <DO/Shakti/Vulkan/DeviceMemory.hpp>
#include <DO/Shakti/Vulkan/EasyGLFW.hpp>
#include <DO/Shakti/Vulkan/Geometry.hpp>
#include <DO/Shakti/Vulkan/GraphicsBackend.hpp>

#include <DO/Sara/Core/DebugUtilities.hpp>
Expand All @@ -30,6 +29,8 @@
#include <limits>
#include <stdexcept>

#include "Geometry.hpp"


namespace glfw = DO::Kalpana::GLFW;
namespace kvk = DO::Kalpana::Vulkan;
Expand Down Expand Up @@ -111,11 +112,20 @@ class VulkanTriangleRenderer : public kvk::GraphicsBackend
VulkanTriangleRenderer(GLFWwindow* window, const std::string& app_name,
const std::filesystem::path& shader_dirpath,
const bool debug_vulkan = true)
: kvk::GraphicsBackend{window, app_name, //
shader_dirpath / "vert.spv", //
shader_dirpath / "frag.spv", //
debug_vulkan}
{
init_instance(app_name, debug_vulkan);
init_surface(window);
init_physical_device();
init_device_and_queues();
init_swapchain(window);
init_render_pass();
init_framebuffers();
init_graphics_pipeline(window, //
shader_dirpath / "vert.spv",
shader_dirpath / "frag.spv");
init_command_pool_and_buffers();
init_synchronization_objects();

transfer_vertex_data_to_vulkan(vertices);
transfer_element_data_to_vulkan(indices);

Expand All @@ -124,6 +134,26 @@ class VulkanTriangleRenderer : public kvk::GraphicsBackend
initialize_model_view_projection_ubos();
}

auto init_graphics_pipeline(GLFWwindow* window, //
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path)
-> void override
{
auto w = int{};
auto h = int{};
glfwGetWindowSize(window, &w, &h);

_graphics_pipeline =
kvk::GraphicsPipeline::Builder{_device, _render_pass}
.vertex_shader_path(vertex_shader_path)
.fragment_shader_path(fragment_shader_path)
.vbo_data_format<Vertex>()
.input_assembly_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.viewport_sizes(static_cast<float>(w), static_cast<float>(h))
.scissor_sizes(w, h)
.create();
}

auto transfer_vertex_data_to_vulkan(const std::vector<Vertex>& vertices)
-> void
{
Expand Down Expand Up @@ -626,7 +656,8 @@ auto main(int, char** argv) -> int

const auto program_dir_path = fs::absolute(fs::path(argv[0])).parent_path();
auto triangle_renderer = VulkanTriangleRenderer{
window, app_name, program_dir_path / "hello_vulkan_triangle_shaders", true};
window, app_name, program_dir_path / "hello_vulkan_triangle_shaders",
true};
triangle_renderer.loop(window);
}
catch (std::exception& e)
Expand Down
40 changes: 0 additions & 40 deletions cpp/src/DO/Shakti/Vulkan/GraphicsBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,13 @@
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#include <DO/Shakti/Vulkan/Geometry.hpp>
#include <DO/Shakti/Vulkan/GraphicsBackend.hpp>
#include <DO/Shakti/Vulkan/Semaphore.hpp>


using namespace DO::Kalpana::Vulkan;


GraphicsBackend::GraphicsBackend(
GLFWwindow* window, const std::string& app_name,
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path, //
const bool debug_vulkan)
{
init_instance(app_name, debug_vulkan);
init_surface(window);
init_physical_device();
init_device_and_queues();
init_swapchain(window);
init_render_pass();
init_framebuffers();
init_graphics_pipeline(window, vertex_shader_path, fragment_shader_path);
init_command_pool_and_buffers();
init_synchronization_objects();
}

auto GraphicsBackend::init_instance(const std::string& app_name,
const bool debug_vulkan) -> void
{
Expand Down Expand Up @@ -150,27 +131,6 @@ auto GraphicsBackend::init_render_pass() -> void
_render_pass.create_basic_render_pass(_device, _swapchain.image_format);
}

auto GraphicsBackend::init_graphics_pipeline(
GLFWwindow* window, //
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path) -> void
{
auto w = int{};
auto h = int{};
glfwGetWindowSize(window, &w, &h);

_graphics_pipeline =
GraphicsPipeline::Builder{_device, _render_pass}
.vertex_shader_path(vertex_shader_path)
.fragment_shader_path(fragment_shader_path)
// .vbo_data_built_in_vertex_shader()
.vbo_data_format<Vertex>()
.input_assembly_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.viewport_sizes(static_cast<float>(w), static_cast<float>(h))
.scissor_sizes(w, h)
.create();
}

auto GraphicsBackend::init_command_pool_and_buffers() -> void
{
namespace svk = Shakti::Vulkan;
Expand Down
9 changes: 3 additions & 6 deletions cpp/src/DO/Shakti/Vulkan/GraphicsBackend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ namespace DO::Kalpana::Vulkan {
static constexpr auto default_height = 600;

public:
GraphicsBackend(GLFWwindow* window, const std::string& app_name,
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path,
const bool debug_vulkan);
virtual ~GraphicsBackend() = default;

auto init_instance(const std::string& app_name, const bool debug_vulkan)
-> void;
Expand All @@ -64,11 +61,11 @@ namespace DO::Kalpana::Vulkan {

auto init_render_pass() -> void;

auto
virtual auto
init_graphics_pipeline(GLFWwindow* window, //
const std::filesystem::path& vertex_shader_path,
const std::filesystem::path& fragment_shader_path)
-> void;
-> void = 0;

auto init_command_pool_and_buffers() -> void;

Expand Down
3 changes: 1 addition & 2 deletions cpp/src/DO/Shakti/Vulkan/GraphicsPipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ namespace DO::Kalpana::Vulkan {
graphics_pipeline._mvp_layout =
Shakti::Vulkan::DescriptorSetLayout::Builder{device}
.push_uniform_buffer_layout_binding()
.push_image_sampler_layout_binding()
.create();

// Initialize the graphics pipeline layout.
Expand Down Expand Up @@ -431,7 +430,7 @@ namespace DO::Kalpana::Vulkan {

//! @brief Data format of the vertex in the vertex buffer.
VkVertexInputBindingDescription binding_description;
std::array<VkVertexInputAttributeDescription, 2> attribute_descriptions;
std::vector<VkVertexInputAttributeDescription> attribute_descriptions;
VkPipelineVertexInputStateCreateInfo vertex_input_info;

//! @brief Data type of the 3D geometry (typically triangles).
Expand Down
Loading

0 comments on commit 8b4eba4

Please sign in to comment.