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 memory.reference;
|
||||||
import std;
|
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_b32_sfloat,
|
||||||
|
|
||||||
r32_g32_sfloat,
|
r32_g32_sfloat,
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum class VertexInputRate: std::uint8_t {
|
enum class VertexInputRate : std::uint8_t
|
||||||
|
{
|
||||||
per_vertex,
|
per_vertex,
|
||||||
|
|
||||||
per_instance,
|
per_instance,
|
||||||
};
|
};
|
||||||
|
|
||||||
export struct VertexInputAttributeDescriptipn
|
struct VertexInputAttributeDescriptipn
|
||||||
{
|
{
|
||||||
std::uint32_t location;
|
std::uint32_t location;
|
||||||
|
|
||||||
|
|
@ -29,7 +31,7 @@ export struct VertexInputAttributeDescriptipn
|
||||||
VertexFormat format;
|
VertexFormat format;
|
||||||
};
|
};
|
||||||
|
|
||||||
export struct VertexInputBindingDescription
|
struct VertexInputBindingDescription
|
||||||
{
|
{
|
||||||
std::uint32_t binding;
|
std::uint32_t binding;
|
||||||
|
|
||||||
|
|
@ -37,7 +39,7 @@ export struct VertexInputBindingDescription
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Requires a math::components::Transform component on the same entity to be functional. */
|
/** Requires a math::components::Transform component on the same entity to be functional. */
|
||||||
export struct Sprite
|
struct Sprite
|
||||||
{
|
{
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +54,7 @@ export struct Sprite
|
||||||
VertexInputAttributeDescriptipn {
|
VertexInputAttributeDescriptipn {
|
||||||
.location = 0u,
|
.location = 0u,
|
||||||
.binding = 0u,
|
.binding = 0u,
|
||||||
.offset = offsetof(Sprite::Vertex, position),
|
.offset = 0u,
|
||||||
.format = VertexFormat::r32_g32_b32_sfloat,
|
.format = VertexFormat::r32_g32_b32_sfloat,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -60,7 +62,7 @@ export struct Sprite
|
||||||
VertexInputAttributeDescriptipn {
|
VertexInputAttributeDescriptipn {
|
||||||
.location = 1u,
|
.location = 1u,
|
||||||
.binding = 0u,
|
.binding = 0u,
|
||||||
.offset = offsetof(Sprite::Vertex, color),
|
.offset = sizeof(math::vec3),
|
||||||
.format = VertexFormat::r32_g32_b32_sfloat,
|
.format = VertexFormat::r32_g32_b32_sfloat,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ import renderer.backend.vk.device;
|
||||||
import renderer.vk.pass;
|
import renderer.vk.pass;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.backend.vk.instance;
|
||||||
import renderer.backend.vk.swapchain;
|
import renderer.backend.vk.swapchain;
|
||||||
|
import renderer.vk.renderer;
|
||||||
import renderer.backend.vk.buffer;
|
import renderer.backend.vk.buffer;
|
||||||
import renderer.backend.vk.gpu;
|
import renderer.backend.vk.gpu;
|
||||||
import renderer.backend.vk.surface;
|
import renderer.backend.vk.surface;
|
||||||
|
import renderer.vk.renderer;
|
||||||
import memory.scope;
|
import memory.scope;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
|
|
@ -35,6 +37,14 @@ export namespace lt::renderer {
|
||||||
const lt::assets::ShaderAsset &fragment_shader
|
const lt::assets::ShaderAsset &fragment_shader
|
||||||
) -> memory::Scope<IPass>;
|
) -> 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
|
} // namespace lt::renderer
|
||||||
|
|
||||||
module :private;
|
module :private;
|
||||||
|
|
@ -147,59 +157,62 @@ using namespace lt::renderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [[nodiscard]] /* static */ auto IRenderer::create(
|
[[nodiscard]] auto create_renderer(
|
||||||
// Api target_api,
|
Api target_api,
|
||||||
// IGpu *gpu,
|
IGpu *gpu,
|
||||||
// IDevice *device,
|
IDevice *device,
|
||||||
// ISwapchain *swapchain,
|
ISwapchain *swapchain,
|
||||||
// uint32_t max_frames_in_flight
|
std::uint32_t max_frames_in_flight
|
||||||
// ) -> memory::Scope<IRenderer>
|
) -> memory::Scope<IRenderer>
|
||||||
// {
|
{
|
||||||
// ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
|
debug::ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
|
||||||
// ensure(device, "Failed to create renderer::IRenderer: null device");
|
debug::ensure(device, "Failed to create renderer::IRenderer: null device");
|
||||||
// ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
|
debug::ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
|
||||||
// ensure(
|
debug::ensure(
|
||||||
// std::clamp(max_frames_in_flight, frames_in_flight_lower_limit, frames_in_flight_upper_limit)
|
std::clamp(
|
||||||
// == max_frames_in_flight,
|
max_frames_in_flight,
|
||||||
// "Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
|
IRenderer::frames_in_flight_lower_limit,
|
||||||
// "{}) ",
|
IRenderer::frames_in_flight_upper_limit
|
||||||
// max_frames_in_flight,
|
) == max_frames_in_flight,
|
||||||
// frames_in_flight_lower_limit,
|
"Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
|
||||||
// frames_in_flight_upper_limit
|
"{}) ",
|
||||||
// );
|
max_frames_in_flight,
|
||||||
//
|
IRenderer::frames_in_flight_lower_limit,
|
||||||
//
|
IRenderer::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]] /* static */ auto IDebugger::create(
|
switch (target_api)
|
||||||
// Api target_api,
|
{
|
||||||
// IInstance *instance,
|
case Api::vulkan:
|
||||||
// CreateInfo info
|
return memory::create_scope<vkb::Renderer>(gpu, device, swapchain, max_frames_in_flight);
|
||||||
// ) -> memory::Scope<IDebugger>
|
case Api::none:
|
||||||
// {
|
case Api::metal:
|
||||||
// debug::ensure(
|
case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
||||||
// info.severities != MessageSeverity::none,
|
}
|
||||||
// "Failed to create vk::Messenger: severities == none"
|
}
|
||||||
// );
|
|
||||||
//
|
|
||||||
// debug::ensure(info.types != MessageType::none, "Failed to create vk::Messenger: types == none");
|
[[nodiscard]] /* static */ auto IDebugger::create(
|
||||||
//
|
Api target_api,
|
||||||
// debug::ensure(info.callback, "Failed to create vk::Messenger: null callback");
|
IInstance *instance,
|
||||||
//
|
CreateInfo info
|
||||||
// switch (target_api)
|
) -> memory::Scope<IDebugger>
|
||||||
// {
|
{
|
||||||
// case Api::vulkan: return memory::create_scope<vk::Messenger>(instance, std::move(info));
|
debug::ensure(
|
||||||
// case Api::none:
|
info.severities != MessageSeverity::none,
|
||||||
// case Api::metal:
|
"Failed to create vk::Messenger: severities == none"
|
||||||
// case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
);
|
||||||
// }
|
|
||||||
// }
|
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;
|
export module renderer.frontend;
|
||||||
|
import renderer.data;
|
||||||
|
import renderer.components;
|
||||||
|
import math.components;
|
||||||
import assets.shader;
|
import assets.shader;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
import math.vec2;
|
import math.vec2;
|
||||||
|
|
@ -129,13 +132,6 @@ public:
|
||||||
std::size_t size;
|
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;
|
IBuffer() = default;
|
||||||
|
|
||||||
virtual ~IBuffer() = default;
|
virtual ~IBuffer() = default;
|
||||||
|
|
@ -160,13 +156,6 @@ private:
|
||||||
class IPass
|
class IPass
|
||||||
{
|
{
|
||||||
public:
|
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;
|
IPass() = default;
|
||||||
|
|
||||||
virtual ~IPass() = default;
|
virtual ~IPass() = default;
|
||||||
|
|
@ -180,52 +169,43 @@ public:
|
||||||
auto operator=(const IPass &) -> IPass & = delete;
|
auto operator=(const IPass &) -> IPass & = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
// class IRenderer
|
class IRenderer
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// static constexpr auto frames_in_flight_upper_limit = 5u;
|
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;
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
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
|
// class IDebugger
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -21,6 +21,11 @@ public:
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto vk() -> vk::Buffer &
|
||||||
|
{
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] auto determine_allocation_info(Usage usage) const -> vk::Memory::AllocateInfo;
|
[[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 };
|
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:
|
private:
|
||||||
void initialize_physical_device();
|
void initialize_physical_device();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
export module renderer.vk.pass;
|
export module renderer.vk.pass;
|
||||||
|
|
||||||
import renderer.data;
|
import renderer.data;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.backend.vk.library_wrapper;
|
||||||
import renderer.backend.vk.device;
|
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>
|
namespace lt::renderer::vkb {
|
||||||
#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::vk {
|
export class Renderer: public IRenderer
|
||||||
|
|
||||||
class Renderer: public IRenderer
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer(
|
Renderer(
|
||||||
class IGpu *gpu,
|
class IGpu *gpu,
|
||||||
class IDevice *device,
|
class IDevice *device,
|
||||||
class ISwapchain *swapchain,
|
class ISwapchain *swapchain,
|
||||||
uint32_t max_frames_in_flight
|
std::uint32_t max_frames_in_flight
|
||||||
);
|
);
|
||||||
|
|
||||||
~Renderer() override;
|
[[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
|
||||||
|
|
||||||
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)
|
|
||||||
-> Result override;
|
-> Result override;
|
||||||
|
|
||||||
void replace_swapchain(ISwapchain *swapchain) override;
|
void replace_swapchain(ISwapchain *swapchain) override;
|
||||||
|
|
@ -48,33 +43,29 @@ public:
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
private:
|
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;
|
math::uvec2 m_resolution;
|
||||||
|
|
||||||
VkExtent2D m_resolution;
|
|
||||||
|
|
||||||
uint32_t m_max_frames_in_flight {};
|
|
||||||
|
|
||||||
FrameConstants m_frame_constants;
|
FrameConstants m_frame_constants;
|
||||||
|
|
||||||
|
|
@ -82,26 +73,27 @@ private:
|
||||||
|
|
||||||
Buffer m_staging_buffer;
|
Buffer m_staging_buffer;
|
||||||
|
|
||||||
size_t m_staging_offset;
|
std::size_t m_staging_offset;
|
||||||
|
|
||||||
std::span<std::byte> m_staging_map;
|
std::span<std::byte> m_staging_map;
|
||||||
|
|
||||||
std::span<components::Sprite::Vertex> m_sprite_vertex_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;
|
module :private;
|
||||||
|
using namespace lt::renderer;
|
||||||
|
using namespace lt::renderer::vkb;
|
||||||
|
|
||||||
#include <memory/reference.hpp>
|
Renderer::Renderer(
|
||||||
#include <renderer/backend/vk/context/swapchain.hpp>
|
IGpu *gpu,
|
||||||
#include <renderer/backend/vk/renderer/renderer.hpp>
|
IDevice *device,
|
||||||
|
ISwapchain *swapchain,
|
||||||
namespace lt::renderer::vk {
|
std::uint32_t max_frames_in_flight
|
||||||
|
)
|
||||||
Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t max_frames_in_flight)
|
|
||||||
: m_device(static_cast<Device *>(device))
|
: m_device(static_cast<Device *>(device))
|
||||||
, m_swapchain(static_cast<Swapchain *>(swapchain))
|
, m_swapchain(static_cast<Swapchain *>(swapchain))
|
||||||
, m_resolution(m_swapchain->get_resolution())
|
, m_resolution(m_swapchain->get_resolution())
|
||||||
|
|
@ -110,7 +102,7 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
|
||||||
, m_vertex_buffer(
|
, m_vertex_buffer(
|
||||||
device,
|
device,
|
||||||
gpu,
|
gpu,
|
||||||
IBuffer::CreateInfo {
|
{
|
||||||
.usage = IBuffer::Usage::vertex,
|
.usage = IBuffer::Usage::vertex,
|
||||||
.size = 1'000'000,
|
.size = 1'000'000,
|
||||||
.debug_name = "vertex buffer",
|
.debug_name = "vertex buffer",
|
||||||
|
|
@ -119,91 +111,46 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
|
||||||
, m_staging_buffer(
|
, m_staging_buffer(
|
||||||
device,
|
device,
|
||||||
gpu,
|
gpu,
|
||||||
IBuffer::CreateInfo {
|
{
|
||||||
.usage = IBuffer::Usage::staging,
|
.usage = IBuffer::Usage::staging,
|
||||||
.size = 1'000'000,
|
.size = 1'000'000,
|
||||||
.debug_name = "staging buffer",
|
.debug_name = "staging buffer",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
{
|
, m_pass(
|
||||||
ensure(m_device, "Failed to initialize renderer: null device");
|
memory::create_ref<Pass>(
|
||||||
ensure(m_swapchain, "Failed to initialize renderer: null swapchain");
|
|
||||||
|
|
||||||
// TODO(Light): HARDCODED PASS!!!
|
|
||||||
m_pass = memory::create_ref<vk::Pass>(
|
|
||||||
m_device,
|
m_device,
|
||||||
m_swapchain,
|
|
||||||
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
|
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
|
||||||
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
|
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
|
||||||
);
|
)
|
||||||
|
)
|
||||||
m_pool = m_device->create_command_pool(
|
, m_pool(
|
||||||
VkCommandPoolCreateInfo {
|
m_device->vk(),
|
||||||
.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))
|
|
||||||
{
|
{
|
||||||
m_device->name(semaphore, "acquire image semaphore {}", idx);
|
.flags = vk::CommandPool::CreateInfo::FlagBits::reset_command_buffer,
|
||||||
m_device->name(fence, "frame fence {}", idx);
|
}
|
||||||
|
)
|
||||||
|
, 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())
|
||||||
|
{
|
||||||
|
for (auto [semaphore, fence] : std::views::zip(m_acquire_image_semaphores, m_frame_fences))
|
||||||
|
{
|
||||||
|
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 &semaphore : m_submit_semaphores)
|
||||||
for (auto idx = 0u; 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)
|
debug::ensure(
|
||||||
{
|
|
||||||
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(
|
|
||||||
frame_idx < m_max_frames_in_flight,
|
frame_idx < m_max_frames_in_flight,
|
||||||
"Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})",
|
"Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})",
|
||||||
frame_idx,
|
frame_idx,
|
||||||
|
|
@ -211,50 +158,33 @@ Renderer::~Renderer()
|
||||||
);
|
);
|
||||||
|
|
||||||
auto &frame_fence = m_frame_fences[frame_idx];
|
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];
|
auto &cmd = m_cmds[frame_idx];
|
||||||
|
|
||||||
m_device->wait_for_fence(frame_fence);
|
frame_fence.wait();
|
||||||
|
const auto image_idx = m_swapchain->vk().acquire_image(acquire_semaphore);
|
||||||
auto image_idx = m_device->acquire_image(m_swapchain->vk(), aquire_semaphore);
|
frame_fence.reset();
|
||||||
if (!image_idx.has_value())
|
|
||||||
{
|
|
||||||
return Result::invalid_swapchain;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device->reset_fence(frame_fence);
|
|
||||||
|
|
||||||
map_buffers(frame_idx);
|
map_buffers(frame_idx);
|
||||||
submit_scene();
|
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];
|
||||||
auto &submit_semaphore = m_submit_semaphores[*image_idx];
|
m_device->graphics_queue().submit(
|
||||||
m_device->submit(
|
vk::Queue::SubmitInfo {
|
||||||
VkSubmitInfo {
|
.command_buffer = &cmd,
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
.wait_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
.waitSemaphoreCount = 1u,
|
.wait_semaphore = &acquire_semaphore,
|
||||||
.pWaitSemaphores = &aquire_semaphore,
|
.signal_semaphore = &submit_semaphore,
|
||||||
.pWaitDstStageMask = &wait_stage,
|
.signal_fence = &frame_fence,
|
||||||
.commandBufferCount = 1u,
|
}
|
||||||
.pCommandBuffers = &cmd,
|
|
||||||
.signalSemaphoreCount = 1u,
|
|
||||||
.pSignalSemaphores = &submit_semaphore,
|
|
||||||
},
|
|
||||||
frame_fence
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO(Light): handle result
|
m_device->present_queue().present(
|
||||||
auto result = VkResult {};
|
vk::Queue::PresentInfo {
|
||||||
m_device->present(
|
.wait_semaphore = &submit_semaphore,
|
||||||
VkPresentInfoKHR {
|
.swapchain = &m_swapchain->vk(),
|
||||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
.image_idx = image_idx,
|
||||||
.waitSemaphoreCount = 1u,
|
|
||||||
.pWaitSemaphores = &submit_semaphore,
|
|
||||||
.swapchainCount = 1u,
|
|
||||||
.pSwapchains = m_swapchain->vk_ptr(),
|
|
||||||
.pImageIndices = &image_idx.value(),
|
|
||||||
.pResults = &result,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -263,13 +193,12 @@ Renderer::~Renderer()
|
||||||
|
|
||||||
void Renderer::replace_swapchain(ISwapchain *swapchain)
|
void Renderer::replace_swapchain(ISwapchain *swapchain)
|
||||||
{
|
{
|
||||||
m_device->wait_idle();
|
m_device->vk().wait_idle();
|
||||||
m_swapchain = static_cast<Swapchain *>(swapchain);
|
m_swapchain = static_cast<Swapchain *>(swapchain);
|
||||||
m_resolution = m_swapchain->get_resolution();
|
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;
|
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_staging_map = {};
|
||||||
m_sprite_vertex_map = {};
|
m_sprite_vertex_map = {};
|
||||||
|
cmd.begin({});
|
||||||
|
|
||||||
m_staging_buffer.unmap();
|
m_staging_buffer.unmap();
|
||||||
const auto buffer_copy_info = VkBufferCopy {
|
cmd.copy(
|
||||||
|
{
|
||||||
.srcOffset = m_staging_offset,
|
.src_buffer = &m_staging_buffer.vk(),
|
||||||
.dstOffset = m_staging_offset,
|
.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),
|
.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
|
|
||||||
);
|
);
|
||||||
vk_cmd_pipeline_barrier(
|
cmd.push_constants(
|
||||||
cmd,
|
{
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.layout = &m_pass->get_layout(),
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.shader_stages = vk::ShaderStageFlags::vertex_bit,
|
||||||
0,
|
.offset = 0u,
|
||||||
0,
|
.size = sizeof(FrameConstants),
|
||||||
nullptr,
|
.data = &m_frame_constants,
|
||||||
0,
|
}
|
||||||
nullptr,
|
|
||||||
1,
|
|
||||||
&begin_frame_barrier
|
|
||||||
);
|
);
|
||||||
vk_cmd_begin_rendering(cmd, &rendering_info);
|
|
||||||
vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline());
|
using AccessFlagBits = vk::CommandBuffer::ImageBarrierInfo::AccessFlagBits;
|
||||||
vk_cmd_set_viewport(cmd, 0, 1, &viewport);
|
cmd.image_barrier(
|
||||||
vk_cmd_set_scissors(cmd, 0, 1, &scissor);
|
{
|
||||||
vk_cmd_draw(cmd, m_current_sprite_idx, 1, 0, 0);
|
.image = &m_swapchain->get_image(image_idx),
|
||||||
vk_cmd_end_rendering(cmd);
|
.range = vk::Image::full_color_range,
|
||||||
vk_cmd_pipeline_barrier(
|
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
cmd,
|
.dst_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.src_accesses = AccessFlagBits::none,
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
.dst_accesses = AccessFlagBits::color_attachment_write,
|
||||||
0,
|
.src_layout = vk::Image::Layout::undefined,
|
||||||
0,
|
.dst_layout = vk::Image::Layout::color_attachment_optimal,
|
||||||
nullptr,
|
}
|
||||||
0,
|
|
||||||
nullptr,
|
|
||||||
1,
|
|
||||||
&end_frame_barrier
|
|
||||||
);
|
);
|
||||||
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(
|
void Renderer::submit_sprite(
|
||||||
|
|
@ -462,5 +439,3 @@ void Renderer::submit_sprite(
|
||||||
.color = sprite.color,
|
.color = sprite.color,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::renderer::vk
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue