mirror of https://github.com/snes9xgit/snes9x.git
vulkan: Add support for VK_KHR_present_wait
May have a tighter CPU-GPU sync for lower latency.
This commit is contained in:
parent
8559143576
commit
c8895c8cdb
|
@ -245,6 +245,23 @@ bool Context::init_device(int preferred_device)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<const char *> present_wait_extensions =
|
||||
{
|
||||
VK_KHR_PRESENT_ID_EXTENSION_NAME,
|
||||
VK_KHR_PRESENT_WAIT_EXTENSION_NAME
|
||||
};
|
||||
|
||||
if (check_extensions(present_wait_extensions, physical_device))
|
||||
{
|
||||
for (auto &ext : present_wait_extensions)
|
||||
required_extensions.push_back(ext);
|
||||
have_VK_KHR_present_wait = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
have_VK_KHR_present_wait = false;
|
||||
}
|
||||
|
||||
auto extension_properties = physical_device.enumerateDeviceExtensionProperties().value;
|
||||
physical_device.getProperties(&physical_device_props);
|
||||
|
||||
|
@ -256,6 +273,14 @@ bool Context::init_device(int preferred_device)
|
|||
vk::DeviceQueueCreateInfo dqci({}, graphics_queue_family_index, priorities);
|
||||
vk::DeviceCreateInfo dci({}, dqci, {}, required_extensions);
|
||||
|
||||
vk::PhysicalDevicePresentWaitFeaturesKHR physical_device_present_wait_feature(true);
|
||||
vk::PhysicalDevicePresentIdFeaturesKHR physical_device_present_id_feature(true);
|
||||
if (have_VK_KHR_present_wait)
|
||||
{
|
||||
dci.setPNext(&physical_device_present_wait_feature);
|
||||
physical_device_present_wait_feature.setPNext(&physical_device_present_id_feature);
|
||||
}
|
||||
|
||||
device = physical_device.createDevice(dci).value;
|
||||
queue = device.getQueue(graphics_queue_family_index, 0);
|
||||
|
||||
|
@ -289,7 +314,7 @@ bool Context::init_vma()
|
|||
bool Context::create_swapchain(int width, int height)
|
||||
{
|
||||
wait_idle();
|
||||
swapchain = std::make_unique<Swapchain>(device, physical_device, queue, surface.get(), command_pool.get());
|
||||
swapchain = std::make_unique<Swapchain>(*this);
|
||||
return swapchain->create(2, width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ class Context
|
|||
vk::PhysicalDeviceProperties physical_device_props;
|
||||
vk::UniqueSurfaceKHR surface;
|
||||
|
||||
bool have_VK_KHR_present_wait = false;
|
||||
|
||||
private:
|
||||
bool init_vma();
|
||||
bool init_device(int preferred_device = 0);
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include "vulkan_swapchain.hpp"
|
||||
#include "vulkan_context.hpp"
|
||||
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
Swapchain::Swapchain(vk::Device device_, vk::PhysicalDevice physical_device_, vk::Queue queue_, vk::SurfaceKHR surface_, vk::CommandPool command_pool_)
|
||||
: surface(surface_),
|
||||
command_pool(command_pool_),
|
||||
physical_device(physical_device_),
|
||||
queue(queue_)
|
||||
Swapchain::Swapchain(Context &context_)
|
||||
: context(context_)
|
||||
{
|
||||
device = device_;
|
||||
device = context.device;
|
||||
queue = context.queue;
|
||||
surface = context.surface.get();
|
||||
physical_device = context.physical_device;
|
||||
command_pool = context.command_pool.get();
|
||||
create_render_pass();
|
||||
end_render_pass_function = nullptr;
|
||||
}
|
||||
|
@ -351,13 +353,22 @@ bool Swapchain::swap()
|
|||
vk::SwapchainPresentModeInfoEXT present_mode_info;
|
||||
auto present_mode = get_present_mode();
|
||||
present_mode_info.setPresentModes(present_mode);
|
||||
present_info.setPNext(&present_mode_info);
|
||||
|
||||
auto &present_fence = image_data[current_swapchain_image].fence.get();
|
||||
device.resetFences(present_fence);
|
||||
vk::SwapchainPresentFenceInfoEXT present_fence_info(present_fence);
|
||||
|
||||
present_info.setPNext(&present_mode_info);
|
||||
present_mode_info.setPNext(&present_fence_info);
|
||||
|
||||
vk::PresentIdKHR present_id;
|
||||
if (context.have_VK_KHR_present_wait)
|
||||
{
|
||||
presentation_id++;
|
||||
present_id.setPresentIds(presentation_id);
|
||||
present_fence_info.setPNext(&present_id);
|
||||
}
|
||||
|
||||
vk::Result result = queue.presentKHR(present_info);
|
||||
if (result == vk::Result::eErrorOutOfDateKHR)
|
||||
{
|
||||
|
@ -424,6 +435,15 @@ void Swapchain::wait_on_frames()
|
|||
{
|
||||
for (auto i = 0; i < image_data.size(); i++)
|
||||
wait_on_frame(i);
|
||||
|
||||
if (context.have_VK_KHR_present_wait)
|
||||
{
|
||||
auto result = device.waitForPresentKHR(swapchain_object.get(), presentation_id, 16666666);
|
||||
if (result != vk::Result::eSuccess)
|
||||
{
|
||||
printf("Error waiting on present: %s\n", vk::to_string(result).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vk::Extent2D Swapchain::get_extents()
|
||||
|
|
|
@ -6,14 +6,12 @@
|
|||
namespace Vulkan
|
||||
{
|
||||
|
||||
class Context;
|
||||
|
||||
class Swapchain
|
||||
{
|
||||
public:
|
||||
Swapchain(vk::Device device,
|
||||
vk::PhysicalDevice physical_device,
|
||||
vk::Queue queue,
|
||||
vk::SurfaceKHR surface,
|
||||
vk::CommandPool command_pool);
|
||||
Swapchain(Context &);
|
||||
~Swapchain();
|
||||
bool create(unsigned int num_frames, int width = -1, int height = -1);
|
||||
bool recreate(int width = -1, int height = -1);
|
||||
|
@ -66,6 +64,7 @@ class Swapchain
|
|||
unsigned int current_frame = 0;
|
||||
unsigned int current_swapchain_image = 0;
|
||||
unsigned int num_swapchain_images = 0;
|
||||
uint64_t presentation_id = 0;
|
||||
bool vsync = true;
|
||||
bool supports_immediate = false;
|
||||
bool supports_mailbox = false;
|
||||
|
@ -73,6 +72,7 @@ class Swapchain
|
|||
std::vector<Frame> frames;
|
||||
std::vector<ImageData> image_data;
|
||||
|
||||
Vulkan::Context &context;
|
||||
vk::Device device;
|
||||
vk::SurfaceKHR surface;
|
||||
vk::CommandPool command_pool;
|
||||
|
|
Loading…
Reference in New Issue