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
layout(push_constant ) uniform pc {
mat4 view_projection;
layout(push_constant) uniform pc {
mat4 view_projection;
};
vec3 positions[3] = vec3[](
vec3(0.0, -0.5, 0.5),
vec3(0.5, 0.5, 0.5),
vec3(-0.5, 0.5, 0.5)
);
struct VertexData
{
vec3 position;
vec3 color;
};
vec3 colors[3] = vec3[](
vec3(0.0, 0.0, 0.0),
vec3(0.0, 0.0, 0.0),
vec3(0.0, 0.0, 0.0)
);
layout(std140, set = 0, binding = 0) readonly buffer Vertices {
VertexData vertices[];
} ssbo_vertices;
layout(location = 0) out vec3 out_frag_color;
void main()
{
gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0);
out_frag_color = colors[gl_VertexIndex];
VertexData vertex = ssbo_vertices.vertices[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/device.cpp
_tests/pass.cpp
_tests/renderer.cpp
_tests/surface.cpp
_tests/system.cpp
TEST_INTERFACES
_tests/utils.cppm
# _tests/renderer.cpp _tests/surface.cpp _tests/system.cpp
)
add_module(

View file

@ -1,24 +1,28 @@
#include <memory/reference.hpp>
#include <renderer/frontend/renderer/renderer.hpp>
#include <renderer/test/utils.hpp>
import renderer.frontend;
import renderer.test_utils;
Suite raii = "renderer_raii"_suite = [] {
Case { "happy path won't throw" } = [] {
auto fixture = FixtureDeviceSwapchain {};
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
fixture.swapchain(),
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" } = [] {
auto fixture = FixtureDeviceSwapchain {};
expect_throw([&] {
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
nullptr,
fixture.device(),
@ -28,7 +32,7 @@ Suite raii = "renderer_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
nullptr,
@ -38,7 +42,7 @@ Suite raii = "renderer_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
@ -48,7 +52,7 @@ Suite raii = "renderer_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
@ -58,7 +62,7 @@ Suite raii = "renderer_raii"_suite = [] {
});
expect_throw([&] {
ignore = lt::renderer::IRenderer::create(
ignore = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
@ -74,7 +78,7 @@ Suite draw = "renderer_draw"_suite = [] {
Case { "renderer draw" } = [] {
auto fixture = FixtureDeviceSwapchain {};
auto renderer = lt::renderer::IRenderer::create(
auto renderer = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
@ -86,11 +90,16 @@ Suite draw = "renderer_draw"_suite = [] {
{
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" } = [] {
auto fixture = FixtureDeviceSwapchain {};
auto renderer = lt::renderer::IRenderer::create(
auto renderer = lt::renderer::create_renderer(
constants::api,
fixture.gpu(),
fixture.device(),
@ -109,5 +118,10 @@ Suite draw = "renderer_draw"_suite = [] {
{
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>
#include <memory/reference.hpp>
#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;
import renderer.frontend;
import renderer.test_utils;
Suite raii = "surface"_suite = [] {
Case { "happy path won't throw" } = [&] {
auto fixture = Fixture_SurfaceSystem {};
const auto surface = lt::renderer::ISurface::create(
const auto surface = lt::renderer::create_surface(
constants::api,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
fixture.surface_entity()
);
@ -31,9 +22,9 @@ Suite raii = "surface"_suite = [] {
auto system = lt::surface::System(registry);
expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(
std::ignore = lt::renderer::create_surface(
constants::api,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
entity
);
});
@ -47,42 +38,38 @@ Suite raii = "surface"_suite = [] {
);
expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(constants::api, nullptr, entity);
std::ignore = lt::renderer::create_surface(constants::api, nullptr, entity);
});
expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(
std::ignore = lt::renderer::create_surface(
lt::renderer::Api::none,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
entity
);
});
expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(
std::ignore = lt::renderer::create_surface(
lt::renderer::Api::direct_x,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
entity
);
});
expect_throw([&] {
std::ignore = lt::renderer::ISurface::create(
std::ignore = lt::renderer::create_surface(
lt::renderer::Api::metal,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
entity
);
});
// Ensure base creation info is non-throwing
std::ignore = lt::renderer::ISurface::create(
std::ignore = lt::renderer::create_surface(
constants::api,
lt::renderer::IInstance::get(constants::api),
lt::renderer::get_instance(constants::api),
entity
);
};
// TODO(Light): add torture tests
Case { "torture tests" } = [] {
};
};

View file

@ -1,31 +1,16 @@
#include <logger/logger.hpp>
#include <memory/reference.hpp>
#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;
import renderer.frontend;
import renderer.test_utils;
struct SurfaceContext
{
surface::System system;
ecs::Entity entity;
lt::surface::System system;
lt::ecs::Entity entity;
};
struct RendererContext
{
memory::Ref<ecs::Registry> registry;
System system;
lt::memory::Ref<lt::ecs::Registry> registry;
lt::renderer::System system;
};
@ -36,59 +21,62 @@ Suite raii = "system_raii"_suite = [] {
Case { "happy path has no errors" } = [] {
auto fixture = Fixture_RendererSystem {};
expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::error));
expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::warning));
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" } = [] {
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();
expect_throw([=] mutable {
info.registry = nullptr;
ignore = System { info };
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
info.surface_entity = ecs::Entity({}, {});
ignore = System { info };
info.surface_entity = lt::ecs::Entity({}, {});
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::none;
ignore = System { info };
ignore = lt::renderer::System { info };
});
// unsupported Apis
expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::direct_x;
ignore = System { info };
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
info.config.target_api = lt::renderer::Api::metal;
ignore = System { info };
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
constexpr auto limit = lt::renderer::System::frames_in_flight_upper_limit;
info.config.max_frames_in_flight = limit + 1u;
ignore = System { info };
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
constexpr auto limit = lt::renderer::System::frames_in_flight_lower_limit;
info.config.max_frames_in_flight = limit - 1u;
ignore = System { info };
ignore = lt::renderer::System { info };
});
expect_throw([=] mutable {
info.debug_callback_info = lt::renderer::IMessenger::CreateInfo {};
ignore = System { info };
info.debug_callback_info = lt::renderer::IDebugger::CreateInfo {};
ignore = lt::renderer::System { info };
});
// 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 = {
vk::device_extension_names::swapchain,
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(),

View file

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

View file

@ -1,4 +1,5 @@
export module renderer.vk.renderer;
import logger;
import assets.shader;
import debug.assertions;
import renderer.vk.api_wrapper;
@ -17,6 +18,7 @@ import std;
namespace lt::renderer::vkb {
// NOLINTNEXTLINE
export class Renderer: public IRenderer
{
public:
@ -27,6 +29,18 @@ public:
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)
-> Result override;
@ -80,6 +94,10 @@ private:
std::span<components::Sprite::Vertex> m_sprite_vertex_map;
std::size_t m_current_sprite_idx;
vk::DescriptorPool m_global_set_pool;
vk::DescriptorSet m_global_set;
};
} // namespace lt::renderer::vkb
@ -102,7 +120,7 @@ Renderer::Renderer(
device,
gpu,
{
.usage = IBuffer::Usage::vertex,
.usage = IBuffer::Usage::storage,
.size = 1'000'000,
.debug_name = "vertex buffer",
}
@ -116,11 +134,13 @@ Renderer::Renderer(
.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_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(),
{
@ -131,6 +151,16 @@ Renderer::Renderer(
, 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())
, 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))
{
@ -167,19 +197,23 @@ Renderer::Renderer(
record_cmd(cmd, image_idx);
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,
});
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,
}
);
m_device->present_queue().present(vk::Queue::PresentInfo {
.wait_semaphore = &submit_semaphore,
.swapchain = &m_swapchain->vk(),
.image_idx = image_idx,
});
m_device->present_queue().present(
vk::Queue::PresentInfo {
.wait_semaphore = &submit_semaphore,
.swapchain = &m_swapchain->vk(),
.image_idx = image_idx,
}
);
return Result::success;
}
@ -210,136 +244,55 @@ void Renderer::map_buffers(std::uint32_t frame_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_sprite_vertex_map = {};
cmd.begin({});
m_staging_buffer.unmap();
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),
});
cmd.push_constants({
.layout = &m_pass->get_layout(),
.shader_stages = vk::ShaderStageFlags::vertex_bit,
.offset = 0u,
.size = sizeof(FrameConstants),
.data = &m_frame_constants,
});
if (m_current_sprite_idx)
{
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),
}
);
}
cmd.push_constants(
{
.layout = &m_pass->get_pipeline_layout(),
.shader_stages = vk::ShaderStageFlags::vertex_bit,
.offset = 0u,
.size = sizeof(FrameConstants),
.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;
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,
});
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,
}
);
using Attachment = vk::CommandBuffer::RenderingInfo::AttachmentInfo;
cmd.begin_rendering(
@ -350,7 +303,7 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
Attachment{
.view= &m_swapchain->get_image_view(image_idx),
.layout = vk::Image::Layout::color_attachment_optimal,
.load_operation = Attachment::LoadOperation::load,
.load_operation = Attachment::LoadOperation::clear,
.store_operation = Attachment::StoreOperation::store,
.color_clear_values = {.5f, .5f, .5f, 1.f}
}
@ -358,27 +311,39 @@ void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
}
);
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.set_viewport(
{
.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),
.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.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::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();
}

View file

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