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;
|
auto extension_properties = physical_device.enumerateDeviceExtensionProperties().value;
|
||||||
physical_device.getProperties(&physical_device_props);
|
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::DeviceQueueCreateInfo dqci({}, graphics_queue_family_index, priorities);
|
||||||
vk::DeviceCreateInfo dci({}, dqci, {}, required_extensions);
|
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;
|
device = physical_device.createDevice(dci).value;
|
||||||
queue = device.getQueue(graphics_queue_family_index, 0);
|
queue = device.getQueue(graphics_queue_family_index, 0);
|
||||||
|
|
||||||
|
@ -289,7 +314,7 @@ bool Context::init_vma()
|
||||||
bool Context::create_swapchain(int width, int height)
|
bool Context::create_swapchain(int width, int height)
|
||||||
{
|
{
|
||||||
wait_idle();
|
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);
|
return swapchain->create(2, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,8 @@ class Context
|
||||||
vk::PhysicalDeviceProperties physical_device_props;
|
vk::PhysicalDeviceProperties physical_device_props;
|
||||||
vk::UniqueSurfaceKHR surface;
|
vk::UniqueSurfaceKHR surface;
|
||||||
|
|
||||||
|
bool have_VK_KHR_present_wait = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool init_vma();
|
bool init_vma();
|
||||||
bool init_device(int preferred_device = 0);
|
bool init_device(int preferred_device = 0);
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
#include "vulkan_swapchain.hpp"
|
#include "vulkan_swapchain.hpp"
|
||||||
|
#include "vulkan_context.hpp"
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
|
|
||||||
Swapchain::Swapchain(vk::Device device_, vk::PhysicalDevice physical_device_, vk::Queue queue_, vk::SurfaceKHR surface_, vk::CommandPool command_pool_)
|
Swapchain::Swapchain(Context &context_)
|
||||||
: surface(surface_),
|
: context(context_)
|
||||||
command_pool(command_pool_),
|
|
||||||
physical_device(physical_device_),
|
|
||||||
queue(queue_)
|
|
||||||
{
|
{
|
||||||
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();
|
create_render_pass();
|
||||||
end_render_pass_function = nullptr;
|
end_render_pass_function = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -351,13 +353,22 @@ bool Swapchain::swap()
|
||||||
vk::SwapchainPresentModeInfoEXT present_mode_info;
|
vk::SwapchainPresentModeInfoEXT present_mode_info;
|
||||||
auto present_mode = get_present_mode();
|
auto present_mode = get_present_mode();
|
||||||
present_mode_info.setPresentModes(present_mode);
|
present_mode_info.setPresentModes(present_mode);
|
||||||
present_info.setPNext(&present_mode_info);
|
|
||||||
|
|
||||||
auto &present_fence = image_data[current_swapchain_image].fence.get();
|
auto &present_fence = image_data[current_swapchain_image].fence.get();
|
||||||
device.resetFences(present_fence);
|
device.resetFences(present_fence);
|
||||||
vk::SwapchainPresentFenceInfoEXT present_fence_info(present_fence);
|
vk::SwapchainPresentFenceInfoEXT present_fence_info(present_fence);
|
||||||
|
|
||||||
|
present_info.setPNext(&present_mode_info);
|
||||||
present_mode_info.setPNext(&present_fence_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);
|
vk::Result result = queue.presentKHR(present_info);
|
||||||
if (result == vk::Result::eErrorOutOfDateKHR)
|
if (result == vk::Result::eErrorOutOfDateKHR)
|
||||||
{
|
{
|
||||||
|
@ -424,6 +435,15 @@ void Swapchain::wait_on_frames()
|
||||||
{
|
{
|
||||||
for (auto i = 0; i < image_data.size(); i++)
|
for (auto i = 0; i < image_data.size(); i++)
|
||||||
wait_on_frame(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()
|
vk::Extent2D Swapchain::get_extents()
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Context;
|
||||||
|
|
||||||
class Swapchain
|
class Swapchain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Swapchain(vk::Device device,
|
Swapchain(Context &);
|
||||||
vk::PhysicalDevice physical_device,
|
|
||||||
vk::Queue queue,
|
|
||||||
vk::SurfaceKHR surface,
|
|
||||||
vk::CommandPool command_pool);
|
|
||||||
~Swapchain();
|
~Swapchain();
|
||||||
bool create(unsigned int num_frames, int width = -1, int height = -1);
|
bool create(unsigned int num_frames, int width = -1, int height = -1);
|
||||||
bool recreate(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_frame = 0;
|
||||||
unsigned int current_swapchain_image = 0;
|
unsigned int current_swapchain_image = 0;
|
||||||
unsigned int num_swapchain_images = 0;
|
unsigned int num_swapchain_images = 0;
|
||||||
|
uint64_t presentation_id = 0;
|
||||||
bool vsync = true;
|
bool vsync = true;
|
||||||
bool supports_immediate = false;
|
bool supports_immediate = false;
|
||||||
bool supports_mailbox = false;
|
bool supports_mailbox = false;
|
||||||
|
@ -73,6 +72,7 @@ class Swapchain
|
||||||
std::vector<Frame> frames;
|
std::vector<Frame> frames;
|
||||||
std::vector<ImageData> image_data;
|
std::vector<ImageData> image_data;
|
||||||
|
|
||||||
|
Vulkan::Context &context;
|
||||||
vk::Device device;
|
vk::Device device;
|
||||||
vk::SurfaceKHR surface;
|
vk::SurfaceKHR surface;
|
||||||
vk::CommandPool command_pool;
|
vk::CommandPool command_pool;
|
||||||
|
|
Loading…
Reference in New Issue