Restrict max latency to 3 frames.

This commit is contained in:
BearOso 2023-01-25 14:03:21 -06:00
parent e4768f9b80
commit 23cf7ec056
6 changed files with 34 additions and 32 deletions

View File

@ -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;
}

View File

@ -239,14 +239,14 @@ bool ShaderChain::load_shader_preset(std::string filename)
std::array<vk::DescriptorPoolSize, 2> 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++;
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -3,6 +3,7 @@
#include "vulkan/vulkan.hpp"
#include "vulkan/vulkan_handles.hpp"
#include "vulkan/vulkan_structs.hpp"
#include <deque>
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<Frame> frames;
std::vector<ImageViewFB> imageviewfbs;