Compare commits

..

No commits in common. "vulkan_api_wrapper" and "main" have entirely different histories.

12 changed files with 515 additions and 867 deletions

Binary file not shown.

View file

@ -1,26 +1,25 @@
#version 450 core #version 450 core
layout(push_constant) uniform pc { layout(push_constant ) uniform pc {
mat4 view_projection; mat4 view_projection;
}; };
struct VertexData vec3 positions[3] = vec3[](
{ vec3(0.0, -0.5, 0.5),
vec3 position; vec3(0.5, 0.5, 0.5),
vec3 color; vec3(-0.5, 0.5, 0.5)
}; );
layout(std140, set = 0, binding = 0) readonly buffer Vertices { vec3 colors[3] = vec3[](
vec3(0.0, 0.0, 0.0),
VertexData vertices[]; vec3(0.0, 0.0, 0.0),
} ssbo_vertices; vec3(0.0, 0.0, 0.0)
);
layout(location = 0) out vec3 out_frag_color; layout(location = 0) out vec3 out_frag_color;
void main() void main()
{ {
VertexData vertex = ssbo_vertices.vertices[gl_VertexIndex]; gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0);
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,11 +219,9 @@ 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,28 +1,24 @@
import renderer.frontend; #include <memory/reference.hpp>
import renderer.test_utils; #include <renderer/frontend/renderer/renderer.hpp>
#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::create_renderer( ignore = lt::renderer::IRenderer::create(
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::create_renderer( ignore = lt::renderer::IRenderer::create(
constants::api, constants::api,
nullptr, nullptr,
fixture.device(), fixture.device(),
@ -32,7 +28,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::create_renderer( ignore = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
nullptr, nullptr,
@ -42,7 +38,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::create_renderer( ignore = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -52,7 +48,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::create_renderer( ignore = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -62,7 +58,7 @@ Suite raii = "renderer_raii"_suite = [] {
}); });
expect_throw([&] { expect_throw([&] {
ignore = lt::renderer::create_renderer( ignore = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -78,7 +74,7 @@ Suite draw = "renderer_draw"_suite = [] {
Case { "renderer draw" } = [] { Case { "renderer draw" } = [] {
auto fixture = FixtureDeviceSwapchain {}; auto fixture = FixtureDeviceSwapchain {};
auto renderer = lt::renderer::create_renderer( auto renderer = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -90,16 +86,11 @@ 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::create_renderer( auto renderer = lt::renderer::IRenderer::create(
constants::api, constants::api,
fixture.gpu(), fixture.gpu(),
fixture.device(), fixture.device(),
@ -118,10 +109,5 @@ 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,13 +1,22 @@
import renderer.frontend; #include <logger/logger.hpp>
import renderer.test_utils; #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;
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::create_surface( const auto surface = lt::renderer::ISurface::create(
constants::api, constants::api,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
fixture.surface_entity() fixture.surface_entity()
); );
@ -22,9 +31,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::create_surface( std::ignore = lt::renderer::ISurface::create(
constants::api, constants::api,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
entity entity
); );
}); });
@ -38,38 +47,42 @@ Suite raii = "surface"_suite = [] {
); );
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::create_surface(constants::api, nullptr, entity); std::ignore = lt::renderer::ISurface::create(constants::api, nullptr, entity);
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::create_surface( std::ignore = lt::renderer::ISurface::create(
lt::renderer::Api::none, lt::renderer::Api::none,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
entity entity
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::create_surface( std::ignore = lt::renderer::ISurface::create(
lt::renderer::Api::direct_x, lt::renderer::Api::direct_x,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
entity entity
); );
}); });
expect_throw([&] { expect_throw([&] {
std::ignore = lt::renderer::create_surface( std::ignore = lt::renderer::ISurface::create(
lt::renderer::Api::metal, lt::renderer::Api::metal,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
entity entity
); );
}); });
// Ensure base creation info is non-throwing // Ensure base creation info is non-throwing
std::ignore = lt::renderer::create_surface( std::ignore = lt::renderer::ISurface::create(
constants::api, constants::api,
lt::renderer::get_instance(constants::api), lt::renderer::IInstance::get(constants::api),
entity entity
); );
}; };
// TODO(Light): add torture tests
Case { "torture tests" } = [] {
};
}; };

View file

@ -1,16 +1,31 @@
import renderer.frontend; #include <logger/logger.hpp>
import renderer.test_utils; #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;
struct SurfaceContext struct SurfaceContext
{ {
lt::surface::System system; surface::System system;
lt::ecs::Entity entity; ecs::Entity entity;
}; };
struct RendererContext struct RendererContext
{ {
lt::memory::Ref<lt::ecs::Registry> registry; memory::Ref<ecs::Registry> registry;
lt::renderer::System system; System system;
}; };
@ -21,62 +36,59 @@ 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(lt::renderer::IDebugger::MessageSeverity::error)); expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::error));
expect_false( expect_false(fixture.has_any_messages_of(renderer::IMessenger::MessageSeverity::warning));
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 = lt::ecs::Entity { fixture.registry(), auto empty_entity = ecs::Entity { fixture.registry(), fixture.registry()->create_entity() };
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 = lt::renderer::System { info }; ignore = System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.surface_entity = lt::ecs::Entity({}, {}); info.surface_entity = ecs::Entity({}, {});
ignore = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = System { info };
}); });
expect_throw([=] mutable { expect_throw([=] mutable {
info.debug_callback_info = lt::renderer::IDebugger::CreateInfo {}; info.debug_callback_info = lt::renderer::IMessenger::CreateInfo {};
ignore = lt::renderer::System { info }; ignore = 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 = lt::renderer::System { info }; ignore = System { info };
}; };
}; };

File diff suppressed because it is too large Load diff

View file

@ -100,15 +100,9 @@ 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,16 +25,11 @@ public:
return m_pipeline; return m_pipeline;
} }
[[nodiscard]] auto get_pipeline_layout() -> vk::PipelineLayout & [[nodiscard]] auto get_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 {};
@ -56,30 +51,60 @@ 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,
.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 { // auto pool_size = VkDescriptorPoolSize {
// .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
// .descriptorCount = descriptor_count, // .descriptorCount = descriptor_count,
@ -110,6 +135,7 @@ 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(
@ -136,7 +162,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_strip, .topology = vk::PrimitiveTopology::triangle_list,
.primitive_restart_enabled = true, .primitive_restart_enabled = true,
}, },
.viewport_state = { .viewport_state = {

View file

@ -1,5 +1,4 @@
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;
@ -18,7 +17,6 @@ import std;
namespace lt::renderer::vkb { namespace lt::renderer::vkb {
// NOLINTNEXTLINE
export class Renderer: public IRenderer export class Renderer: public IRenderer
{ {
public: public:
@ -29,18 +27,6 @@ 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;
@ -94,10 +80,6 @@ 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
@ -120,7 +102,7 @@ Renderer::Renderer(
device, device,
gpu, gpu,
{ {
.usage = IBuffer::Usage::storage, .usage = IBuffer::Usage::vertex,
.size = 1'000'000, .size = 1'000'000,
.debug_name = "vertex buffer", .debug_name = "vertex buffer",
} }
@ -134,13 +116,11 @@ Renderer::Renderer(
.debug_name = "staging buffer", .debug_name = "staging buffer",
} }
) )
, m_pass( , m_pass(memory::create_ref<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(),
{ {
@ -151,16 +131,6 @@ 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))
{ {
@ -197,23 +167,19 @@ 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( m_device->graphics_queue().submit(vk::Queue::SubmitInfo {
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( m_device->present_queue().present(vk::Queue::PresentInfo {
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;
} }
@ -244,55 +210,136 @@ 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) .src_buffer = &m_staging_buffer.vk(),
{ .dst_buffer = &m_vertex_buffer.vk(),
cmd.copy( .src_offset = m_staging_offset,
{ .dst_offset = m_staging_offset,
.src_buffer = &m_staging_buffer.vk(), .size = m_current_sprite_idx * sizeof(components::Sprite::Vertex),
.dst_buffer = &m_vertex_buffer.vk(), });
.src_offset = m_staging_offset, cmd.push_constants({
.dst_offset = m_staging_offset, .layout = &m_pass->get_layout(),
.size = m_current_sprite_idx * sizeof(components::Sprite::Vertex), .shader_stages = vk::ShaderStageFlags::vertex_bit,
} .offset = 0u,
); .size = sizeof(FrameConstants),
} .data = &m_frame_constants,
});
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; 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, .dst_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.dst_stages = vk::PipelineStageFlags::color_attachment_output_bit, .src_accesses = AccessFlagBits::none,
.src_accesses = AccessFlagBits::none, .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(
@ -303,7 +350,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::clear, .load_operation = Attachment::LoadOperation::load,
.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}
} }
@ -311,39 +358,27 @@ 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();
.origin = {}, cmd.draw({
.extent = { static_cast<float>(m_resolution.x), static_cast<float>(m_resolution.y) }, .vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx),
.min_depth = 0.0f, .instance_count = 1u,
.max_depth = 1.0f, .first_vertex = 0u,
} .first_instance = 0u,
); });
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.end_rendering();
cmd.image_barrier( cmd.image_barrier({
{ .image = &m_swapchain->get_image(image_idx),
.image = &m_swapchain->get_image(image_idx), .src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
.range = vk::Image::full_color_range, .dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit,
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit, .src_accesses = AccessFlagBits::color_attachment_read
.dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit, | AccessFlagBits::color_attachment_write,
.src_accesses = AccessFlagBits::color_attachment_read .dst_accesses = {},
| AccessFlagBits::color_attachment_write, .src_layout = vk::Image::Layout::color_attachment_optimal,
.dst_accesses = {}, .dst_layout = vk::Image::Layout::present_src,
.src_layout = vk::Image::Layout::color_attachment_optimal,
.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$'
) )