feat: vulkan api wrapper #69

Open
light7734 wants to merge 4 commits from vulkan_api_wrapper into main
12 changed files with 868 additions and 516 deletions

Binary file not shown.

View file

@ -1,25 +1,26 @@
#version 450 core #version 450 core
layout(push_constant ) uniform pc { layout(push_constant) uniform pc {
mat4 view_projection; mat4 view_projection;
}; };
vec3 positions[3] = vec3[]( struct VertexData
vec3(0.0, -0.5, 0.5), {
vec3(0.5, 0.5, 0.5), vec3 position;
vec3(-0.5, 0.5, 0.5) vec3 color;
); };
vec3 colors[3] = vec3[]( layout(std140, set = 0, binding = 0) readonly buffer Vertices {
vec3(0.0, 0.0, 0.0),
vec3(0.0, 0.0, 0.0), VertexData vertices[];
vec3(0.0, 0.0, 0.0) } ssbo_vertices;
);
layout(location = 0) out vec3 out_frag_color; layout(location = 0) out vec3 out_frag_color;
void main() void main()
{ {
gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0); VertexData vertex = ssbo_vertices.vertices[gl_VertexIndex];
out_frag_color = colors[gl_VertexIndex];
gl_Position = view_projection * vec4(vertex.position, 1.0);
out_frag_color = vertex.color;
} }

Binary file not shown.

View file

@ -219,9 +219,11 @@ add_module(
_tests/debugger.cpp _tests/debugger.cpp
_tests/device.cpp _tests/device.cpp
_tests/pass.cpp _tests/pass.cpp
_tests/renderer.cpp
_tests/surface.cpp
_tests/system.cpp
TEST_INTERFACES TEST_INTERFACES
_tests/utils.cppm _tests/utils.cppm
# _tests/renderer.cpp _tests/surface.cpp _tests/system.cpp
) )
add_module( add_module(

View file

@ -1,24 +1,28 @@
#include <memory/reference.hpp> import renderer.frontend;
#include <renderer/frontend/renderer/renderer.hpp> import renderer.test_utils;
#include <renderer/test/utils.hpp>
Suite raii = "renderer_raii"_suite = [] { Suite raii = "renderer_raii"_suite = [] {
Case { "happy path won't throw" } = [] { Case { "happy path won't throw" } = [] {
auto fixture = FixtureDeviceSwapchain {}; auto fixture = FixtureDeviceSwapchain {};
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
fixture.swapchain(), fixture.swapchain(),
constants::frames_in_flight constants::frames_in_flight
); );
expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::error));
expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::warning)
);
}; };
Case { "unhappy path throws" } = [] { Case { "unhappy path throws" } = [] {
auto fixture = FixtureDeviceSwapchain {}; auto fixture = FixtureDeviceSwapchain {};
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
nullptr, nullptr,
fixture.device(), fixture.device(),
@ -28,7 +32,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
nullptr, nullptr,
@ -38,7 +42,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -48,7 +52,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -58,7 +62,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::IRenderer::create( ignore = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -74,7 +78,7 @@ Suite draw = "renderer_draw"_suite = [] {
Case { "renderer draw" } = [] { Case { "renderer draw" } = [] {
auto fixture = FixtureDeviceSwapchain {}; auto fixture = FixtureDeviceSwapchain {};
auto renderer = lt::renderer::IRenderer::create( auto renderer = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -86,11 +90,16 @@ Suite draw = "renderer_draw"_suite = [] {
{ {
expect_eq(renderer->frame(frame_idx % constants::frames_in_flight, [] {}), success); expect_eq(renderer->frame(frame_idx % constants::frames_in_flight, [] {}), success);
} }
expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::error));
expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::warning)
);
}; };
Case { "post swapchain replacement renderer draw" } = [] { Case { "post swapchain replacement renderer draw" } = [] {
auto fixture = FixtureDeviceSwapchain {}; auto fixture = FixtureDeviceSwapchain {};
auto renderer = lt::renderer::IRenderer::create( auto renderer = lt::renderer::create_renderer(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -109,5 +118,10 @@ Suite draw = "renderer_draw"_suite = [] {
{ {
expect_eq(renderer->frame(frame_idx % constants::frames_in_flight, [] {}), success); expect_eq(renderer->frame(frame_idx % constants::frames_in_flight, [] {}), success);
} }
expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::error));
expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger ::MessageSeverity::warning)
);
}; };
}; };

View file

@ -1,22 +1,13 @@
#include <logger/logger.hpp> import renderer.frontend;
#include <memory/reference.hpp> import renderer.test_utils;
#include <renderer/frontend/context/instance.hpp>
#include <renderer/frontend/context/surface.hpp>
#include <renderer/test/utils.hpp>
#include <surface/components.hpp>
#include <surface/system.hpp>
#include <test/test.hpp>
using ::lt::ecs::EntityId;
using ::lt::ecs::Registry;
Suite raii = "surface"_suite = [] { Suite raii = "surface"_suite = [] {
Case { "happy path won't throw" } = [&] { Case { "happy path won't throw" } = [&] {
auto fixture = Fixture_SurfaceSystem {}; auto fixture = Fixture_SurfaceSystem {};
const auto surface = lt::renderer::ISurface::create( const auto surface = lt::renderer::create_surface(
constants::api, constants::api,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
fixture.surface_entity() fixture.surface_entity()
); );
@ -31,9 +22,9 @@ Suite raii = "surface"_suite = [] {
auto system = lt::surface::System(registry); auto system = lt::surface::System(registry);
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::ISurface::create( std::ignore = lt::renderer::create_surface(
constants::api, constants::api,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
entity entity
); );
}); });
@ -47,42 +38,38 @@ Suite raii = "surface"_suite = [] {
); );
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(constants::api, nullptr, entity); std::ignore = lt::renderer::create_surface(constants::api, nullptr, entity);
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::ISurface::create( std::ignore = lt::renderer::create_surface(
lt::renderer::Api::none, lt::renderer::Api::none,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
entity entity
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::ISurface::create( std::ignore = lt::renderer::create_surface(
lt::renderer::Api::direct_x, lt::renderer::Api::direct_x,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
entity entity
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::ISurface::create( std::ignore = lt::renderer::create_surface(
lt::renderer::Api::metal, lt::renderer::Api::metal,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
entity entity
); );
}); });
// Ensure base creation info is non-throwing // Ensure base creation info is non-throwing
std::ignore = lt::renderer::ISurface::create( std::ignore = lt::renderer::create_surface(
constants::api, constants::api,
lt::renderer::IInstance::get(constants::api), lt::renderer::get_instance(constants::api),
entity entity
); );
}; };
// TODO(Light): add torture tests
Case { "torture tests" } = [] {
};
}; };

View file

@ -1,31 +1,16 @@
#include <logger/logger.hpp> import renderer.frontend;
#include <memory/reference.hpp> import renderer.test_utils;
#include <memory/scope.hpp>
#include <renderer/frontend/renderer/renderer.hpp>
#include <renderer/system.hpp>
#include <renderer/test/utils.hpp>
#include <surface/components.hpp>
#include <surface/system.hpp>
#include <test/test.hpp>
using namespace lt;
using std::ignore;
using test::Case;
using test::expect_throw;
using test::Suite;
using renderer::System;
struct SurfaceContext struct SurfaceContext
{ {
surface::System system; lt::surface::System system;
ecs::Entity entity; lt::ecs::Entity entity;
}; };
struct RendererContext struct RendererContext
{ {
memory::Ref<ecs::Registry> registry; lt::memory::Ref<lt::ecs::Registry> registry;
System system; lt::renderer::System system;
}; };
@ -36,59 +21,62 @@ Suite raii = "system_raii"_suite = [] {
Case { "happy path has no errors" } = [] { Case { "happy path has no errors" } = [] {
auto fixture = Fixture_RendererSystem {}; auto fixture = Fixture_RendererSystem {};
expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::error)); expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::error));
expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::warning)); expect_false(
fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::warning)
);
}; };
Case { "unhappy path throws" } = [] { Case { "unhappy path throws" } = [] {
auto fixture = Fixture_SurfaceSystem {}; auto fixture = Fixture_SurfaceSystem {};
auto empty_entity = ecs::Entity { fixture.registry(), fixture.registry()->create_entity() }; auto empty_entity = lt::ecs::Entity { fixture.registry(),
fixture.registry()->create_entity() };
auto info = fixture.renderer_system_create_info(); auto info = fixture.renderer_system_create_info();
expect_throw([=] mutable { expect_throw([=] mutable {
info.registry = nullptr; info.registry = nullptr;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.surface_entity = ecs::Entity({}, {}); info.surface_entity = lt::ecs::Entity({}, {});
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::none; info.config.target_api = lt::renderer::Api::none;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
// unsupported Apis // unsupported Apis
expect_throw([=] mutable { expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::direct_x; info.config.target_api = lt::renderer::Api::direct_x;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::metal; info.config.target_api = lt::renderer::Api::metal;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
constexpr auto limit = lt::renderer::System::frames_in_flight_upper_limit; constexpr auto limit = lt::renderer::System::frames_in_flight_upper_limit;
info.config.max_frames_in_flight = limit + 1u; info.config.max_frames_in_flight = limit + 1u;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
constexpr auto limit = lt::renderer::System::frames_in_flight_lower_limit; constexpr auto limit = lt::renderer::System::frames_in_flight_lower_limit;
info.config.max_frames_in_flight = limit - 1u; info.config.max_frames_in_flight = limit - 1u;
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.debug_callback_info = lt::renderer::IMessenger::CreateInfo {}; info.debug_callback_info = lt::renderer::IDebugger::CreateInfo {};
ignore = System { info }; ignore = lt::renderer::System { info };
}); });
// Make sure the base info is not at fault for unhappiness. // Make sure the base info is not at fault for unhappiness.
ignore = System { info }; ignore = lt::renderer::System { info };
}; };
}; };

File diff suppressed because it is too large Load diff

View file

@ -100,9 +100,15 @@ void Device::initialize_logical_device()
.extensions = { .extensions = {
vk::device_extension_names::swapchain, vk::device_extension_names::swapchain,
vk::device_extension_names::dynamic_rendering, vk::device_extension_names::dynamic_rendering,
vk::device_extension_names::descriptor_indexing,
}, },
.features = {}, .features = {
.geometry_shader = true,
.sampler_anisotropy = true,
.multi_draw_indirect = true,
.draw_indirect_first_instance = true,
},
.dynamic_rendering_features = m_gpu->vk().get_supported_dynamic_rendering_features(), .dynamic_rendering_features = m_gpu->vk().get_supported_dynamic_rendering_features(),

View file

@ -25,11 +25,16 @@ public:
return m_pipeline; return m_pipeline;
} }
[[nodiscard]] auto get_layout() -> vk::PipelineLayout & [[nodiscard]] auto get_pipeline_layout() -> vk::PipelineLayout &
{ {
return m_layout; return m_layout;
} }
[[nodiscard]] auto get_descriptor_set_layout() -> vk::DescriptorSetLayout &
{
return m_descriptor_set_layout;
}
private: private:
Device *m_device {}; Device *m_device {};
@ -51,60 +56,30 @@ module :private;
using namespace ::lt::renderer::vkb; using namespace ::lt::renderer::vkb;
using namespace ::lt::renderer; using namespace ::lt::renderer;
using enum vk::DescriptorSetLayout::Binding::FlagBits;
Pass::Pass( Pass::Pass(
IDevice *device, IDevice *device,
const lt::assets::ShaderAsset &vertex_shader, const lt::assets::ShaderAsset &vertex_shader,
const lt::assets::ShaderAsset &fragment_shader const lt::assets::ShaderAsset &fragment_shader
) )
: m_device(static_cast<Device *>(device)) : m_device(static_cast<Device *>(device))
, m_descriptor_set_layout(m_device->vk(),{
{ .flags = vk::DescriptorSetLayout::CreateInfo::FlagBits::update_after_bind_pool,
using enum vk::DescriptorSetLayout::Binding::FlagBits;
auto bindings = std::vector<vk::DescriptorSetLayout::Binding> {
{
.flags = variable_descriptor_count | partially_bound | update_after_bind
| update_unused_while_pending,
.idx = 0u,
.count = 1'000u,
.type = vk::DescriptorSet::Type::storage_buffer,
.shader_stages = vk::ShaderStageFlags::vertex_bit,
},
};
using enum vk::DescriptorSetLayout::CreateInfo::FlagBits;
m_descriptor_set_layout = vk::DescriptorSetLayout(
m_device->vk(),
vk::DescriptorSetLayout::CreateInfo {
.flags = update_after_bind_pool,
.bindings = { .bindings = {
vk::DescriptorSetLayout::Binding { {
.flags = variable_descriptor_count | partially_bound | update_after_bind | update_unused_while_pending, .flags = partially_bound | update_after_bind | update_unused_while_pending,
.idx = 0u, .idx = 0u,
.count = 1'000u, .count = 1'000u,
.type = vk::DescriptorSet::Type::storage_buffer, .type = vk::DescriptorSet::Type::storage_buffer,
.shader_stages = vk::ShaderStageFlags::vertex_bit, .shader_stages = vk::ShaderStageFlags::vertex_bit,
}, },
}, }}),
} m_layout(vk::PipelineLayout(m_device->vk(),{
); .descriptor_set_layouts = { &m_descriptor_set_layout },
.push_constant_ranges = { { vk::ShaderStageFlags::vertex_bit, 0u, sizeof(FrameConstants) } }
auto push_constant_ranges = std::vector<vk::PipelineLayout::PushConstantRange> { }))
{ {
.shader_stages = vk::ShaderStageFlags::vertex_bit,
.offset = 0u,
.size = sizeof(FrameConstants),
},
};
m_layout = vk::PipelineLayout(
m_device->vk(),
vk::PipelineLayout::CreateInfo {
.descriptor_set_layouts = {
&m_descriptor_set_layout,
},
.push_constant_ranges = push_constant_ranges,
}
);
// auto pool_size = VkDescriptorPoolSize { // auto pool_size = VkDescriptorPoolSize {
// .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
// .descriptorCount = descriptor_count, // .descriptorCount = descriptor_count,
@ -135,7 +110,6 @@ Pass::Pass(
// } // }
// ); // );
auto shaders = std::vector<std::pair<vk::ShaderModule, vk::ShaderStageFlags::T>> {}; auto shaders = std::vector<std::pair<vk::ShaderModule, vk::ShaderStageFlags::T>> {};
shaders.emplace_back( shaders.emplace_back(
vk::ShaderModule( vk::ShaderModule(
@ -162,7 +136,7 @@ Pass::Pass(
vk::Pipeline::CreateInfo { vk::Pipeline::CreateInfo {
.shaders = std::move(shaders), .shaders = std::move(shaders),
.input_assembly_state = { .input_assembly_state = {
.topology = vk::PrimitiveTopology::triangle_list, .topology = vk::PrimitiveTopology::triangle_strip,
.primitive_restart_enabled = true, .primitive_restart_enabled = true,
}, },
.viewport_state = { .viewport_state = {

View file

@ -1,4 +1,5 @@
export module renderer.vk.renderer; export module renderer.vk.renderer;
import logger;
import assets.shader; import assets.shader;
import debug.assertions; import debug.assertions;
import renderer.vk.api_wrapper; import renderer.vk.api_wrapper;
@ -17,6 +18,7 @@ import std;
namespace lt::renderer::vkb { namespace lt::renderer::vkb {
// NOLINTNEXTLINE
export class Renderer: public IRenderer export class Renderer: public IRenderer
{ {
public: public:
@ -27,6 +29,18 @@ public:
std::uint32_t max_frames_in_flight std::uint32_t max_frames_in_flight
); );
~Renderer() override
{
try
{
m_device->vk().wait_idle();
}
catch (std::exception &exp)
{
log::error("Failed to wait idle on device in renderer destructor");
}
}
[[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene) [[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
-> Result override; -> Result override;
@ -80,6 +94,10 @@ private:
std::span<components::Sprite::Vertex> m_sprite_vertex_map; std::span<components::Sprite::Vertex> m_sprite_vertex_map;
std::size_t m_current_sprite_idx; std::size_t m_current_sprite_idx;
vk::DescriptorPool m_global_set_pool;
vk::DescriptorSet m_global_set;
}; };
} // namespace lt::renderer::vkb } // namespace lt::renderer::vkb
@ -102,7 +120,7 @@ Renderer::Renderer(
device, device,
gpu, gpu,
{ {
.usage = IBuffer::Usage::vertex, .usage = IBuffer::Usage::storage,
.size = 1'000'000, .size = 1'000'000,
.debug_name = "vertex buffer", .debug_name = "vertex buffer",
} }
@ -116,11 +134,13 @@ Renderer::Renderer(
.debug_name = "staging buffer", .debug_name = "staging buffer",
} }
) )
, m_pass(memory::create_ref<Pass>( , m_pass(
memory::create_ref<Pass>(
m_device, m_device,
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_pool(
m_device->vk(), m_device->vk(),
{ {
@ -131,6 +151,16 @@ Renderer::Renderer(
, m_acquire_image_semaphores(m_max_frames_in_flight) , m_acquire_image_semaphores(m_max_frames_in_flight)
, m_frame_fences(m_max_frames_in_flight) , m_frame_fences(m_max_frames_in_flight)
, m_submit_semaphores(m_swapchain->get_image_count()) , m_submit_semaphores(m_swapchain->get_image_count())
, m_global_set_pool(
m_device->vk(),
vk::DescriptorPool::CreateInfo {
.sizes = { { .type = vk::DescriptorSet::Type::storage_buffer, .count = 1'000 } },
.max_sets = 1'000,
.name = "global pool",
}
)
, m_global_set(m_global_set_pool.allocate(m_pass->get_descriptor_set_layout()))
{ {
for (auto [semaphore, fence] : std::views::zip(m_acquire_image_semaphores, m_frame_fences)) for (auto [semaphore, fence] : std::views::zip(m_acquire_image_semaphores, m_frame_fences))
{ {
@ -167,19 +197,23 @@ Renderer::Renderer(
record_cmd(cmd, image_idx); record_cmd(cmd, image_idx);
auto &submit_semaphore = m_submit_semaphores[image_idx]; auto &submit_semaphore = m_submit_semaphores[image_idx];
m_device->graphics_queue().submit(vk::Queue::SubmitInfo { m_device->graphics_queue().submit(
vk::Queue::SubmitInfo {
.command_buffer = &cmd, .command_buffer = &cmd,
.wait_stages = vk::PipelineStageFlags::color_attachment_output_bit, .wait_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.wait_semaphore = &acquire_semaphore, .wait_semaphore = &acquire_semaphore,
.signal_semaphore = &submit_semaphore, .signal_semaphore = &submit_semaphore,
.signal_fence = &frame_fence, .signal_fence = &frame_fence,
}); }
);
m_device->present_queue().present(vk::Queue::PresentInfo { m_device->present_queue().present(
vk::Queue::PresentInfo {
.wait_semaphore = &submit_semaphore, .wait_semaphore = &submit_semaphore,
.swapchain = &m_swapchain->vk(), .swapchain = &m_swapchain->vk(),
.image_idx = image_idx, .image_idx = image_idx,
}); }
);
return Result::success; return Result::success;
} }
@ -210,127 +244,45 @@ void Renderer::map_buffers(std::uint32_t frame_idx)
void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx) 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({}); cmd.begin({});
m_staging_buffer.unmap(); m_staging_buffer.unmap();
cmd.copy({
if (m_current_sprite_idx)
{
cmd.copy(
{
.src_buffer = &m_staging_buffer.vk(), .src_buffer = &m_staging_buffer.vk(),
.dst_buffer = &m_vertex_buffer.vk(), .dst_buffer = &m_vertex_buffer.vk(),
.src_offset = m_staging_offset, .src_offset = m_staging_offset,
.dst_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),
}); }
cmd.push_constants({ );
.layout = &m_pass->get_layout(), }
cmd.push_constants(
{
.layout = &m_pass->get_pipeline_layout(),
.shader_stages = vk::ShaderStageFlags::vertex_bit, .shader_stages = vk::ShaderStageFlags::vertex_bit,
.offset = 0u, .offset = 0u,
.size = sizeof(FrameConstants), .size = sizeof(FrameConstants),
.data = &m_frame_constants, .data = &m_frame_constants,
}); }
);
cmd.bind_descriptor_set(
m_global_set,
vk::Pipeline::BindPoint::graphics,
m_pass->get_pipeline_layout(),
0
);
using AccessFlagBits = vk::CommandBuffer::ImageBarrierInfo::AccessFlagBits; using AccessFlagBits = vk::CommandBuffer::ImageBarrierInfo::AccessFlagBits;
cmd.image_barrier({ cmd.image_barrier(
{
.image = &m_swapchain->get_image(image_idx), .image = &m_swapchain->get_image(image_idx),
.range = vk::Image::full_color_range, .range = vk::Image::full_color_range,
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit, .src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
@ -339,7 +291,8 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
.dst_accesses = AccessFlagBits::color_attachment_write, .dst_accesses = AccessFlagBits::color_attachment_write,
.src_layout = vk::Image::Layout::undefined, .src_layout = vk::Image::Layout::undefined,
.dst_layout = vk::Image::Layout::color_attachment_optimal, .dst_layout = vk::Image::Layout::color_attachment_optimal,
}); }
);
using Attachment = vk::CommandBuffer::RenderingInfo::AttachmentInfo; using Attachment = vk::CommandBuffer::RenderingInfo::AttachmentInfo;
cmd.begin_rendering( cmd.begin_rendering(
@ -350,7 +303,7 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
Attachment{ Attachment{
.view= &m_swapchain->get_image_view(image_idx), .view= &m_swapchain->get_image_view(image_idx),
.layout = vk::Image::Layout::color_attachment_optimal, .layout = vk::Image::Layout::color_attachment_optimal,
.load_operation = Attachment::LoadOperation::load, .load_operation = Attachment::LoadOperation::clear,
.store_operation = Attachment::StoreOperation::store, .store_operation = Attachment::StoreOperation::store,
.color_clear_values = {.5f, .5f, .5f, 1.f} .color_clear_values = {.5f, .5f, .5f, 1.f}
} }
@ -358,18 +311,29 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
} }
); );
cmd.bind_pipeline(m_pass->get_pipeline(), vk::Pipeline::BindPoint::graphics); cmd.bind_pipeline(m_pass->get_pipeline(), vk::Pipeline::BindPoint::graphics);
// cmd.set_viewport(); cmd.set_viewport(
// cmd.set_scissors(); {
cmd.draw({ .origin = {},
.extent = { static_cast<float>(m_resolution.x), static_cast<float>(m_resolution.y) },
.min_depth = 0.0f,
.max_depth = 1.0f,
}
);
cmd.set_scissor({ .offset = {}, .extent = m_resolution });
cmd.draw(
{
.vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx), .vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx),
.instance_count = 1u, .instance_count = 1u,
.first_vertex = 0u, .first_vertex = 0u,
.first_instance = 0u, .first_instance = 0u,
}); }
);
cmd.end_rendering(); cmd.end_rendering();
cmd.image_barrier({ cmd.image_barrier(
{
.image = &m_swapchain->get_image(image_idx), .image = &m_swapchain->get_image(image_idx),
.range = vk::Image::full_color_range,
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit, .src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit, .dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit,
.src_accesses = AccessFlagBits::color_attachment_read .src_accesses = AccessFlagBits::color_attachment_read
@ -378,7 +342,8 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
.src_layout = vk::Image::Layout::color_attachment_optimal, .src_layout = vk::Image::Layout::color_attachment_optimal,
.dst_layout = vk::Image::Layout::present_src, .dst_layout = vk::Image::Layout::present_src,
}); }
);
cmd.end(); cmd.end();
} }

View file

@ -49,8 +49,8 @@ find ./build/modules -type f -name "*.profraw" -exec rm -fv {} +
LLVM_COV_SHOW=$( LLVM_COV_SHOW=$(
llvm-cov show \ llvm-cov show \
-instr-profile='./build/coverage/merged.profdata' \ -instr-profile='./build/coverage/merged.profdata' \
"$(find ./build -type f -name '*_tests' -executable -exec printf -- '-object %s ' {} \;)" \ "$(find ./build -type f -name '*_tests' -executable -exec printf -- '--object=%s ' {} \;)" \
"$(find ./build -type f -name '*\.a' -exec printf -- '-object %s ' {} \;)" \ "$(find ./build -type f -name '*\.a' -exec printf -- '--object=%s ' {} \;)" \
-ignore-filename-regex='\.test\.cpp$' \ -ignore-filename-regex='\.test\.cpp$' \
-ignore-filename-regex='\.fuzz\.cpp$' -ignore-filename-regex='\.fuzz\.cpp$'
) )