diff --git a/modules/renderer/CMakeLists.txt b/modules/renderer/CMakeLists.txt index 35f0146..6863120 100644 --- a/modules/renderer/CMakeLists.txt +++ b/modules/renderer/CMakeLists.txt @@ -6,6 +6,8 @@ add_library_module(renderer vk/context/device.cpp vk/context/swapchain.cpp vk/context/context.cpp + vk/renderer/pass.cpp + vk/renderer/renderer.cpp vk/pipeline.cpp ) @@ -14,6 +16,8 @@ PUBLIC app ecs memory + assets + time PRIVATE surface pthread @@ -28,6 +32,8 @@ add_test_module(renderer vk/context/device.test.cpp vk/context/swapchain.test.cpp vk/context/context.test.cpp + vk/renderer/pass.test.cpp + vk/renderer/renderer.test.cpp vk/pipeline.test.cpp ) target_link_libraries(renderer_tests diff --git a/modules/renderer/private/system.cpp b/modules/renderer/private/system.cpp index 3da8e18..21e3039 100644 --- a/modules/renderer/private/system.cpp +++ b/modules/renderer/private/system.cpp @@ -2,4 +2,16 @@ namespace lt::renderer { +void System::on_register() +{ } + +void System::on_unregister() +{ +} + +void System::tick(app::TickInfo tick) +{ +} + +} // namespace lt::renderer diff --git a/modules/renderer/private/vk/context/context.cpp b/modules/renderer/private/vk/context/context.cpp index 18ef46e..ad25078 100644 --- a/modules/renderer/private/vk/context/context.cpp +++ b/modules/renderer/private/vk/context/context.cpp @@ -3,9 +3,8 @@ namespace lt::renderer::vk { -Context::Context(const ecs::Entity &surface_entity, Ref system_stats) - : m_stats(std::move(system_stats)) - , m_surface(surface_entity) +Context::Context(const ecs::Entity &surface_entity) + : m_surface(surface_entity) , m_device(m_surface) , m_swapchain(m_device, m_surface) { diff --git a/modules/renderer/private/vk/context/context.hpp b/modules/renderer/private/vk/context/context.hpp index 80c0aa1..d046945 100644 --- a/modules/renderer/private/vk/context/context.hpp +++ b/modules/renderer/private/vk/context/context.hpp @@ -18,7 +18,7 @@ using memory::NullOnMove; class Context { public: - Context(const ecs::Entity &surface_entity, Ref system_stats); + Context(const ecs::Entity &surface_entity); [[nodiscard]] auto instance() const -> VkInstance { @@ -36,8 +36,6 @@ public: } private: - Ref m_stats; - Surface m_surface; Device m_device; diff --git a/modules/renderer/private/vk/context/device.cpp b/modules/renderer/private/vk/context/device.cpp index 1e5a16f..88c8993 100644 --- a/modules/renderer/private/vk/context/device.cpp +++ b/modules/renderer/private/vk/context/device.cpp @@ -10,9 +10,12 @@ Device::Device(const Surface &surface) ensure(surface.vk(), "Failed to initialize vk::Device: null vulkan surface"); initialize_physical_device(); + initialize_queue_indices(surface); initialize_logical_device(); Instance::load_device_functions(m_device); - initialize_queue(surface); + + vk_get_device_queue(m_device, m_graphics_queue_family_index, 0, &m_graphics_queue); + vk_get_device_queue(m_device, m_present_queue_family_index, 0, &m_present_queue); } Device::~Device() @@ -54,12 +57,20 @@ void Device::initialize_logical_device() { const float priorities = .0f; - auto queue_info = VkDeviceQueueCreateInfo { - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = find_suitable_queue_family(), - .queueCount = 1u, - .pQueuePriorities = &priorities, - }; + auto queue_infos = std::vector {}; + auto queue_families = std::set { m_graphics_queue_family_index, m_present_queue_family_index }; + + for (auto queue_family : queue_families) + { + queue_infos.emplace_back( + VkDeviceQueueCreateInfo { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueFamilyIndex = queue_family, + .queueCount = 1u, + .pQueuePriorities = &priorities, + } + ); + } auto physical_device_features = VkPhysicalDeviceFeatures {}; @@ -69,8 +80,8 @@ void Device::initialize_logical_device() auto device_info = VkDeviceCreateInfo { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = 1, - .pQueueCreateInfos = &queue_info, + .queueCreateInfoCount = static_cast(queue_infos.size()), + .pQueueCreateInfos = queue_infos.data(), .enabledExtensionCount = static_cast(extensions.size()), .ppEnabledExtensionNames = extensions.data(), .pEnabledFeatures = &physical_device_features, @@ -84,30 +95,28 @@ void Device::initialize_logical_device() [[nodiscard]] auto Device::find_suitable_queue_family() const -> uint32_t { - auto count = 0u; - vk_get_physical_device_queue_family_properties(m_physical_device, &count, nullptr); - ensure(count != 0u, "Failed to find any physical devices with Vulkan support"); - - auto families = std::vector(count); - vk_get_physical_device_queue_family_properties(m_physical_device, &count, families.data()); - - const auto required_flags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT; - for (auto idx = 0u; auto &family : families) - { - if ((family.queueFlags & required_flags) == required_flags) - { - return idx; - } - } - - ensure(false, "Failed to find a suitable Vulkan queue family"); - return 0; + // auto count = 0u; + // vk_get_physical_device_queue_family_properties(m_physical_device, &count, nullptr); + // ensure(count != 0u, "Failed to find any physical devices with Vulkan support"); + // + // auto families = std::vector(count); + // vk_get_physical_device_queue_family_properties(m_physical_device, &count, families.data()); + // + // const auto required_flags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT; + // for (auto idx = 0u; auto &family : families) + // { + // if ((family.queueFlags & required_flags) == required_flags) + // { + // return idx; + // } + // } + // + // ensure(false, "Failed to find a suitable Vulkan queue family"); + // return 0; } -void Device::initialize_queue(const Surface &surface) +void Device::initialize_queue_indices(const Surface &surface) { - vk_get_device_queue(m_device, find_suitable_queue_family(), 0, &m_queue); - auto count = uint32_t { 0u }; vk_get_physical_device_queue_family_properties(m_physical_device, &count, nullptr); diff --git a/modules/renderer/private/vk/context/device.hpp b/modules/renderer/private/vk/context/device.hpp index 157904a..ed10a17 100644 --- a/modules/renderer/private/vk/context/device.hpp +++ b/modules/renderer/private/vk/context/device.hpp @@ -35,12 +35,22 @@ public: return { m_graphics_queue_family_index, m_present_queue_family_index }; } + [[nodiscard]] auto get_graphics_queue() const -> VkQueue + { + return m_graphics_queue; + } + + [[nodiscard]] auto get_present_queue() const -> VkQueue + { + return m_present_queue; + } + private: void initialize_physical_device(); void initialize_logical_device(); - void initialize_queue(const class Surface &surface); + void initialize_queue_indices(const class Surface &surface); [[nodiscard]] auto find_suitable_queue_family() const -> uint32_t; @@ -49,7 +59,9 @@ private: memory::NullOnMove m_device = VK_NULL_HANDLE; - memory::NullOnMove m_queue = VK_NULL_HANDLE; + memory::NullOnMove m_graphics_queue = VK_NULL_HANDLE; + + memory::NullOnMove m_present_queue = VK_NULL_HANDLE; uint32_t m_graphics_queue_family_index = VK_QUEUE_FAMILY_IGNORED; diff --git a/modules/renderer/private/vk/context/instance.cpp b/modules/renderer/private/vk/context/instance.cpp index 96186a5..a66b400 100644 --- a/modules/renderer/private/vk/context/instance.cpp +++ b/modules/renderer/private/vk/context/instance.cpp @@ -86,6 +86,8 @@ PFN_vkCmdDraw vk_cmd_draw {}; PFN_vkCmdSetViewport vk_cmd_set_viewport {}; PFN_vkCmdSetScissor vk_cmd_set_scissors {}; +PFN_vkResetCommandBuffer vk_reset_command_buffer {}; + PFN_vkGetPhysicalDeviceSurfaceSupportKHR vk_get_physical_device_surface_support {}; PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities {}; PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vk_get_physical_device_surface_formats {}; @@ -370,6 +372,7 @@ void Instance::load_device_functions_impl(VkDevice device) load_fn(vk_cmd_draw, "vkCmdDraw"); load_fn(vk_cmd_set_viewport, "vkCmdSetViewport"); load_fn(vk_cmd_set_scissors, "vkCmdSetScissor"); + load_fn(vk_reset_command_buffer, "vkResetCommandBuffer"); } auto parse_message_type(VkDebugUtilsMessageTypeFlagsEXT message_types) -> const char * diff --git a/modules/renderer/private/vk/context/swapchain.cpp b/modules/renderer/private/vk/context/swapchain.cpp index 8c94de3..9ebbbdd 100644 --- a/modules/renderer/private/vk/context/swapchain.cpp +++ b/modules/renderer/private/vk/context/swapchain.cpp @@ -7,7 +7,9 @@ namespace lt::renderer::vk { -Swapchain::Swapchain(const Device &device, const Surface &surface): m_device(device.vk()) +Swapchain::Swapchain(const Device &device, const Surface &surface) + : m_device(device.vk()) + , m_resolution(surface.get_framebuffer_size()) { auto *physical_device = device.physical(); @@ -30,6 +32,7 @@ Swapchain::Swapchain(const Device &device, const Surface &surface): m_device(dev constexpr auto desired_swapchain_image_count = uint32_t { 3 }; const auto surface_format = formats.front(); const auto queue_indices = device.get_family_indices(); + m_format = surface_format.format; auto create_info = VkSwapchainCreateInfoKHR { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, @@ -45,7 +48,7 @@ Swapchain::Swapchain(const Device &device, const Surface &surface): m_device(dev .pQueueFamilyIndices = queue_indices.data(), .preTransform = capabilities.currentTransform, .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR, // TODO(Light): parameterize + .presentMode = VK_PRESENT_MODE_FIFO_KHR, // TODO(Light): parameterize .clipped = VK_TRUE, .oldSwapchain = nullptr, }; @@ -84,6 +87,7 @@ Swapchain::Swapchain(const Device &device, const Surface &surface): m_device(dev vkc(vk_create_image_view(device.vk(), &create_info, nullptr, &view)); } + } Swapchain::~Swapchain() diff --git a/modules/renderer/private/vk/context/swapchain.hpp b/modules/renderer/private/vk/context/swapchain.hpp index 3ddc0ed..93e5b07 100644 --- a/modules/renderer/private/vk/context/swapchain.hpp +++ b/modules/renderer/private/vk/context/swapchain.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace lt::renderer::vk { @@ -20,6 +21,44 @@ public: auto operator=(const Swapchain &) const -> Swapchain & = delete; + [[nodiscard]] auto vk() const -> VkSwapchainKHR + { + return m_swapchain; + } + + [[nodiscard]] auto get_resolution() const -> VkExtent2D + { + return m_resolution; + } + + [[nodiscard]] auto get_format() const -> VkFormat + { + return m_format; + } + + [[nodiscard]] auto create_framebuffers_for_pass(VkRenderPass pass) const + -> std::vector + { + auto framebuffers = std::vector(m_swapchain_image_views.size()); + + for (auto idx = 0u; auto &framebuffer : framebuffers) + { + auto info = VkFramebufferCreateInfo { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .renderPass = pass, + .attachmentCount = 1u, + .pAttachments = &m_swapchain_image_views[idx++], + .width = m_resolution.width, + .height = m_resolution.height, + .layers = 1u + }; + + vkc(vk_create_frame_buffer(m_device, &info, nullptr, &framebuffer)); + } + + return framebuffers; + } + private: [[nodiscard]] auto get_optimal_image_count( VkSurfaceCapabilitiesKHR capabilities, @@ -33,6 +72,10 @@ private: std::vector m_swapchain_images; std::vector m_swapchain_image_views; + + VkExtent2D m_resolution; + + VkFormat m_format; }; } // namespace lt::renderer::vk diff --git a/modules/renderer/private/vk/pipeline.test.cpp b/modules/renderer/private/vk/pipeline.test.cpp index c2d2e0d..3b2a565 100644 --- a/modules/renderer/private/vk/pipeline.test.cpp +++ b/modules/renderer/private/vk/pipeline.test.cpp @@ -24,7 +24,7 @@ public: .resolution = constants::resolution, }); - m_context = create_ref(*m_surface_entity, m_stats); + m_context = create_ref(*m_surface_entity); } [[nodiscard]] auto context() -> Ref @@ -38,8 +38,6 @@ public: } private: - Ref m_stats; - Ref m_registry; Ref m_surface_system; diff --git a/modules/renderer/private/vk/renderer/pass.cpp b/modules/renderer/private/vk/renderer/pass.cpp new file mode 100644 index 0000000..e69de29 diff --git a/modules/renderer/private/vk/renderer/pass.hpp b/modules/renderer/private/vk/renderer/pass.hpp new file mode 100644 index 0000000..23d5382 --- /dev/null +++ b/modules/renderer/private/vk/renderer/pass.hpp @@ -0,0 +1,280 @@ +#pragma once + +#include +#include +#include + +namespace lt::renderer::vk { + +class Pass +{ +public: + Pass( + Context &context, + lt::assets::ShaderAsset vertex_shader, + lt::assets::ShaderAsset fragment_shader + ) + : m_device(context.device().vk()) + { + // auto fragment_blob = vertex_shader.unpack(lt::assets::ShaderAsset::BlobTag::code); + + auto *vertex_module = create_module( + vertex_shader.unpack(lt::assets::ShaderAsset::BlobTag::code) + ); + + auto *fragment_module = create_module( + fragment_shader.unpack(lt::assets::ShaderAsset::BlobTag::code) + ); + + auto shader_stages = std::array { + VkPipelineShaderStageCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vertex_module, + .pName = "main", + }, + VkPipelineShaderStageCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragment_module, + .pName = "main", + }, + }; + + auto dynamic_states = std::array { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + + auto dynamic_state = VkPipelineDynamicStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = static_cast(dynamic_states.size()), + .pDynamicStates = dynamic_states.data(), + }; + + auto vertex_input = VkPipelineVertexInputStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + }; + + auto input_assembly = VkPipelineInputAssemblyStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; + + auto viewport = VkViewport { + .x = 0u, + .y = 0u, + .width = static_cast(context.swapchain().get_resolution().width), + .height = static_cast(context.swapchain().get_resolution().height), + .minDepth = 0.0f, + .maxDepth = 0.0f, + }; + + auto scissor = VkRect2D { + .offset = { 0u, 0u }, + .extent = context.swapchain().get_resolution(), + }; + + auto viewport_state = VkPipelineViewportStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1u, + .scissorCount = 1u, + }; + + auto rasterization = VkPipelineRasterizationStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .lineWidth = 1.0, + }; + + auto multisampling = VkPipelineMultisampleStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .sampleShadingEnable = VK_FALSE, + .minSampleShading = 1.0, + .pSampleMask = nullptr, + .alphaToCoverageEnable = VK_FALSE, + .alphaToOneEnable = VK_FALSE, + }; + + auto color_blend_attachment = VkPipelineColorBlendAttachmentState { + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + .blendEnable = VK_FALSE, + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, + .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, + .alphaBlendOp = VK_BLEND_OP_ADD, + }; + + auto color_blend = VkPipelineColorBlendStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .logicOpEnable = VK_FALSE, + .logicOp = VK_LOGIC_OP_COPY, + .attachmentCount = 1, + .pAttachments = &color_blend_attachment, + .blendConstants = { 0.0f, 0.0, 0.0, 0.0 }, + }; + + auto layout_info = VkPipelineLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 0u, + .pSetLayouts = nullptr, + .pushConstantRangeCount = 0u, + .pPushConstantRanges = nullptr, + }; + + vkc(vk_create_pipeline_layout(m_device, &layout_info, nullptr, &m_layout)); + + auto attachment_description = VkAttachmentDescription { + .format = context.swapchain().get_format(), + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + }; + + auto color_attachment_ref = VkAttachmentReference { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + + auto subpass_description = VkSubpassDescription { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1u, + .pColorAttachments = &color_attachment_ref, + }; + + auto pass_dependency = VkSubpassDependency { + .srcSubpass = VK_SUBPASS_EXTERNAL, + .dstSubpass = 0u, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = 0u, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + }; + + auto renderpass_info = VkRenderPassCreateInfo { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 1u, + .pAttachments = &attachment_description, + .subpassCount = 1u, + .pSubpasses = &subpass_description, + .dependencyCount = 1u, + .pDependencies = &pass_dependency, + }; + + vkc(vk_create_render_pass(m_device, &renderpass_info, nullptr, &m_pass)); + + auto pipeline_info = VkGraphicsPipelineCreateInfo { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = static_cast(shader_stages.size()), + .pStages = shader_stages.data(), + .pVertexInputState = &vertex_input, + .pInputAssemblyState = &input_assembly, + .pViewportState = &viewport_state, + .pRasterizationState = &rasterization, + .pMultisampleState = &multisampling, + .pDepthStencilState = nullptr, + .pColorBlendState = &color_blend, + .pDynamicState = &dynamic_state, + .layout = m_layout, + .renderPass = m_pass, + .subpass = 0u, + .basePipelineHandle = VK_NULL_HANDLE, + .basePipelineIndex = -1, + }; + + vkc(vk_create_graphics_pipelines( + m_device, + VK_NULL_HANDLE, + 1u, + &pipeline_info, + nullptr, + &m_pipeline + )); + + vk_destroy_shader_module(m_device, vertex_module, nullptr); + vk_destroy_shader_module(m_device, fragment_module, nullptr); + + m_framebuffers = context.swapchain().create_framebuffers_for_pass(m_pass); + } + + ~Pass() + { + if (!m_device) + { + return; + } + + for (auto &framebuffer : m_framebuffers) + { + vk_destroy_frame_buffer(m_device, framebuffer, nullptr); + } + + vk_destroy_pipeline(m_device, m_pipeline, nullptr); + vk_destroy_render_pass(m_device, m_pass, nullptr); + vk_destroy_pipeline_layout(m_device, m_layout, nullptr); + } + + Pass(Pass &&) = default; + + Pass(const Pass &) = delete; + + auto operator=(Pass &&) -> Pass & = default; + + auto operator=(const Pass &) -> Pass & = delete; + + [[nodiscard]] auto get_pass() -> VkRenderPass + { + return m_pass; + } + + [[nodiscard]] auto get_pipeline() -> VkPipeline + { + return m_pipeline; + } + + [[nodiscard]] auto get_framebuffers() -> std::vector & + { + return m_framebuffers; + } + +private: + auto create_module(lt::assets::Blob blob) -> VkShaderModule + { + log_dbg("BLOB SIZE: {}", blob.size()); + auto info = VkShaderModuleCreateInfo { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .codeSize = blob.size(), + .pCode = reinterpret_cast(blob.data()) // NOLINT + }; + + auto *module = VkShaderModule { VK_NULL_HANDLE }; + vkc(vk_create_shader_module(m_device, &info, nullptr, &module)); + + return module; + } + + memory::NullOnMove m_device = VK_NULL_HANDLE; + + memory::NullOnMove m_pipeline = VK_NULL_HANDLE; + + memory::NullOnMove m_pass = VK_NULL_HANDLE; + + memory::NullOnMove m_layout = VK_NULL_HANDLE; + + std::vector m_framebuffers; +}; + +} // namespace lt::renderer::vk diff --git a/modules/renderer/private/vk/renderer/pass.test.cpp b/modules/renderer/private/vk/renderer/pass.test.cpp new file mode 100644 index 0000000..64ffefe --- /dev/null +++ b/modules/renderer/private/vk/renderer/pass.test.cpp @@ -0,0 +1,20 @@ +#include +#include + +using ::lt::assets::ShaderAsset; +using ::lt::renderer::vk::Pass; + +Suite raii = "pass_raii"_suite = [] { + Case { "happy path won't throw" } = [] { + auto observer = ValidationObserver {}; + auto [context, _] = create_context(); + + std::ignore = Pass { + context, + ShaderAsset { "./data/test_assets/triangle.vert.asset" }, + ShaderAsset { "./data/test_assets/triangle.frag.asset" }, + }; + + expect_false(observer.had_any_messages()); + }; +}; diff --git a/modules/renderer/private/vk/renderer/renderer.cpp b/modules/renderer/private/vk/renderer/renderer.cpp new file mode 100644 index 0000000..e69de29 diff --git a/modules/renderer/private/vk/renderer/renderer.hpp b/modules/renderer/private/vk/renderer/renderer.hpp new file mode 100644 index 0000000..d3e3b2b --- /dev/null +++ b/modules/renderer/private/vk/renderer/renderer.hpp @@ -0,0 +1,203 @@ +#pragma once + +#include +#include +#include +#include