diff --git a/vulkan/vulkan_context.cpp b/vulkan/vulkan_context.cpp index b0d9264c..99cdc2aa 100644 --- a/vulkan/vulkan_context.cpp +++ b/vulkan/vulkan_context.cpp @@ -76,7 +76,7 @@ bool Context::init_wayland(wl_display *dpy, wl_surface *parent, int initial_widt init_command_pool(); init_descriptor_pool(); create_swapchain(initial_width, initial_height); - device.waitIdle(); + wait_idle(); return true; } #endif @@ -90,9 +90,7 @@ bool Context::init(int preferred_device) init_descriptor_pool(); create_swapchain(); - - device.waitIdle(); - + wait_idle(); return true; } diff --git a/vulkan/vulkan_shader_chain.cpp b/vulkan/vulkan_shader_chain.cpp index b7907532..4d64fb2e 100644 --- a/vulkan/vulkan_shader_chain.cpp +++ b/vulkan/vulkan_shader_chain.cpp @@ -239,14 +239,14 @@ bool ShaderChain::load_shader_preset(std::string filename) std::array descriptor_pool_sizes; descriptor_pool_sizes[0] .setType(vk::DescriptorType::eUniformBuffer) - .setDescriptorCount(num_ubos * context->swapchain->get_num_frames()); + .setDescriptorCount(num_ubos * queue_size); descriptor_pool_sizes[1] .setType(vk::DescriptorType::eCombinedImageSampler) - .setDescriptorCount(num_samplers * context->swapchain->get_num_frames()); + .setDescriptorCount(num_samplers * queue_size); auto descriptor_pool_create_info = vk::DescriptorPoolCreateInfo{} .setPoolSizes(descriptor_pool_sizes) - .setMaxSets(pipelines.size() * context->swapchain->get_num_frames()) + .setMaxSets(pipelines.size() * queue_size) .setFlags(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet); descriptor_pool = context->device.createDescriptorPoolUnique(descriptor_pool_create_info); @@ -276,6 +276,8 @@ bool ShaderChain::load_shader_preset(std::string filename) context->allocator.flushAllocation(vertex_buffer_allocation, 0, sizeof(vertex_data)); frame_count = 0; + current_frame_index = 0; + last_frame_index = 2; return true; } @@ -393,7 +395,6 @@ void ShaderChain::do_frame(uint8_t *data, int width, int height, int stride, vk: auto cmd = context->swapchain->get_cmd(); - current_frame_index = context->swapchain->get_current_frame(); update_and_propagate_sizes(width, height, viewport_width, viewport_height); update_framebuffers(cmd, current_frame_index); @@ -508,6 +509,7 @@ void ShaderChain::do_frame(uint8_t *data, int width, int height, int stride, vk: context->swapchain->end_frame(); last_frame_index = current_frame_index; + current_frame_index = (current_frame_index + 1) % queue_size; frame_count++; } diff --git a/vulkan/vulkan_shader_chain.hpp b/vulkan/vulkan_shader_chain.hpp index 27eeb11a..ca835211 100644 --- a/vulkan/vulkan_shader_chain.hpp +++ b/vulkan/vulkan_shader_chain.hpp @@ -12,6 +12,8 @@ namespace Vulkan class ShaderChain { public: + const int queue_size = 3; + ShaderChain(Context *context_); ~ShaderChain(); bool load_shader_preset(std::string filename); diff --git a/vulkan/vulkan_slang_pipeline.hpp b/vulkan/vulkan_slang_pipeline.hpp index 7dfd89e9..2e34ffa0 100644 --- a/vulkan/vulkan_slang_pipeline.hpp +++ b/vulkan/vulkan_slang_pipeline.hpp @@ -34,7 +34,7 @@ class SlangPipeline vk::UniqueDescriptorSet descriptor_set; PipelineImage image; vk::UniqueFence fence; - } frame[4]; + } frame[3]; vk::Buffer uniform_buffer; vma::Allocation uniform_buffer_allocation; diff --git a/vulkan/vulkan_swapchain.cpp b/vulkan/vulkan_swapchain.cpp index 5658b728..211c3c0e 100644 --- a/vulkan/vulkan_swapchain.cpp +++ b/vulkan/vulkan_swapchain.cpp @@ -23,7 +23,6 @@ bool Swapchain::set_vsync(bool new_setting) if (new_setting == vsync) return false; - vsync = new_setting; return true; } @@ -75,8 +74,7 @@ void Swapchain::create_render_pass() bool Swapchain::recreate(int new_width, int new_height) { device.waitIdle(); - - return create(num_frames, new_width, new_height); + return create(num_swapchain_images, new_width, new_height); } vk::Image Swapchain::get_image() @@ -84,17 +82,17 @@ vk::Image Swapchain::get_image() return imageviewfbs[current_swapchain_image].image; } -bool Swapchain::create(unsigned int desired_num_frames, int new_width, int new_height) +bool Swapchain::create(unsigned int desired_num_swapchain_images, int new_width, int new_height) { frames.clear(); imageviewfbs.clear(); auto surface_capabilities = physical_device.getSurfaceCapabilitiesKHR(surface); - if (surface_capabilities.minImageCount > desired_num_frames) - num_frames = surface_capabilities.minImageCount; + if (surface_capabilities.minImageCount > desired_num_swapchain_images) + num_swapchain_images = surface_capabilities.minImageCount; else - num_frames = desired_num_frames; + num_swapchain_images = desired_num_swapchain_images; extents = surface_capabilities.currentExtent; @@ -113,7 +111,7 @@ bool Swapchain::create(unsigned int desired_num_frames, int new_width, int new_h } auto swapchain_create_info = vk::SwapchainCreateInfoKHR{} - .setMinImageCount(num_frames) + .setMinImageCount(num_swapchain_images) .setImageFormat(vk::Format::eB8G8R8A8Unorm) .setImageExtent(extents) .setImageColorSpace(vk::ColorSpaceKHR::eSrgbNonlinear) @@ -133,18 +131,18 @@ bool Swapchain::create(unsigned int desired_num_frames, int new_width, int new_h return false; auto swapchain_images = device.getSwapchainImagesKHR(swapchain_object.get()); - vk::CommandBufferAllocateInfo command_buffer_allocate_info(command_pool, vk::CommandBufferLevel::ePrimary, num_frames); + vk::CommandBufferAllocateInfo command_buffer_allocate_info(command_pool, vk::CommandBufferLevel::ePrimary, max_latency); auto command_buffers = device.allocateCommandBuffersUnique(command_buffer_allocate_info); - if (imageviewfbs.size() > num_frames) - num_frames = imageviewfbs.size(); + if (imageviewfbs.size() > num_swapchain_images) + num_swapchain_images = imageviewfbs.size(); - frames.resize(num_frames); - imageviewfbs.resize(num_frames); + frames.resize(max_latency); + imageviewfbs.resize(num_swapchain_images); vk::FenceCreateInfo fence_create_info(vk::FenceCreateFlagBits::eSignaled); - for (unsigned int i = 0; i < num_frames; i++) + for (int i = 0; i < max_latency; i++) { // Create frame queue resources auto &frame = frames[i]; @@ -155,7 +153,7 @@ bool Swapchain::create(unsigned int desired_num_frames, int new_width, int new_h } current_frame = 0; - for (unsigned int i = 0; i < num_frames; i++) + for (unsigned int i = 0; i < num_swapchain_images; i++) { // Create resources associated with swapchain images auto &image = imageviewfbs[i]; @@ -216,16 +214,17 @@ bool Swapchain::begin_frame() return false; } - device.resetFences(frame.fence.get()); current_swapchain_image = result_value.value; + device.resetFences(frame.fence.get()); + vk::CommandBufferBeginInfo command_buffer_begin_info(vk::CommandBufferUsageFlags{vk::CommandBufferUsageFlagBits::eOneTimeSubmit}); frame.command_buffer->begin(command_buffer_begin_info); return true; } -bool Swapchain::end_frame(vk::Fence extra_fence) +bool Swapchain::end_frame() { auto &frame = frames[current_frame]; frame.command_buffer->end(); @@ -237,8 +236,6 @@ bool Swapchain::end_frame(vk::Fence extra_fence) frame.command_buffer.get(), frame.complete.get()); - if (extra_fence) - queue.submit(submit_info, extra_fence); queue.submit(submit_info, frame.fence.get()); auto present_info = vk::PresentInfoKHR{} @@ -248,7 +245,7 @@ bool Swapchain::end_frame(vk::Fence extra_fence) auto result = queue.presentKHR(present_info); - current_frame = (current_frame + 1) % num_frames; + current_frame = (current_frame + 1) % max_latency; if (result != vk::Result::eSuccess) return false; @@ -308,7 +305,7 @@ vk::RenderPass &Swapchain::get_render_pass() unsigned int Swapchain::get_num_frames() { - return num_frames; + return max_latency; } } // namespace Vulkan \ No newline at end of file diff --git a/vulkan/vulkan_swapchain.hpp b/vulkan/vulkan_swapchain.hpp index 4a9b1362..13e0ec2b 100644 --- a/vulkan/vulkan_swapchain.hpp +++ b/vulkan/vulkan_swapchain.hpp @@ -3,6 +3,7 @@ #include "vulkan/vulkan.hpp" #include "vulkan/vulkan_handles.hpp" #include "vulkan/vulkan_structs.hpp" +#include namespace Vulkan { @@ -10,6 +11,8 @@ namespace Vulkan class Swapchain { public: + const int max_latency = 3; + Swapchain(vk::Device device, vk::PhysicalDevice physical_device, vk::Queue queue, @@ -22,7 +25,7 @@ class Swapchain void begin_render_pass(); void end_render_pass(); bool wait_on_frame(int frame_num); - bool end_frame(vk::Fence extra_fence = nullptr); + bool end_frame(); // Returns true if vsync setting was changed, false if it was the same bool set_vsync(bool on); @@ -60,7 +63,7 @@ class Swapchain unsigned int current_frame = 0; unsigned int current_swapchain_image = 0; - unsigned int num_frames = 0; + unsigned int num_swapchain_images = 0; bool vsync = true; std::vector frames; std::vector imageviewfbs;