From c269423f9b437a726365a20b8ad15f3380df32e5 Mon Sep 17 00:00:00 2001 From: light7734 Date: Sat, 13 Dec 2025 14:23:33 +0330 Subject: [PATCH 1/4] fix vk tests & implemented missing api wrapper features --- data/test_assets/sprite.vert.asset | Bin 2128 -> 2132 bytes data/test_assets/triangle.vert | 29 +- data/test_assets/triangle.vert.asset | Bin 1736 -> 1964 bytes modules/renderer/_tests/renderer.cpp | 36 +- modules/renderer/_tests/surface.cpp | 43 +- modules/renderer/_tests/system.cpp | 58 +- modules/renderer/vk/api_wrapper.cppm | 843 ++++++++++++++++++++------- modules/renderer/vk/device.cppm | 8 +- modules/renderer/vk/pass.cppm | 74 +-- modules/renderer/vk/renderer.cppm | 285 ++++----- 10 files changed, 863 insertions(+), 513 deletions(-) diff --git a/data/test_assets/sprite.vert.asset b/data/test_assets/sprite.vert.asset index 7514cd62137d4e341757e77440832840ce9cb4e5..3c5a817a300cd342ca140d1f931285de1e214427 100644 GIT binary patch delta 43 ucmca0a7AE(45tPM0~ly*RE=a5WMvQr^2$<+N>VH0QxZ!OH+M50Wdi`slnTrM delta 39 qcmca2a6w>#45tbQ0~n}mRE=chWnmBo@`{U-@(mdnHup0gWdi`5R|pgU diff --git a/data/test_assets/triangle.vert b/data/test_assets/triangle.vert index 0496de0..8847b81 100644 --- a/data/test_assets/triangle.vert +++ b/data/test_assets/triangle.vert @@ -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; } diff --git a/data/test_assets/triangle.vert.asset b/data/test_assets/triangle.vert.asset index 6ffe543338103f1abd95693b80da0350c1a500a6..52d90f04e6a946bcbf206169de94c6942741aab7 100644 GIT binary patch literal 1964 zcmZXUYflqV5Qa}FyLbf=xu{SJcn1*`(8Q=AmK2jFpd^0X)a^>vtlg%&Ao_`)pnu6< zM_HadFOIw-r0JvyWQA%7r0|8#;lt1oQ@TWyQ?G1W5%zT^X8&?TE_4ji-?qW#uFiq0FZt5}3vCYT!#KHgdz&QWb1OL08CsvF6 zIE*rK=m(6$I}Z1R!&{bpNP{5OCSkK@?II*k6oE=ii&*9G0aq;Bo1<(4^i z<#RmGS-aSU)WQ2r^#bSksfF(PcJ`7m4mNwBulv@nT0V=nJgW;H^i99)hko66;V^Q* zsuG8xgYiAn7k#)nTu+`b;+@S;86Ji)#~1y=ZB4?NQZ?!=sy1(-&q#CJ%_^RH*!XL* z`7MDVb=hZ29UMRXI{$*Q*acWkI^1KEH(u&s&r2Jw@lVTUhPtF8St;#F=^XMe>&8bM z`Pl3N4F9xl_cn7}mCYP*N&RcO>kn4wP;b2jB-O8w0(hYxL^x~~MvK_bdOn-cL#+<$)eq9>x@*ei% z(k6%c*zBJe$LWUjieyXQ5c{W34l%!k@O_a>pZq^atrxQ4{fY$6x77)J&q&xId%{N? zyPuWd`(7!&AAVb4FZBvFvA6XS^WKuc0X4|4>%J`kCk77gO2~6D^mMPp-zo-PR!U5l zaoB2!F|WfOlo+$`YdW}FlaNn5emMT2y7(SS=!Y2kf%8Wac1}OcgiW05cT+n3!ZkC| R@0J9dcy@yQTbp<$`2&qHo?-w1 literal 1736 zcmYk6+fEZv6oz+84~POHa!?Tms-l2+0>l_4L`X4d0!rfTgiJ>=W}Io-DITtT1@CXwvKMuR^!)_LS5fp2AYEWvXkhW zx+BN>m`lFban#w5df90bgaaSj!q<=Efv>7vupbV#C*28bJ#5Z-6n^$Q-Si{NNRvE{ zeR7zAy{fJq;7!tI3V3#%_A~!O_w>xqhc>3EZ!j}`9x4i(V{h+2$Bb}j7e@{pb2ttg zj@?t+leV=hxh<%#*mw`1QrGia^O5+zD+*-ivshO;mAjiOE?ZsSoq7~NsD*a z747CFhd6wWpDHliFn>kZ#X6pTrX}o-JYrmbyleV$b!TMrJty$w&r0w)VPA8?I!6hRr>32Yd21q;E@@gFU=d1^T}ufd|w7Jqf*& zL*J_sYQhs^XR!QR#W2?c$(n@YxDDBG?8R{p3y%JeRf&1|b0?p8{Osk2>f(DWp+92i ohdn)&aL>%Zj9}ti|J$;M`+p|P9^hU7JF?-)XRqMD>U2l)4>+2EzW@LL diff --git a/modules/renderer/_tests/renderer.cpp b/modules/renderer/_tests/renderer.cpp index 8e35aeb..6edd944 100644 --- a/modules/renderer/_tests/renderer.cpp +++ b/modules/renderer/_tests/renderer.cpp @@ -1,24 +1,28 @@ -#include -#include -#include +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) + ); }; }; diff --git a/modules/renderer/_tests/surface.cpp b/modules/renderer/_tests/surface.cpp index 5265893..26b52a9 100644 --- a/modules/renderer/_tests/surface.cpp +++ b/modules/renderer/_tests/surface.cpp @@ -1,22 +1,13 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -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" } = [] { - }; }; diff --git a/modules/renderer/_tests/system.cpp b/modules/renderer/_tests/system.cpp index 0bc6dd0..350f6b0 100644 --- a/modules/renderer/_tests/system.cpp +++ b/modules/renderer/_tests/system.cpp @@ -1,31 +1,16 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 registry; - System system; + lt::memory::Ref 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 }; }; }; diff --git a/modules/renderer/vk/api_wrapper.cppm b/modules/renderer/vk/api_wrapper.cppm index 8f6b511..29dfc4a 100644 --- a/modules/renderer/vk/api_wrapper.cppm +++ b/modules/renderer/vk/api_wrapper.cppm @@ -102,7 +102,7 @@ namespace device_extension_names { constexpr auto swapchain = VK_KHR_SWAPCHAIN_EXTENSION_NAME; constexpr auto dynamic_rendering = VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME; - +constexpr auto descriptor_indexing = VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME; }; // namespace device_extension_names @@ -688,6 +688,24 @@ enum class Format : std::underlying_type_t }; +struct Viewport +{ + math::vec2 origin; + + math::vec2 extent; + + float min_depth {}; + + float max_depth {}; +}; + +struct Rect2d +{ + math::ivec2 offset; + + math::uvec2 extent; +}; + /** There is no global state in Vulkan and all per-application state is stored in a VkInstance * object. Creating a VkInstance object initializes the Vulkan library and allows the application to * pass information about itself to the implementation. @@ -842,12 +860,12 @@ public: private: [[nodiscard]] auto get_vk_handle() -> VkSurfaceKHR { - return m_surface.get(); + return m_surface; } - memory::NullOnMove m_surface {}; + memory::NullOnMove m_instance {}; - VkInstance m_instance {}; + VkSurfaceKHR m_surface {}; }; class Gpu @@ -1175,6 +1193,9 @@ public: friend class Fence; friend class ShaderModule; friend class DescriptorSetLayout; + friend class PipelineLayout; + friend class CommandPool; + friend class DescriptorPool; struct CreateInfo { @@ -1436,6 +1457,7 @@ class Buffer public: friend class Device; friend class Memory; + friend class CommandBuffer; static constexpr auto object_type = VK_OBJECT_TYPE_BUFFER; @@ -1521,10 +1543,9 @@ class Image { public: friend class Device; - friend class Swapchain; - friend class ImageView; + friend class CommandBuffer; static constexpr auto object_type = VK_OBJECT_TYPE_IMAGE_VIEW; @@ -1666,6 +1687,7 @@ class ImageView { public: friend class Device; + friend class CommandBuffer; static constexpr auto object_type = VK_OBJECT_TYPE_IMAGE_VIEW; @@ -1770,13 +1792,13 @@ private: VkShaderModule m_shader_module {}; }; -class DescriptorPool -{ -}; - class DescriptorSet { public: + friend class Device; + friend class DescriptorPool; + friend class CommandBuffer; + enum class Type : std::underlying_type_t { sampler = VK_DESCRIPTOR_TYPE_SAMPLER, @@ -1800,11 +1822,42 @@ public: partitioned_acceleration_structure_nv = VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, }; + + DescriptorSet() = default; + + DescriptorSet(DescriptorSet &&) = default; + + DescriptorSet(const DescriptorSet &) = delete; + + auto operator=(DescriptorSet &&) -> DescriptorSet & = default; + + auto operator=(const DescriptorSet &) -> DescriptorSet & = delete; + + ~DescriptorSet() = default; + +private: + [[nodiscard]] auto get_vk_handle() -> VkDescriptorSet + { + return m_descriptor_set; + } + + [[nodiscard]] auto get_vk_handle_addr() -> VkDescriptorSet * + { + return &m_descriptor_set; + } + + DescriptorSet(VkDescriptorSet descriptor_set); + + VkDescriptorSet m_descriptor_set {}; }; class DescriptorSetLayout { public: + friend class Device; + friend class PipelineLayout; + friend class DescriptorPool; + static constexpr auto object_type = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT; struct Binding @@ -1864,18 +1917,77 @@ public: ~DescriptorSetLayout(); private: - auto get_vk_handle() -> VkDescriptorSetLayout + [[nodiscard]] auto get_vk_handle() -> VkDescriptorSetLayout { return m_descriptor_set_layout; } - memory::NullOnMove m_device; - VkDescriptorSetLayout m_descriptor_set_layout; + [[nodiscard]] auto get_vk_handle_addr() -> VkDescriptorSetLayout * + { + return &m_descriptor_set_layout; + } + + memory::NullOnMove m_device {}; + + VkDescriptorSetLayout m_descriptor_set_layout {}; +}; + +class DescriptorPool +{ +public: + friend class Device; + + static constexpr auto object_type = VK_OBJECT_TYPE_DESCRIPTOR_POOL; + + struct Size + { + DescriptorSet::Type type; + + std::uint32_t count; + }; + + struct CreateInfo + { + std::vector sizes; + + std::uint32_t max_sets; + + std::string_view name; + }; + + DescriptorPool() = default; + + DescriptorPool(Device &device, CreateInfo info); + + DescriptorPool(DescriptorPool &&) = default; + + DescriptorPool(const DescriptorPool &) = delete; + + auto operator=(DescriptorPool &&) -> DescriptorPool & = default; + + auto operator=(const DescriptorPool &) -> DescriptorPool & = delete; + + ~DescriptorPool(); + + [[nodiscard]] auto allocate(DescriptorSetLayout &layout) -> DescriptorSet; + +private: + [[nodiscard]] auto get_vk_handle() -> VkDescriptorPool + { + return m_descriptor_pool; + } + + memory::NullOnMove m_device {}; + + VkDescriptorPool m_descriptor_pool {}; }; class Pipeline { public: + friend class Device; + friend class CommandBuffer; + static constexpr auto object_type = VK_OBJECT_TYPE_PIPELINE; enum class BindPoint : std::underlying_type_t @@ -1998,6 +2110,11 @@ public: ~Pipeline(); private: + [[nodiscard]] auto get_vk_handle() -> VkPipeline + { + return m_pipeline; + } + memory::NullOnMove m_device {}; VkPipeline m_pipeline {}; @@ -2007,6 +2124,8 @@ class PipelineLayout { public: friend class Pipeline; + friend class Device; + friend class CommandBuffer; static constexpr auto object_type = VK_OBJECT_TYPE_PIPELINE_LAYOUT; @@ -2022,6 +2141,8 @@ public: std::vector descriptor_set_layouts; std::vector push_constant_ranges; + + std::string_view name; }; PipelineLayout() = default; @@ -2054,6 +2175,7 @@ class CommandBuffer public: friend class Device; friend class Queue; + friend class CommandPool; struct BeginInfo { @@ -2183,7 +2305,7 @@ public: Flags resolve_mode_flags; }; - math::uvec2 area_offset; + math::ivec2 area_offset; math::uvec2 area_extent; @@ -2201,7 +2323,7 @@ public: std::uint32_t first_instance; }; - CommandBuffer() = default; // WIP + CommandBuffer() = default; CommandBuffer(CommandBuffer &&) = default; @@ -2211,43 +2333,39 @@ public: auto operator=(const CommandBuffer &) -> CommandBuffer & = delete; - void begin(BeginInfo info = {}) - { - } + void begin(BeginInfo info = {}); - void end() - { - } + void end(); - void copy(BufferCopyInfo info) - { - } + void copy(BufferCopyInfo info); - void push_constants(PushConstantsInfo info) - { - } + void push_constants(PushConstantsInfo info); - void image_barrier(ImageBarrierInfo info) - { - } + void image_barrier(ImageBarrierInfo info); - void begin_rendering(RenderingInfo info) - { - } + void begin_rendering(RenderingInfo info); - void end_rendering() - { - } + void end_rendering(); - void bind_pipeline(Pipeline &pipeline, Pipeline::BindPoint bind_point) - { - } + void bind_pipeline(Pipeline &pipeline, Pipeline::BindPoint bind_point); + + void draw(DrawInfo info); + + void set_viewport(Viewport viewport); + + void set_scissor(Rect2d scissor); + + void bind_descriptor_set( + DescriptorSet &set, + Pipeline::BindPoint bind_point, + PipelineLayout &layout, + uint32_t idx + ); - void draw(DrawInfo info) - { - } private: + CommandBuffer(VkCommandBuffer buffer); + [[nodiscard]] auto get_vk_handle() -> VkCommandBuffer { return m_buffer; @@ -2264,6 +2382,10 @@ private: class CommandPool { public: + friend class Device; + + static constexpr auto object_type = VK_OBJECT_TYPE_COMMAND_POOL; + struct CreateInfo { enum FlagBits : std::underlying_type_t @@ -2274,6 +2396,8 @@ public: }; Flags flags; + + std::string_view name; }; enum class BufferLevel @@ -2284,15 +2408,9 @@ public: CommandPool() = default; - CommandPool(Device &device, CreateInfo info) - { - // WIP - } + CommandPool(Device &device, CreateInfo info); - ~CommandPool() - { - // WIP - } + ~CommandPool(); CommandPool(CommandPool &&) = default; @@ -2302,14 +2420,15 @@ public: auto operator=(const CommandPool &) -> CommandPool & = delete; - [[nodiscard]] auto allocate(uint32_t count, BufferLevel level) -> std::vector - { - // WIP - return {}; - } + [[nodiscard]] auto allocate(uint32_t count, BufferLevel level) -> std::vector; private: - VkDevice m_device {}; + [[nodiscard]] auto get_vk_handle() -> VkCommandPool + { + return m_pool; + } + + memory::NullOnMove m_device {}; VkCommandPool m_pool {}; }; @@ -2698,6 +2817,7 @@ PFN_vkDestroyPipeline destroy_pipeline {}; PFN_vkCmdBeginRenderPass cmd_begin_render_pass {}; PFN_vkCmdEndRenderPass cmd_end_render_pass {}; PFN_vkCmdBindPipeline cmd_bind_pipeline {}; +PFN_vkCmdBindDescriptorSets cmd_bind_descriptor_sets {}; PFN_vkCmdDraw cmd_draw {}; PFN_vkCmdSetViewport cmd_set_viewport {}; PFN_vkCmdSetScissor cmd_set_scissors {}; @@ -2898,6 +3018,7 @@ void Device::load_functions() load_fn(api::cmd_begin_render_pass, "vkCmdBeginRenderPass"); load_fn(api::cmd_end_render_pass, "vkCmdEndRenderPass"); load_fn(api::cmd_bind_pipeline, "vkCmdBindPipeline"); + load_fn(api::cmd_bind_descriptor_sets, "vkCmdBindDescriptorSets"); load_fn(api::cmd_draw, "vkCmdDraw"); load_fn(api::cmd_set_viewport, "vkCmdSetViewport"); load_fn(api::cmd_set_scissors, "vkCmdSetScissor"); @@ -2979,16 +3100,6 @@ Instance::Instance(CreateInfo info) } } - log::debug("Settings size: {}", layer_settings.size()); - log::debug("Settings:"); - for (auto &setting : layer_settings) - { - log::debug("\tpValues: {}", (std::size_t)setting.pValues); - log::debug("\tname: {}", setting.pSettingName); - log::debug("\tlayer name: {}", setting.pLayerName); - log::debug("\ttype: {}", std::to_underlying(setting.type)); - log::debug("\tvalue count: {}", setting.valueCount); - } const auto layer_settings_create_info = VkLayerSettingsCreateInfoEXT { .sType = VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, .settingCount = static_cast(layer_settings.size()), @@ -3014,18 +3125,12 @@ Instance::Instance(CreateInfo info) .pApplicationInfo = &app_info, }; - log::debug("Extension names:"); - for (auto &extension_name : extension_names) - { - log::debug("\t{}", extension_name); - } - - log::debug("Create instance: {}", (std::size_t)(api::create_instance)); vkc(api::create_instance(&vk_info, nullptr, &m_instance)); debug::ensure(m_instance, "Failed to create vulkan instance"); } -Surface::Surface(const Instance &instance, const CreateInfo &info): m_instance(instance.m_instance) +Surface::Surface(const Instance &instance, const CreateInfo &info) + : m_instance(instance.m_instance.get()) { #if defined(LIGHT_PLATFORM_LINUX) const auto vk_info = VkXlibSurfaceCreateInfoKHR { @@ -3056,7 +3161,10 @@ Surface::Surface(const Instance &instance, const CreateInfo &info): m_instance(i Surface::~Surface() { - api::destroy_surface_khr(m_instance, m_surface, nullptr); + if (m_instance) + { + api::destroy_surface_khr(m_instance, m_surface, nullptr); + } } [[nodiscard]] @@ -3160,7 +3268,6 @@ Surface::~Surface() }; api::get_physical_device_features(m_physical_device, &features_2); - log::debug("Dynamic rendering features: {}", features.dynamicRendering); return DynamicRenderingFeatures { .enabled = !!features.dynamicRendering, }; @@ -3181,26 +3288,26 @@ Surface::~Surface() api::get_physical_device_features(m_physical_device, &features_2); return DescriptorIndexingFeatures { // clang-format off - .shader_input_attachment_array_dynamic_indexing =false, - .shader_uniform_texel_buffer_array_dynamic_indexing =false, - .shader_storage_texel_buffer_array_dynamic_indexing =false, - .shader_uniform_buffer_array_non_uniform_indexing =false, - .shader_sampled_image_array_non_uniform_indexing =false, - .shader_storage_buffer_array_non_uniform_indexing =false, - .shader_storage_image_array_non_uniform_indexing =false, - .shader_input_attachment_array_non_uniform_indexing =false, - .shader_uniform_texel_buffer_array_non_uniform_indexing =false, - .shader_storage_texel_buffer_array_non_uniform_indexing =false, - .descriptor_binding_uniform_buffer_update_after_bind =false, - .descriptor_binding_sampled_image_update_after_bind =false, - .descriptor_binding_storage_image_update_after_bind =false, - .descriptor_binding_storage_buffer_update_after_bind =false, - .descriptor_binding_uniform_texel_buffer_update_after_bind =false, - .descriptor_binding_storage_texel_buffer_update_after_bind =false, - .descriptor_binding_update_unused_while_pending =false, - .descriptor_binding_partially_bound =false, - .descriptor_binding_variable_descriptor_count =false, - .runtime_descriptor_array =false, + .shader_input_attachment_array_dynamic_indexing =true, + .shader_uniform_texel_buffer_array_dynamic_indexing =true, + .shader_storage_texel_buffer_array_dynamic_indexing =true, + .shader_uniform_buffer_array_non_uniform_indexing =true, + .shader_sampled_image_array_non_uniform_indexing =true, + .shader_storage_buffer_array_non_uniform_indexing =true, + .shader_storage_image_array_non_uniform_indexing =true, + .shader_input_attachment_array_non_uniform_indexing =true, + .shader_uniform_texel_buffer_array_non_uniform_indexing =true, + .shader_storage_texel_buffer_array_non_uniform_indexing =true, + .descriptor_binding_uniform_buffer_update_after_bind =true, + .descriptor_binding_sampled_image_update_after_bind =true, + .descriptor_binding_storage_image_update_after_bind =true, + .descriptor_binding_storage_buffer_update_after_bind =true, + .descriptor_binding_uniform_texel_buffer_update_after_bind =true, + .descriptor_binding_storage_texel_buffer_update_after_bind =true, + .descriptor_binding_update_unused_while_pending =true, + .descriptor_binding_partially_bound =true, + .descriptor_binding_variable_descriptor_count =true, + .runtime_descriptor_array =true, // clang-format on }; } @@ -3556,7 +3663,7 @@ Device::Device(const Gpu &gpu, CreateInfo info) vk_extension_names.emplace_back(extension.c_str()); } - const auto vk_features = VkPhysicalDeviceFeatures { + const auto vk_physical_device_features = VkPhysicalDeviceFeatures { // clang-format off .robustBufferAccess = info.features.robust_buffer_access, .fullDrawIndexUint32 = info.features.full_draw_index_uint32, @@ -3616,128 +3723,71 @@ Device::Device(const Gpu &gpu, CreateInfo info) // clang-format on }; - auto vk_features_2 = VkPhysicalDeviceFeatures2 { + auto vk_physical_device_features2 = VkPhysicalDeviceFeatures2 { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, .pNext = {}, - .features = vk_features, + .features = vk_physical_device_features, }; - auto vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures {}; - - // log::debug("Dynamic rendering: {}", vk_dynamic_rendering_features.dynamicRendering); - // void **last_p_next = &vk_features_2.pNext; - - if (info.dynamic_rendering_features) - { - // *last_p_next = &vk_dynamic_rendering_features; - // last_p_next = &vk_dynamic_rendering_features.pNext; - } - - // if (info.descriptor_indexing_features) - // { - // const auto features = *info.descriptor_indexing_features; - // vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures { - // .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, - // .pNext = {}, - // // clang-format off - // .shaderInputAttachmentArrayDynamicIndexing = - // features.shader_input_attachment_array_dynamic_indexing, - // .shaderUniformTexelBufferArrayDynamicIndexing = - // features.shader_uniform_texel_buffer_array_dynamic_indexing, - // .shaderStorageTexelBufferArrayDynamicIndexing = - // features.shader_storage_texel_buffer_array_dynamic_indexing, - // .shaderUniformBufferArrayNonUniformIndexing = - // features.shader_uniform_buffer_array_non_uniform_indexing, - // .shaderSampledImageArrayNonUniformIndexing = - // features.shader_sampled_image_array_non_uniform_indexing, - // .shaderStorageBufferArrayNonUniformIndexing = - // features.shader_storage_buffer_array_non_uniform_indexing, - // .shaderStorageImageArrayNonUniformIndexing = - // features.shader_storage_image_array_non_uniform_indexing, - // .shaderInputAttachmentArrayNonUniformIndexing = - // features.shader_input_attachment_array_non_uniform_indexing, - // .shaderUniformTexelBufferArrayNonUniformIndexing = - // features.shader_uniform_texel_buffer_array_non_uniform_indexing, - // .shaderStorageTexelBufferArrayNonUniformIndexing = - // features.shader_storage_texel_buffer_array_non_uniform_indexing, - // .descriptorBindingUniformBufferUpdateAfterBind = - // features.descriptor_binding_uniform_buffer_update_after_bind, - // .descriptorBindingSampledImageUpdateAfterBind = - // features.descriptor_binding_sampled_image_update_after_bind, - // .descriptorBindingStorageImageUpdateAfterBind = - // features.descriptor_binding_storage_image_update_after_bind, - // .descriptorBindingStorageBufferUpdateAfterBind = - // features.descriptor_binding_storage_buffer_update_after_bind, - // .descriptorBindingUniformTexelBufferUpdateAfterBind = - // features.descriptor_binding_uniform_texel_buffer_update_after_bind, - // .descriptorBindingStorageTexelBufferUpdateAfterBind = - // features.descriptor_binding_storage_texel_buffer_update_after_bind, - // .descriptorBindingUpdateUnusedWhilePending = - // features.descriptor_binding_update_unused_while_pending, - // .descriptorBindingPartiallyBound = features.descriptor_binding_partially_bound, - // .descriptorBindingVariableDescriptorCount = - // features.descriptor_binding_variable_descriptor_count, .runtimeDescriptorArray = - // features.runtime_descriptor_array, - // // clang-format on - // }; - // - // // *last_p_next = &vk_descriptor_indexing_features; - // // last_p_next = &vk_descriptor_indexing_features.pNext; - // } - - auto physical_device_features = VkPhysicalDeviceFeatures { - .geometryShader = true, - .samplerAnisotropy = true, - .multiDrawIndirect = true, - .drawIndirectFirstInstance = true, - }; - auto vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, - .pNext = {}, - .dynamicRendering = true, - }; auto vk_info = VkDeviceCreateInfo { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = &vk_dynamic_rendering_features, + .pNext = &vk_physical_device_features2, .queueCreateInfoCount = static_cast(vk_queue_infos.size()), .pQueueCreateInfos = vk_queue_infos.data(), .enabledExtensionCount = static_cast(vk_extension_names.size()), .ppEnabledExtensionNames = vk_extension_names.data(), - .pEnabledFeatures = &physical_device_features, + .pEnabledFeatures = {}, // replaced by vk_physical_device_features2 }; - log::debug("sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO"); - log::debug("*pNext (dynamic rendering features):"); - log::debug("\tsType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES"); - log::debug("\tdynamicRendering = {}", vk_dynamic_rendering_features.dynamicRendering); - log::debug("\tpNext = {}", vk_dynamic_rendering_features.pNext); + void **last_p_next = &vk_physical_device_features2.pNext; + auto vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures {}; + auto vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {}; - log::debug("queueCreateInfoCount: {}", static_cast(vk_queue_infos.size())); - log::debug("*pQueueCreateInfos:"); - for (auto &info : vk_queue_infos) + if (info.dynamic_rendering_features) { - log::debug("\tsType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO"); - log::debug("\tpNext: {}", info.pNext); - log::debug("\tqueueCount: {}", info.queueCount); - log::debug("\tqueueFamilyIndex: {}", info.queueFamilyIndex); - log::debug("\t*pQueuePriorities: {}", *info.pQueuePriorities); - log::debug("----"); + vk_dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + .pNext = {}, + .dynamicRendering = true, + }; + + *last_p_next = &vk_dynamic_rendering_features; + last_p_next = &vk_dynamic_rendering_features.pNext; } - log::debug("enabledExtensionCount: {}", vk_info.enabledExtensionCount); - for (const auto *name : vk_extension_names) + if (info.descriptor_indexing_features) { - log::debug("\t{}", name); - } - log::debug("*pEnabledFeatures:"); - log::debug("\t.geometryShader = {}", physical_device_features.geometryShader); - log::debug("\t.samplerAnisotropy = {}", physical_device_features.samplerAnisotropy); - log::debug("\t.multiDrawIndirect = {}", physical_device_features.multiDrawIndirect); - log::debug( - "\t.drawIndirectFirstInstance = {}", - physical_device_features.drawIndirectFirstInstance - ); + const auto &features = *info.descriptor_indexing_features; + vk_descriptor_indexing_features = VkPhysicalDeviceDescriptorIndexingFeatures { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + .pNext = {}, + // clang-format off + .shaderInputAttachmentArrayDynamicIndexing = features.shader_input_attachment_array_dynamic_indexing, + .shaderUniformTexelBufferArrayDynamicIndexing = features.shader_uniform_texel_buffer_array_dynamic_indexing, + .shaderStorageTexelBufferArrayDynamicIndexing = features.shader_storage_texel_buffer_array_dynamic_indexing, + .shaderUniformBufferArrayNonUniformIndexing = features.shader_uniform_buffer_array_non_uniform_indexing, + .shaderSampledImageArrayNonUniformIndexing = features.shader_sampled_image_array_non_uniform_indexing, + .shaderStorageBufferArrayNonUniformIndexing = features.shader_storage_buffer_array_non_uniform_indexing, + .shaderStorageImageArrayNonUniformIndexing = features.shader_storage_image_array_non_uniform_indexing, + .shaderInputAttachmentArrayNonUniformIndexing = features.shader_input_attachment_array_non_uniform_indexing, + .shaderUniformTexelBufferArrayNonUniformIndexing = features.shader_uniform_texel_buffer_array_non_uniform_indexing, + .shaderStorageTexelBufferArrayNonUniformIndexing = features.shader_storage_texel_buffer_array_non_uniform_indexing, + .descriptorBindingUniformBufferUpdateAfterBind = features.descriptor_binding_uniform_buffer_update_after_bind, + .descriptorBindingSampledImageUpdateAfterBind = features.descriptor_binding_sampled_image_update_after_bind, + .descriptorBindingStorageImageUpdateAfterBind = features.descriptor_binding_storage_image_update_after_bind, + .descriptorBindingStorageBufferUpdateAfterBind = features.descriptor_binding_storage_buffer_update_after_bind, + .descriptorBindingUniformTexelBufferUpdateAfterBind = features.descriptor_binding_uniform_texel_buffer_update_after_bind, + .descriptorBindingStorageTexelBufferUpdateAfterBind = features.descriptor_binding_storage_texel_buffer_update_after_bind, + .descriptorBindingUpdateUnusedWhilePending = features.descriptor_binding_update_unused_while_pending, + .descriptorBindingPartiallyBound = features.descriptor_binding_partially_bound, + .descriptorBindingVariableDescriptorCount = features.descriptor_binding_variable_descriptor_count, + .runtimeDescriptorArray = features.runtime_descriptor_array, + // clang-format on + }; + *last_p_next = &vk_descriptor_indexing_features; + last_p_next = &vk_descriptor_indexing_features.pNext; + } vkc(api::create_device(gpu.m_physical_device, &vk_info, nullptr, &m_device)); } @@ -3746,7 +3796,6 @@ Device::~Device() { if (m_device) { - log::debug("Destrying device"); api::destroy_device(m_device, nullptr); } } @@ -4216,6 +4265,242 @@ ImageView::~ImageView() } } +CommandBuffer::CommandBuffer(VkCommandBuffer buffer): m_buffer(buffer) +{ +} + +void CommandBuffer::begin(BeginInfo info /* = {} */) +{ + auto vk_info = VkCommandBufferBeginInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = {}, + .flags = {}, + .pInheritanceInfo = {}, + }; + + vkc(api::begin_command_buffer(m_buffer, &vk_info)); +} + +void CommandBuffer::end() +{ + vkc(api::end_command_buffer(m_buffer)); +} + +void CommandBuffer::copy(BufferCopyInfo info) +{ + auto vk_copy_region = VkBufferCopy { + .srcOffset = info.src_offset, + .dstOffset = info.dst_offset, + .size = info.size, + }; + + api::cmd_copy_buffer( + m_buffer, + info.src_buffer->get_vk_handle(), + info.dst_buffer->get_vk_handle(), + 1u, + &vk_copy_region + ); +} + +void CommandBuffer::push_constants(PushConstantsInfo info) +{ + api::cmd_push_constants( + m_buffer, + info.layout->get_vk_handle(), + info.shader_stages, + info.offset, + info.size, + info.data + ); +} + +void CommandBuffer::image_barrier(ImageBarrierInfo info) +{ + auto vk_barrier = VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = {}, + .srcAccessMask = info.src_accesses, + .dstAccessMask = info.dst_accesses, + .oldLayout = static_cast(info.src_layout), + .newLayout = static_cast(info.dst_layout), + .srcQueueFamilyIndex = {}, + .dstQueueFamilyIndex = {}, + .image = info.image->get_vk_handle(), + .subresourceRange = { + .aspectMask = info.range.aspect_flags, + .baseMipLevel = info.range.base_mip_level, + .levelCount = info.range.level_count, + .baseArrayLayer = info.range.base_array_layer, + .layerCount = info.range.layer_count, + }, + }; + + api::cmd_pipeline_barrier( + m_buffer, + info.src_stages, + info.dst_stages, + {}, + {}, + {}, + {}, + {}, + 1u, + &vk_barrier + ); +} + +void CommandBuffer::begin_rendering(RenderingInfo info) +{ + auto vk_color_attachments = std::vector {}; + for (auto attachment : info.color_attachments) + { + vk_color_attachments.emplace_back( + VkRenderingAttachmentInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .pNext = {}, + .imageView = attachment.view->get_vk_handle(), + .imageLayout = static_cast(attachment.layout), + .resolveMode = static_cast(attachment.resolve_mode_flags), + .loadOp = static_cast(attachment.load_operation), + .storeOp = static_cast(attachment.store_operation), + .clearValue = { .color { .float32 = { attachment.color_clear_values[0], attachment.color_clear_values[1], attachment.color_clear_values[2], attachment.color_clear_values[3], } } }, + } + ); + } + + auto vk_info = VkRenderingInfo + { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .pNext = {}, .flags = {}, + .renderArea = { + .offset = {info.area_offset.x, info.area_offset.y}, + .extent = {info.area_extent.x, info.area_extent.y}, + }, + .layerCount = 1u, + .colorAttachmentCount = static_cast(vk_color_attachments.size()), + .pColorAttachments= vk_color_attachments.data(), + }; + + api::cmd_begin_rendering(m_buffer, &vk_info); +} + +void CommandBuffer::end_rendering() +{ + api::cmd_end_rendering(m_buffer); +} + +void CommandBuffer::bind_pipeline(Pipeline &pipeline, Pipeline::BindPoint bind_point) +{ + api::cmd_bind_pipeline( + m_buffer, + static_cast(bind_point), + pipeline.get_vk_handle() + ); +} + +void CommandBuffer::bind_descriptor_set( + DescriptorSet &set, + Pipeline::BindPoint bind_point, + PipelineLayout &layout, + uint32_t idx +) +{ + api::cmd_bind_descriptor_sets( + m_buffer, + static_cast(bind_point), + layout.get_vk_handle(), + idx, + 1u, + set.get_vk_handle_addr(), + 0u, + {} + ); +} + +void CommandBuffer::draw(DrawInfo info) +{ + api::cmd_draw( + m_buffer, + info.vertex_count, + info.instance_count, + info.first_vertex, + info.first_instance + ); +} + +void CommandBuffer::set_viewport(Viewport viewport) +{ + auto vk_viewport = VkViewport { + .x = viewport.origin.x, + .y = viewport.origin.y, + .width = viewport.extent.x, + .height = viewport.extent.y, + .minDepth = viewport.min_depth, + .maxDepth = viewport.max_depth, + }; + api::cmd_set_viewport(m_buffer, 0u, 1u, &vk_viewport); +} + +void CommandBuffer::set_scissor(Rect2d scissor) +{ + auto vk_scissor = VkRect2D { + .offset = { .x = scissor.offset.x, .y = scissor.offset.y }, + .extent = { .width = scissor.extent.x, .height = scissor.extent.y }, + }; + api::cmd_set_scissors(m_buffer, 0u, 1u, &vk_scissor); +} + +CommandPool::CommandPool(Device &device, CreateInfo info): m_device(device.get_vk_handle()) +{ + auto vk_info = VkCommandPoolCreateInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = info.flags, + .pNext = {}, + .queueFamilyIndex = {}, + }; + + vkc(api::create_command_pool(m_device, &vk_info, nullptr, &m_pool)); + + if (info.name.empty()) + { + info.name = ""; + } + device.name(*this, "{}", info.name); +} + +CommandPool::~CommandPool() +{ + if (m_device) + { + api::destroy_command_pool(m_device, m_pool, nullptr); + } +} + +[[nodiscard]] auto CommandPool::allocate(uint32_t count, BufferLevel level) + -> std::vector +{ + auto vk_buffers = std::vector(count); + + auto vk_info = VkCommandBufferAllocateInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = {}, + .commandPool = m_pool, + .level = static_cast(level), + .commandBufferCount = count, + }; + + vkc(api::allocate_command_buffers(m_device, &vk_info, vk_buffers.data())); + + auto buffers = std::vector(); + buffers.reserve(vk_buffers.size()); + for (auto &vk_buffer : vk_buffers) + { + buffers.emplace_back(CommandBuffer { vk_buffer }); + } + + return buffers; +} + Swapchain::Swapchain(Device &device, Surface &surface, CreateInfo info) : m_device(device.m_device.get()) , m_swapchain() @@ -4288,7 +4573,6 @@ Swapchain::~Swapchain() return idx; } - Buffer::Buffer(Device &device, CreateInfo info): m_device(device.m_device.get()) { auto vk_info = VkBufferCreateInfo { @@ -4365,7 +4649,7 @@ ShaderModule::ShaderModule(Device &device, CreateInfo info): m_device(device.get .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, .pNext = {}, .flags = {}, - .codeSize = info.code.size() / 4ul, + .codeSize = info.code.size(), .pCode = std::bit_cast(info.code.data()), }; vkc(api::create_shader_module(m_device, &vk_info, nullptr, &m_shader_module)); @@ -4379,18 +4663,48 @@ ShaderModule::ShaderModule(Device &device, CreateInfo info): m_device(device.get ShaderModule::~ShaderModule() { - api::destroy_shader_module(m_device, m_shader_module, nullptr); + if (m_device) + { + api::destroy_shader_module(m_device, m_shader_module, nullptr); + } } DescriptorSetLayout::DescriptorSetLayout(Device &device, CreateInfo info) : m_device(device.get_vk_handle()) { + auto vk_bindings = std::vector {}; + auto vk_binding_flag_values = std::vector {}; + + vk_bindings.reserve(info.bindings.size()); + vk_binding_flag_values.reserve(info.bindings.size()); + for (auto &binding_info : info.bindings) + { + vk_bindings.emplace_back( + VkDescriptorSetLayoutBinding { + .binding = binding_info.idx, + .descriptorType = static_cast(binding_info.type), + .descriptorCount = binding_info.count, + .stageFlags = binding_info.shader_stages, + .pImmutableSamplers = {}, + } + ); + + vk_binding_flag_values.emplace_back(binding_info.flags); + } + + auto vk_binding_flags_info = VkDescriptorSetLayoutBindingFlagsCreateInfoEXT { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .pNext = {}, + .bindingCount = static_cast(vk_binding_flag_values.size()), + .pBindingFlags = vk_binding_flag_values.data(), + }; + auto vk_info = VkDescriptorSetLayoutCreateInfo { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = {}, - .flags = {}, - .bindingCount = static_cast(info.bindings.size()), - .pBindings = std::bit_cast(info.bindings.data()), + .pNext = &vk_binding_flags_info, + .flags = info.flags, + .bindingCount = static_cast(vk_bindings.size()), + .pBindings = vk_bindings.data(), }; vkc(api::create_descriptor_set_layout(m_device, &vk_info, nullptr, &m_descriptor_set_layout)); @@ -4403,7 +4717,68 @@ DescriptorSetLayout::DescriptorSetLayout(Device &device, CreateInfo info) DescriptorSetLayout::~DescriptorSetLayout() { - api::destroy_descriptor_set_layout(m_device, m_descriptor_set_layout, nullptr); + if (m_device) + { + api::destroy_descriptor_set_layout(m_device, m_descriptor_set_layout, nullptr); + } +} + +DescriptorPool::DescriptorPool(Device &device, CreateInfo info): m_device(device.get_vk_handle()) +{ + auto vk_sizes = std::vector {}; + vk_sizes.reserve(info.sizes.size()); + for (auto &size : info.sizes) + { + vk_sizes.emplace_back( + VkDescriptorPoolSize { + .type = static_cast(size.type), + .descriptorCount = size.count, + } + ); + } + + auto vk_info = VkDescriptorPoolCreateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = {}, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + .maxSets = info.max_sets, + .poolSizeCount = static_cast(vk_sizes.size()), + .pPoolSizes = vk_sizes.data(), + }; + + vkc(api::create_descriptor_pool(m_device, &vk_info, nullptr, &m_descriptor_pool)); + + if (info.name.empty()) + { + info.name = ""; + } + device.name(*this, "{}", info.name); +} + +DescriptorPool::~DescriptorPool() +{ + if (m_device) + { + api::destroy_descriptor_pool(m_device, m_descriptor_pool, nullptr); + } +} + +[[nodiscard]] auto DescriptorPool::allocate(DescriptorSetLayout &layout) -> DescriptorSet +{ + auto *vk_set = VkDescriptorSet {}; + auto vk_info = VkDescriptorSetAllocateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = m_descriptor_pool, + .descriptorSetCount = 1, + .pSetLayouts = layout.get_vk_handle_addr(), + }; + vkc(api::allocate_descriptor_sets(m_device, &vk_info, &vk_set)); + + return DescriptorSet { vk_set }; +} + +DescriptorSet::DescriptorSet(VkDescriptorSet descriptor_set): m_descriptor_set(descriptor_set) +{ } Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info) @@ -4540,16 +4915,57 @@ Pipeline::Pipeline(Device &device, PipelineLayout &layout, CreateInfo info) Pipeline::~Pipeline() { - api::destroy_pipeline(m_device, m_pipeline, nullptr); + if (m_device) + { + api::destroy_pipeline(m_device, m_pipeline, nullptr); + } } +PipelineLayout::PipelineLayout(Device &device, CreateInfo info): m_device(device.get_vk_handle()) +{ + auto vk_set_layouts = std::vector {}; + vk_set_layouts.reserve(info.descriptor_set_layouts.size()); -PipelineLayout::PipelineLayout(Device &device, CreateInfo info) { - vkc(api::create_pipeline_layout(m_device, &vk_info, nullptr, &m_layout)) + auto vk_push_constant_ranges = std::vector {}; + vk_push_constant_ranges.reserve(info.push_constant_ranges.size()); + + for (const auto &range : info.push_constant_ranges) + { + vk_push_constant_ranges.emplace_back( + VkPushConstantRange { + .stageFlags = range.shader_stages, + .offset = range.offset, + .size = range.size, + } + ); + } + + for (const auto &layout : info.descriptor_set_layouts) + { + vk_set_layouts.emplace_back(layout->get_vk_handle()); + } + + auto vk_info = VkPipelineLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = {}, + .flags = {}, + .setLayoutCount = static_cast(vk_set_layouts.size()), + .pSetLayouts = vk_set_layouts.data(), + .pushConstantRangeCount = static_cast(vk_push_constant_ranges.size()), + .pPushConstantRanges = vk_push_constant_ranges.data() + }; + vkc(api::create_pipeline_layout(m_device, &vk_info, nullptr, &m_pipeline_layout)); + + if (info.name.empty()) + { + info.name = ""; + } + device.name(*this, "{}", info.name); } PipelineLayout::~PipelineLayout() { + api::destroy_pipeline_layout(m_device, m_pipeline_layout, nullptr); } Messenger::Messenger(Instance &instance, CreateInfo info): m_instance(instance.get_vk_handle()) @@ -4580,7 +4996,6 @@ Messenger::Messenger(Instance &instance, CreateInfo info): m_instance(instance.g }; - log::debug("Creating debug messenger...."); vkc(api::create_debug_messenger(m_instance, &vk_info, nullptr, &m_messenger)); } diff --git a/modules/renderer/vk/device.cppm b/modules/renderer/vk/device.cppm index df655c0..ac7c303 100644 --- a/modules/renderer/vk/device.cppm +++ b/modules/renderer/vk/device.cppm @@ -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(), diff --git a/modules/renderer/vk/pass.cppm b/modules/renderer/vk/pass.cppm index 623acf2..f67da7c 100644 --- a/modules/renderer/vk/pass.cppm +++ b/modules/renderer/vk/pass.cppm @@ -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)) - + , 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 { - { - .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 { - { - .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> {}; 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 = { diff --git a/modules/renderer/vk/renderer.cppm b/modules/renderer/vk/renderer.cppm index 4a217c5..e4c4d8a 100644 --- a/modules/renderer/vk/renderer.cppm +++ b/modules/renderer/vk/renderer.cppm @@ -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 submit_scene) -> Result override; @@ -80,6 +94,10 @@ private: std::span 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( - m_device, - assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" }, - assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" } - )) + , m_pass( + memory::create_ref( + 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(m_resolution.width), - // .height = static_cast(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(m_current_sprite_idx), - .instance_count = 1u, - .first_vertex = 0u, - .first_instance = 0u, - }); + cmd.set_viewport( + { + .origin = {}, + .extent = { static_cast(m_resolution.x), static_cast(m_resolution.y) }, + .min_depth = 0.0f, + .max_depth = 1.0f, + } + ); + cmd.set_scissor({ .offset = {}, .extent = m_resolution }); + cmd.draw( + { + .vertex_count = static_cast(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(); } -- 2.45.3 From bd51b5ae1582d82affb51a1b9fdb803410e15b2f Mon Sep 17 00:00:00 2001 From: light7734 Date: Sat, 13 Dec 2025 14:52:24 +0330 Subject: [PATCH 2/4] build: add remaining renderer tests --- modules/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index c568f25..78d1c23 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -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( -- 2.45.3 From 8b0f286f39cfbb9b44c9f9d7322ed2ece9f9b931 Mon Sep 17 00:00:00 2001 From: light7734 Date: Sat, 13 Dec 2025 14:56:16 +0330 Subject: [PATCH 3/4] ci: attempt to fix llvm-cov show --- tools/ci/amd64/clang/coverage.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci/amd64/clang/coverage.sh b/tools/ci/amd64/clang/coverage.sh index 3629275..9479a6a 100755 --- a/tools/ci/amd64/clang/coverage.sh +++ b/tools/ci/amd64/clang/coverage.sh @@ -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 -- '-o %s ' {} \;)" \ + "$(find ./build -type f -name '*\.a' -exec printf -- '-o %s ' {} \;)" \ -ignore-filename-regex='\.test\.cpp$' \ -ignore-filename-regex='\.fuzz\.cpp$' ) -- 2.45.3 From 1608fb4b5c0c12f8c286a6140ae65d8f9d5f0eca Mon Sep 17 00:00:00 2001 From: light7734 Date: Sat, 13 Dec 2025 14:59:22 +0330 Subject: [PATCH 4/4] ci: attempt to fix llvm-cov show --- tools/ci/amd64/clang/coverage.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci/amd64/clang/coverage.sh b/tools/ci/amd64/clang/coverage.sh index 9479a6a..a2ca513 100755 --- a/tools/ci/amd64/clang/coverage.sh +++ b/tools/ci/amd64/clang/coverage.sh @@ -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 -- '-o %s ' {} \;)" \ - "$(find ./build -type f -name '*\.a' -exec printf -- '-o %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$' ) -- 2.45.3