wip: convert from include style to module import style :D
This commit is contained in:
parent
2f60b837c9
commit
018d19335d
9 changed files with 1105 additions and 855 deletions
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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" };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export module renderer.vk.pass;
|
||||
|
||||
import renderer.data;
|
||||
import renderer.backend.vk.library_wrapper;
|
||||
import renderer.backend.vk.device;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue