wip: convert from include style to module import style :D

This commit is contained in:
light7734 2025-11-12 16:07:51 +03:30
parent 2f60b837c9
commit 018d19335d
Signed by: light7734
GPG key ID: 8C30176798F1A6BA
9 changed files with 1105 additions and 855 deletions

View file

@ -4,21 +4,23 @@ import math.vec3;
import memory.reference;
import std;
namespace lt::renderer::components {
export namespace lt::renderer::components {
export enum class VertexFormat: std::uint8_t {
enum class VertexFormat : std::uint8_t
{
r32_g32_b32_sfloat,
r32_g32_sfloat,
};
export enum class VertexInputRate: std::uint8_t {
enum class VertexInputRate : std::uint8_t
{
per_vertex,
per_instance,
};
export struct VertexInputAttributeDescriptipn
struct VertexInputAttributeDescriptipn
{
std::uint32_t location;
@ -29,7 +31,7 @@ export struct VertexInputAttributeDescriptipn
VertexFormat format;
};
export struct VertexInputBindingDescription
struct VertexInputBindingDescription
{
std::uint32_t binding;
@ -37,7 +39,7 @@ export struct VertexInputBindingDescription
};
/** Requires a math::components::Transform component on the same entity to be functional. */
export struct Sprite
struct Sprite
{
struct Vertex
{
@ -52,7 +54,7 @@ export struct Sprite
VertexInputAttributeDescriptipn {
.location = 0u,
.binding = 0u,
.offset = offsetof(Sprite::Vertex, position),
.offset = 0u,
.format = VertexFormat::r32_g32_b32_sfloat,
},
@ -60,7 +62,7 @@ export struct Sprite
VertexInputAttributeDescriptipn {
.location = 1u,
.binding = 0u,
.offset = offsetof(Sprite::Vertex, color),
.offset = sizeof(math::vec3),
.format = VertexFormat::r32_g32_b32_sfloat,
},
};

View file

@ -5,9 +5,11 @@ import renderer.backend.vk.device;
import renderer.vk.pass;
import renderer.backend.vk.instance;
import renderer.backend.vk.swapchain;
import renderer.vk.renderer;
import renderer.backend.vk.buffer;
import renderer.backend.vk.gpu;
import renderer.backend.vk.surface;
import renderer.vk.renderer;
import memory.scope;
import debug.assertions;
import ecs.entity;
@ -35,6 +37,14 @@ export namespace lt::renderer {
const lt::assets::ShaderAsset &fragment_shader
) -> memory::Scope<IPass>;
[[nodiscard]] auto create_renderer(
Api target_api,
IGpu *gpu,
IDevice *device,
ISwapchain *swapchain,
std::uint32_t max_frames_in_flight
) -> memory::Scope<IRenderer>
} // namespace lt::renderer
module :private;
@ -147,59 +157,62 @@ using namespace lt::renderer;
}
}
// [[nodiscard]] /* static */ auto IRenderer::create(
// Api target_api,
// IGpu *gpu,
// IDevice *device,
// ISwapchain *swapchain,
// uint32_t max_frames_in_flight
// ) -> memory::Scope<IRenderer>
// {
// ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
// ensure(device, "Failed to create renderer::IRenderer: null device");
// ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
// ensure(
// std::clamp(max_frames_in_flight, frames_in_flight_lower_limit, frames_in_flight_upper_limit)
// == max_frames_in_flight,
// "Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
// "{}) ",
// max_frames_in_flight,
// frames_in_flight_lower_limit,
// frames_in_flight_upper_limit
// );
//
//
// switch (target_api)
// {
// case Api::vulkan:
// return memory::create_scope<vk::Renderer>(gpu, device, swapchain, max_frames_in_flight);
// case Api::none:
// case Api::metal:
// case Api::direct_x: throw std::runtime_error { "Invalid API" };
// }
// }
[[nodiscard]] auto create_renderer(
Api target_api,
IGpu *gpu,
IDevice *device,
ISwapchain *swapchain,
std::uint32_t max_frames_in_flight
) -> memory::Scope<IRenderer>
{
debug::ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
debug::ensure(device, "Failed to create renderer::IRenderer: null device");
debug::ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
debug::ensure(
std::clamp(
max_frames_in_flight,
IRenderer::frames_in_flight_lower_limit,
IRenderer::frames_in_flight_upper_limit
) == max_frames_in_flight,
"Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
"{}) ",
max_frames_in_flight,
IRenderer::frames_in_flight_lower_limit,
IRenderer::frames_in_flight_upper_limit
);
// [[nodiscard]] /* static */ auto IDebugger::create(
// Api target_api,
// IInstance *instance,
// CreateInfo info
// ) -> memory::Scope<IDebugger>
// {
// debug::ensure(
// info.severities != MessageSeverity::none,
// "Failed to create vk::Messenger: severities == none"
// );
//
// debug::ensure(info.types != MessageType::none, "Failed to create vk::Messenger: types == none");
//
// debug::ensure(info.callback, "Failed to create vk::Messenger: null callback");
//
// switch (target_api)
// {
// case Api::vulkan: return memory::create_scope<vk::Messenger>(instance, std::move(info));
// case Api::none:
// case Api::metal:
// case Api::direct_x: throw std::runtime_error { "Invalid API" };
// }
// }
switch (target_api)
{
case Api::vulkan:
return memory::create_scope<vkb::Renderer>(gpu, device, swapchain, max_frames_in_flight);
case Api::none:
case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" };
}
}
[[nodiscard]] /* static */ auto IDebugger::create(
Api target_api,
IInstance *instance,
CreateInfo info
) -> memory::Scope<IDebugger>
{
debug::ensure(
info.severities != MessageSeverity::none,
"Failed to create vk::Messenger: severities == none"
);
debug::ensure(info.types != MessageType::none, "Failed to create vk::Messenger: types == none");
debug::ensure(info.callback, "Failed to create vk::Messenger: null callback");
switch (target_api)
{
case Api::vulkan: return memory::create_scope<vk::Messenger>(instance, std::move(info));
case Api::none:
case Api::metal:
case Api::direct_x: throw std::runtime_error { "Invalid API" };
}
}

View file

@ -1,4 +1,7 @@
export module renderer.frontend;
import renderer.data;
import renderer.components;
import math.components;
import assets.shader;
import ecs.entity;
import math.vec2;
@ -129,13 +132,6 @@ public:
std::size_t size;
};
[[nodiscard]] static auto create(
Api target_api,
class IDevice *device,
class IGpu *gpu,
const CreateInfo &info
) -> memory::Scope<IBuffer>;
IBuffer() = default;
virtual ~IBuffer() = default;
@ -160,13 +156,6 @@ private:
class IPass
{
public:
[[nodiscard]] static auto create(
lt::renderer::Api target_api,
class IDevice *device,
const class lt::assets::ShaderAsset &vertex_shader,
const class lt::assets::ShaderAsset &fragment_shader
) -> memory::Scope<IPass>;
IPass() = default;
virtual ~IPass() = default;
@ -180,52 +169,43 @@ public:
auto operator=(const IPass &) -> IPass & = delete;
};
// class IRenderer
// {
// public:
// static constexpr auto frames_in_flight_upper_limit = 5u;
//
// static constexpr auto frames_in_flight_lower_limit = 1u;
//
// enum class Result : uint8_t
// {
// success = 0,
// invalid_swapchain,
// error,
// };
//
// [[nodiscard]] static auto create(
// Api target_api,
// class IGpu *gpu,
// class IDevice *device,
// class ISwapchain *swapchain,
// uint32_t max_frames_in_flight
// ) -> memory::Scope<IRenderer>;
//
// IRenderer() = default;
//
// virtual ~IRenderer() = default;
//
// IRenderer(IRenderer &&) = default;
//
// IRenderer(const IRenderer &) = delete;
//
// auto operator=(IRenderer &&) -> IRenderer & = default;
//
// auto operator=(const IRenderer &) -> IRenderer & = delete;
//
// virtual auto frame(uint32_t frame_idx, std::function<void()> submit_scene) -> Result = 0;
//
// virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
//
// virtual void set_frame_constants(FrameConstants constants) = 0;
//
// virtual void submit_sprite(
// const components::Sprite &sprite,
// const math::components::Transform &transform
// ) = 0;
// };
class IRenderer
{
public:
static constexpr auto frames_in_flight_upper_limit = 5u;
static constexpr auto frames_in_flight_lower_limit = 1u;
enum class Result : std::uint8_t
{
success = 0,
invalid_swapchain,
error,
};
IRenderer() = default;
virtual ~IRenderer() = default;
IRenderer(IRenderer &&) = default;
IRenderer(const IRenderer &) = delete;
auto operator=(IRenderer &&) -> IRenderer & = default;
auto operator=(const IRenderer &) -> IRenderer & = delete;
virtual auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene) -> Result = 0;
virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
virtual void set_frame_constants(FrameConstants constants) = 0;
virtual void submit_sprite(
const components::Sprite &sprite,
const math::components::Transform &transform
) = 0;
};
// class IDebugger
// {

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,11 @@ public:
return m_size;
}
[[nodiscard]] auto vk() -> vk::Buffer &
{
return m_buffer;
}
private:
[[nodiscard]] auto determine_allocation_info(Usage usage) const -> vk::Memory::AllocateInfo;

View file

@ -27,6 +27,16 @@ public:
return { m_graphics_queue_family_index, m_present_queue_family_index };
}
[[nodiscard]] auto graphics_queue() -> vk::Queue &
{
return m_graphics_queue;
}
[[nodiscard]] auto present_queue() -> vk::Queue &
{
return m_present_queue;
}
private:
void initialize_physical_device();

View file

@ -1,5 +1,4 @@
export module renderer.vk.pass;
import renderer.data;
import renderer.backend.vk.library_wrapper;
import renderer.backend.vk.device;

View file

@ -1,84 +0,0 @@
#include <memory/pointer_types/null_on_move.hpp>
#include <renderer/backend/vk/context/device.hpp>
#include <renderer/backend/vk/context/instance.hpp>
#include <renderer/backend/vk/vulkan.hpp>
export namespace lt::renderer::vk::raii {
class DebugMessenger
{
public:
DebugMessenger(Instance *instance, VkDebugUtilsMessengerCreateInfoEXT info)
: m_instance(instance)
, m_object(m_instance->create_messenger(info))
{
}
~DebugMessenger()
{
if (m_instance)
{
m_instance->destroy_messenger(m_object);
}
}
DebugMessenger(DebugMessenger &&) = default;
DebugMessenger(const DebugMessenger &) = delete;
auto operator=(DebugMessenger &&) -> DebugMessenger & = default;
auto operator=(const DebugMessenger &) -> DebugMessenger & = delete;
private:
memory::NullOnMove<Instance *> m_instance {};
VkDebugUtilsMessengerEXT m_object;
};
class Memory
{
public:
Memory(Device *device, VkBuffer buffer, VkMemoryAllocateInfo info)
: m_device(device)
, m_object(m_device->allocate_memory(info))
{
m_device->bind_memory(buffer, m_object);
}
~Memory()
{
if (m_device)
{
m_device->free_memory(m_object);
}
}
Memory(Memory &&) = default;
Memory(const Memory &) = delete;
auto operator=(Memory &&) -> Memory & = default;
auto operator=(const Memory &) -> Memory & = delete;
[[nodiscard]] auto operator*() const -> VkDeviceMemory
{
return m_object;
}
[[nodiscard]] operator VkDeviceMemory() const
{
return m_object;
}
private:
memory::NullOnMove<Device *> m_device {};
VkDeviceMemory m_object = VK_NULL_HANDLE;
};
} // namespace lt::renderer::vk::raii

View file

@ -1,38 +1,33 @@
#pragma once
export module renderer.vk.renderer;
import assets.shader;
import debug.assertions;
import renderer.backend.vk.library_wrapper;
import memory.reference;
import memory.null_on_move;
import renderer.backend.vk.device;
import math.vec2;
import math.components;
import renderer.backend.vk.swapchain;
import renderer.components;
import renderer.backend.vk.buffer;
import renderer.vk.pass;
import renderer.data;
import renderer.frontend;
import std;
#include <memory/reference.hpp>
#include <ranges>
#include <renderer/backend/vk/context/device.hpp>
#include <renderer/backend/vk/data/buffer.hpp>
#include <renderer/backend/vk/renderer/pass.hpp>
#include <renderer/backend/vk/utils.hpp>
#include <renderer/frontend/data/buffer.hpp>
#include <renderer/frontend/renderer/pass.hpp>
#include <renderer/frontend/renderer/renderer.hpp>
namespace lt::renderer::vkb {
namespace lt::renderer::vk {
class Renderer: public IRenderer
export class Renderer: public IRenderer
{
public:
Renderer(
class IGpu *gpu,
class IDevice *device,
class ISwapchain *swapchain,
uint32_t max_frames_in_flight
std::uint32_t max_frames_in_flight
);
~Renderer() override;
Renderer(Renderer &&) = default;
Renderer(const Renderer &) = delete;
auto operator=(Renderer &&) -> Renderer & = default;
auto operator=(const Renderer &) -> Renderer & = delete;
[[nodiscard]] auto frame(uint32_t frame_idx, std::function<void()> submit_scene)
[[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
-> Result override;
void replace_swapchain(ISwapchain *swapchain) override;
@ -48,33 +43,29 @@ public:
) override;
private:
void record_cmd(VkCommandBuffer cmd, uint32_t image_idx);
void record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx);
void map_buffers(uint32_t frame_idx);
void map_buffers(std::uint32_t frame_idx);
void flush_buffers(VkCommandBuffer cmd);
std::uint32_t m_max_frames_in_flight {};
memory::NullOnMove<class Device *> m_device {};
memory::NullOnMove<Device *> m_device {};
class Swapchain *m_swapchain {};
Swapchain *m_swapchain {};
memory::Ref<class Pass> m_pass;
memory::Ref<Pass> m_pass;
VkCommandPool m_pool = VK_NULL_HANDLE;
vk::CommandPool m_pool;
VkCommandPool m_transient_pool = VK_NULL_HANDLE;
std::vector<vk::CommandBuffer> m_cmds;
std::vector<VkCommandBuffer> m_cmds;
std::vector<vk::Fence> m_frame_fences;
std::vector<VkFence> m_frame_fences;
std::vector<vk::Semaphore> m_acquire_image_semaphores;
std::vector<VkSemaphore> m_aquire_image_semaphores;
std::vector<vk::Semaphore> m_submit_semaphores;
std::vector<VkSemaphore> m_submit_semaphores;
VkExtent2D m_resolution;
uint32_t m_max_frames_in_flight {};
math::uvec2 m_resolution;
FrameConstants m_frame_constants;
@ -82,26 +73,27 @@ private:
Buffer m_staging_buffer;
size_t m_staging_offset;
std::size_t m_staging_offset;
std::span<std::byte> m_staging_map;
std::span<components::Sprite::Vertex> m_sprite_vertex_map;
size_t m_current_sprite_idx;
std::size_t m_current_sprite_idx;
};
} // namespace lt::renderer::vk
} // namespace lt::renderer::vkb
module :private;
using namespace lt::renderer;
using namespace lt::renderer::vkb;
#include <memory/reference.hpp>
#include <renderer/backend/vk/context/swapchain.hpp>
#include <renderer/backend/vk/renderer/renderer.hpp>
namespace lt::renderer::vk {
Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t max_frames_in_flight)
Renderer::Renderer(
IGpu *gpu,
IDevice *device,
ISwapchain *swapchain,
std::uint32_t max_frames_in_flight
)
: m_device(static_cast<Device *>(device))
, m_swapchain(static_cast<Swapchain *>(swapchain))
, m_resolution(m_swapchain->get_resolution())
@ -110,7 +102,7 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
, m_vertex_buffer(
device,
gpu,
IBuffer::CreateInfo {
{
.usage = IBuffer::Usage::vertex,
.size = 1'000'000,
.debug_name = "vertex buffer",
@ -119,91 +111,46 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
, m_staging_buffer(
device,
gpu,
IBuffer::CreateInfo {
{
.usage = IBuffer::Usage::staging,
.size = 1'000'000,
.debug_name = "staging buffer",
}
)
, m_pass(
memory::create_ref<Pass>(
m_device,
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
)
)
, m_pool(
m_device->vk(),
{
.flags = vk::CommandPool::CreateInfo::FlagBits::reset_command_buffer,
}
)
, m_cmds(m_pool.allocate(m_max_frames_in_flight, vk::CommandPool::BufferLevel::primary))
, m_acquire_image_semaphores(m_max_frames_in_flight)
, m_frame_fences(m_max_frames_in_flight)
, m_submit_semaphores(m_swapchain->get_image_count())
{
ensure(m_device, "Failed to initialize renderer: null device");
ensure(m_swapchain, "Failed to initialize renderer: null swapchain");
// TODO(Light): HARDCODED PASS!!!
m_pass = memory::create_ref<vk::Pass>(
m_device,
m_swapchain,
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
);
m_pool = m_device->create_command_pool(
VkCommandPoolCreateInfo {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = m_device->get_family_indices()[0],
}
);
m_transient_pool = m_device->create_command_pool(
VkCommandPoolCreateInfo {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
.queueFamilyIndex = m_device->get_family_indices()[0],
}
);
m_cmds.resize(m_max_frames_in_flight);
m_cmds = m_device->allocate_command_buffers(
VkCommandBufferAllocateInfo {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = m_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = static_cast<uint32_t>(m_cmds.size()),
}
);
m_aquire_image_semaphores = m_device->create_semaphores(m_max_frames_in_flight);
m_frame_fences = m_device->create_fences(
VkFenceCreateInfo {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
},
m_max_frames_in_flight
);
for (auto idx = 0u;
auto [semaphore, fence] : std::views::zip(m_aquire_image_semaphores, m_frame_fences))
for (auto [semaphore, fence] : std::views::zip(m_acquire_image_semaphores, m_frame_fences))
{
m_device->name(semaphore, "acquire image semaphore {}", idx);
m_device->name(fence, "frame fence {}", idx);
semaphore = vk::Semaphore(m_device->vk());
fence = vk::Fence(m_device->vk(), { .signaled = true });
}
m_submit_semaphores = m_device->create_semaphores(m_swapchain->get_image_count());
for (auto idx = 0u; auto &semaphore : m_submit_semaphores)
for (auto &semaphore : m_submit_semaphores)
{
m_device->name(semaphore, "submit semaphore {}", idx);
semaphore = vk::Semaphore(m_device->vk());
}
};
Renderer::~Renderer()
[[nodiscard]] auto Renderer::frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
-> Result
{
if (!m_device)
{
return;
}
m_device->wait_idle();
m_device->destroy_semaphores(m_aquire_image_semaphores);
m_device->destroy_semaphores(m_submit_semaphores);
m_device->destroy_fences(m_frame_fences);
m_device->destroy_command_pool(m_pool);
m_device->destroy_command_pool(m_transient_pool);
}
[[nodiscard]] auto Renderer::frame(uint32_t frame_idx, std::function<void()> submit_scene) -> Result
{
ensure(
debug::ensure(
frame_idx < m_max_frames_in_flight,
"Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})",
frame_idx,
@ -211,50 +158,33 @@ Renderer::~Renderer()
);
auto &frame_fence = m_frame_fences[frame_idx];
auto &aquire_semaphore = m_aquire_image_semaphores[frame_idx];
auto &acquire_semaphore = m_acquire_image_semaphores[frame_idx];
auto &cmd = m_cmds[frame_idx];
m_device->wait_for_fence(frame_fence);
auto image_idx = m_device->acquire_image(m_swapchain->vk(), aquire_semaphore);
if (!image_idx.has_value())
{
return Result::invalid_swapchain;
}
m_device->reset_fence(frame_fence);
frame_fence.wait();
const auto image_idx = m_swapchain->vk().acquire_image(acquire_semaphore);
frame_fence.reset();
map_buffers(frame_idx);
submit_scene();
record_cmd(cmd, *image_idx);
record_cmd(cmd, image_idx);
auto wait_stage = VkPipelineStageFlags { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
auto &submit_semaphore = m_submit_semaphores[*image_idx];
m_device->submit(
VkSubmitInfo {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = 1u,
.pWaitSemaphores = &aquire_semaphore,
.pWaitDstStageMask = &wait_stage,
.commandBufferCount = 1u,
.pCommandBuffers = &cmd,
.signalSemaphoreCount = 1u,
.pSignalSemaphores = &submit_semaphore,
},
frame_fence
auto &submit_semaphore = m_submit_semaphores[image_idx];
m_device->graphics_queue().submit(
vk::Queue::SubmitInfo {
.command_buffer = &cmd,
.wait_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.wait_semaphore = &acquire_semaphore,
.signal_semaphore = &submit_semaphore,
.signal_fence = &frame_fence,
}
);
// TODO(Light): handle result
auto result = VkResult {};
m_device->present(
VkPresentInfoKHR {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1u,
.pWaitSemaphores = &submit_semaphore,
.swapchainCount = 1u,
.pSwapchains = m_swapchain->vk_ptr(),
.pImageIndices = &image_idx.value(),
.pResults = &result,
m_device->present_queue().present(
vk::Queue::PresentInfo {
.wait_semaphore = &submit_semaphore,
.swapchain = &m_swapchain->vk(),
.image_idx = image_idx,
}
);
@ -263,13 +193,12 @@ Renderer::~Renderer()
void Renderer::replace_swapchain(ISwapchain *swapchain)
{
m_device->wait_idle();
m_device->vk().wait_idle();
m_swapchain = static_cast<Swapchain *>(swapchain);
m_resolution = m_swapchain->get_resolution();
m_pass->replace_swapchain(*swapchain);
}
void Renderer::map_buffers(uint32_t frame_idx)
void Renderer::map_buffers(std::uint32_t frame_idx)
{
using components::Sprite;
@ -286,140 +215,188 @@ void Renderer::map_buffers(uint32_t frame_idx)
);
}
void Renderer::flush_buffers(VkCommandBuffer cmd)
void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
{
// const auto cmd_begin_info = VkCommandBufferBeginInfo {
// .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
// .flags = {},
// .pInheritanceInfo = nullptr,
// };
// vk_reset_command_buffer(cmd, {});
// vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
// const auto begin_frame_barrier = VkImageMemoryBarrier {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .srcAccessMask = {},
// .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
// .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .image = m_swapchain->get_image(image_idx),
// .range = vk::Image::full_color_range,
// .subresourceRange = VkImageSubresourceRange{
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
// .baseMipLevel = 0u,
// .levelCount = VK_REMAINING_MIP_LEVELS,
// .baseArrayLayer = 0u,
// .layerCount = VK_REMAINING_ARRAY_LAYERS,
// },
// };
//
//
// vk_cmd_pipeline_barrier(
// cmd,
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// 0,
// 0,
// nullptr,
// 0,
// nullptr,
// 1,
// &begin_frame_barrier
// );
//
// const auto end_frame_barrier = VkImageMemoryBarrier {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
// VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = {}, .oldLayout =
// VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
// .image = m_swapchain->get_image(image_idx),
//
// .subresourceRange = VkImageSubresourceRange{
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
// .baseMipLevel = 0u,
// .levelCount = VK_REMAINING_MIP_LEVELS,
// .baseArrayLayer = 0u,
// .layerCount = VK_REMAINING_ARRAY_LAYERS,
// },
// };
// vk_cmd_pipeline_barrier(
// cmd,
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
// 0,
// 0,
// nullptr,
// 0,
// nullptr,
// 1,
// &end_frame_barrier
// );
// const auto scissor = VkRect2D {
// .offset = { .x = 0u, .y = 0u },
// .extent = m_resolution,
// };
// const auto viewport = VkViewport {
// .x = 0.0f,
// .y = 0.0f,
// .width = static_cast<float>(m_resolution.width),
// .height = static_cast<float>(m_resolution.height),
// .minDepth = 0.0f,
// .maxDepth = 1.0f,
// };
// const auto color_attachment_info = VkRenderingAttachmentInfoKHR {
// .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
// .imageView = m_swapchain->get_image_view(image_idx),
// .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .resolveMode = VK_RESOLVE_MODE_NONE,
// .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
// .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
// .clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } },
// };
// const auto rendering_info = VkRenderingInfoKHR {
// .sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
// .renderArea = scissor,
// .layerCount = 1,
// .colorAttachmentCount = 1,
// .pColorAttachments = &color_attachment_info,
//
// };
m_staging_map = {};
m_sprite_vertex_map = {};
cmd.begin({});
m_staging_buffer.unmap();
const auto buffer_copy_info = VkBufferCopy {
.srcOffset = m_staging_offset,
.dstOffset = m_staging_offset,
.size = m_current_sprite_idx * sizeof(components::Sprite::Vertex),
};
vk_cmd_copy_buffer(cmd, m_staging_buffer.vk(), m_vertex_buffer.vk(), 1u, &buffer_copy_info);
}
void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx)
{
const auto cmd_begin_info = VkCommandBufferBeginInfo {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = {},
.pInheritanceInfo = nullptr,
};
const auto begin_frame_barrier = VkImageMemoryBarrier {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = {},
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.image = m_swapchain->get_image(image_idx),
.subresourceRange = VkImageSubresourceRange{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0u,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0u,
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
const auto end_frame_barrier = VkImageMemoryBarrier {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccessMask = {},
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.image = m_swapchain->get_image(image_idx),
.subresourceRange = VkImageSubresourceRange{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0u,
.levelCount = VK_REMAINING_MIP_LEVELS,
.baseArrayLayer = 0u,
.layerCount = VK_REMAINING_ARRAY_LAYERS,
},
};
const auto scissor = VkRect2D {
.offset = { .x = 0u, .y = 0u },
.extent = m_resolution,
};
const auto viewport = VkViewport {
.x = 0.0f,
.y = 0.0f,
.width = static_cast<float>(m_resolution.width),
.height = static_cast<float>(m_resolution.height),
.minDepth = 0.0f,
.maxDepth = 1.0f,
};
const auto color_attachment_info = VkRenderingAttachmentInfoKHR {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.imageView = m_swapchain->get_image_view(image_idx),
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.resolveMode = VK_RESOLVE_MODE_NONE,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } },
};
const auto rendering_info = VkRenderingInfoKHR {
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
.renderArea = scissor,
.layerCount = 1,
.colorAttachmentCount = 1,
.pColorAttachments = &color_attachment_info,
};
vk_reset_command_buffer(cmd, {});
vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
flush_buffers(cmd);
vk_cmd_push_constants(
cmd,
m_pass->get_layout(),
VK_SHADER_STAGE_VERTEX_BIT,
0u,
sizeof(FrameConstants),
&m_frame_constants
cmd.copy(
{
.src_buffer = &m_staging_buffer.vk(),
.dst_buffer = &m_vertex_buffer.vk(),
.src_offset = m_staging_offset,
.dst_offset = m_staging_offset,
.size = m_current_sprite_idx * sizeof(components::Sprite::Vertex),
}
);
vk_cmd_pipeline_barrier(
cmd,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
0,
0,
nullptr,
0,
nullptr,
1,
&begin_frame_barrier
cmd.push_constants(
{
.layout = &m_pass->get_layout(),
.shader_stages = vk::ShaderStageFlags::vertex_bit,
.offset = 0u,
.size = sizeof(FrameConstants),
.data = &m_frame_constants,
}
);
vk_cmd_begin_rendering(cmd, &rendering_info);
vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline());
vk_cmd_set_viewport(cmd, 0, 1, &viewport);
vk_cmd_set_scissors(cmd, 0, 1, &scissor);
vk_cmd_draw(cmd, m_current_sprite_idx, 1, 0, 0);
vk_cmd_end_rendering(cmd);
vk_cmd_pipeline_barrier(
cmd,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
0,
0,
nullptr,
0,
nullptr,
1,
&end_frame_barrier
using AccessFlagBits = vk::CommandBuffer::ImageBarrierInfo::AccessFlagBits;
cmd.image_barrier(
{
.image = &m_swapchain->get_image(image_idx),
.range = vk::Image::full_color_range,
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.dst_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.src_accesses = AccessFlagBits::none,
.dst_accesses = AccessFlagBits::color_attachment_write,
.src_layout = vk::Image::Layout::undefined,
.dst_layout = vk::Image::Layout::color_attachment_optimal,
}
);
vkc(vk_end_command_buffer(cmd));
using Attachment = vk::CommandBuffer::RenderingInfo::AttachmentInfo;
cmd.begin_rendering(
{
.area_offset = {0u, 0u,},
.area_extent = m_resolution,
.color_attachments = std::vector<Attachment> {
Attachment{
.view= &m_swapchain->get_image_view(image_idx),
.layout = vk::Image::Layout::color_attachment_optimal,
.load_operation = Attachment::LoadOperation::load,
.store_operation = Attachment::StoreOperation::store,
.color_clear_values = {.5f, .5f, .5f, 1.f}
}
}
}
);
cmd.bind_pipeline(m_pass->get_pipeline(), vk::Pipeline::BindPoint::graphics);
// cmd.set_viewport();
// cmd.set_scissors();
cmd.draw(
{
.vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx),
.instance_count = 1u,
.first_vertex = 0u,
.first_instance = 0u,
}
);
cmd.end_rendering();
cmd.image_barrier(
{
.image = &m_swapchain->get_image(image_idx),
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit,
.src_accesses = AccessFlagBits::color_attachment_read
| AccessFlagBits::color_attachment_write,
.dst_accesses = {},
.src_layout = vk::Image::Layout::color_attachment_optimal,
.dst_layout = vk::Image::Layout::present_src,
}
);
cmd.end();
}
void Renderer::submit_sprite(
@ -462,5 +439,3 @@ void Renderer::submit_sprite(
.color = sprite.color,
};
}
} // namespace lt::renderer::vk