mirror of
https://github.com/snes9xgit/snes9x.git
synced 2025-04-02 10:42:16 -04:00
Compare commits
6 commits
5949bbab97
...
a9e64edf73
Author | SHA1 | Date | |
---|---|---|---|
|
a9e64edf73 | ||
|
008cbcd1a1 | ||
|
3980a9d6d4 | ||
|
5c78493f4e | ||
|
33e40a8f16 | ||
|
2e25b70cf0 |
4 changed files with 56 additions and 59 deletions
|
@ -233,7 +233,7 @@ bool Context::init_device(int preferred_device)
|
||||||
physical_device = device_list[preferred_device];
|
physical_device = device_list[preferred_device];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (physical_device != nullptr)
|
if (physical_device == nullptr)
|
||||||
{
|
{
|
||||||
for (auto &device : device_list)
|
for (auto &device : device_list)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,13 +18,9 @@ Swapchain::~Swapchain()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Swapchain::set_vsync(bool new_setting)
|
void Swapchain::set_vsync(bool new_setting)
|
||||||
{
|
{
|
||||||
if (new_setting == vsync)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
vsync = new_setting;
|
vsync = new_setting;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swapchain::on_render_pass_end(std::function<void ()> function)
|
void Swapchain::on_render_pass_end(std::function<void ()> function)
|
||||||
|
@ -80,14 +76,39 @@ void Swapchain::create_render_pass()
|
||||||
bool Swapchain::recreate(int new_width, int new_height)
|
bool Swapchain::recreate(int new_width, int new_height)
|
||||||
{
|
{
|
||||||
if (swapchain_object)
|
if (swapchain_object)
|
||||||
|
{
|
||||||
|
device.waitIdle();
|
||||||
wait_on_frames();
|
wait_on_frames();
|
||||||
|
}
|
||||||
|
|
||||||
return create(num_swapchain_images, new_width, new_height);
|
return create(num_swapchain_images, new_width, new_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Image Swapchain::get_image()
|
vk::Image Swapchain::get_image()
|
||||||
{
|
{
|
||||||
return imageviewfbs[current_swapchain_image].image;
|
return image_data[current_swapchain_image].image;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool vector_find(std::vector<T> haystack, T&& needle)
|
||||||
|
{
|
||||||
|
for (auto &elem : haystack)
|
||||||
|
if (elem == needle)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PresentModeKHR Swapchain::get_present_mode() {
|
||||||
|
auto present_mode = vk::PresentModeKHR::eFifo;
|
||||||
|
|
||||||
|
if (!vsync) {
|
||||||
|
if (supports_mailbox)
|
||||||
|
present_mode = vk::PresentModeKHR::eMailbox;
|
||||||
|
if (supports_immediate)
|
||||||
|
present_mode = vk::PresentModeKHR::eImmediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return present_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Swapchain::check_and_resize(int width, int height)
|
bool Swapchain::check_and_resize(int width, int height)
|
||||||
|
@ -116,7 +137,7 @@ bool Swapchain::check_and_resize(int width, int height)
|
||||||
bool Swapchain::create(unsigned int desired_num_swapchain_images, int new_width, int new_height)
|
bool Swapchain::create(unsigned int desired_num_swapchain_images, int new_width, int new_height)
|
||||||
{
|
{
|
||||||
frames.clear();
|
frames.clear();
|
||||||
imageviewfbs.clear();
|
image_data.clear();
|
||||||
|
|
||||||
auto surface_capabilities = physical_device.getSurfaceCapabilitiesKHR(surface).value;
|
auto surface_capabilities = physical_device.getSurfaceCapabilitiesKHR(surface).value;
|
||||||
|
|
||||||
|
@ -165,21 +186,9 @@ bool Swapchain::create(unsigned int desired_num_swapchain_images, int new_width,
|
||||||
extents.height = surface_capabilities.minImageExtent.height;
|
extents.height = surface_capabilities.minImageExtent.height;
|
||||||
|
|
||||||
auto present_modes = physical_device.getSurfacePresentModesKHR(surface).value;
|
auto present_modes = physical_device.getSurfacePresentModesKHR(surface).value;
|
||||||
supports_mailbox =
|
supports_mailbox = vector_find(present_modes, vk::PresentModeKHR::eMailbox);
|
||||||
std::find(present_modes.begin(), present_modes.end(),
|
supports_immediate = vector_find(present_modes, vk::PresentModeKHR::eImmediate);
|
||||||
vk::PresentModeKHR::eMailbox) != present_modes.end();
|
supports_relaxed = vector_find(present_modes, vk::PresentModeKHR::eFifoRelaxed);
|
||||||
supports_immediate =
|
|
||||||
std::find(present_modes.begin(), present_modes.end(),
|
|
||||||
vk::PresentModeKHR::eImmediate) != present_modes.end();
|
|
||||||
|
|
||||||
auto present_mode = vk::PresentModeKHR::eFifo;
|
|
||||||
if (!vsync)
|
|
||||||
{
|
|
||||||
if (supports_mailbox)
|
|
||||||
present_mode = vk::PresentModeKHR::eMailbox;
|
|
||||||
if (supports_immediate)
|
|
||||||
present_mode = vk::PresentModeKHR::eImmediate;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto swapchain_maintenance_info = vk::SwapchainPresentModesCreateInfoEXT{}
|
auto swapchain_maintenance_info = vk::SwapchainPresentModesCreateInfoEXT{}
|
||||||
.setPresentModes(present_modes);
|
.setPresentModes(present_modes);
|
||||||
|
@ -193,7 +202,7 @@ bool Swapchain::create(unsigned int desired_num_swapchain_images, int new_width,
|
||||||
.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc)
|
.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferSrc)
|
||||||
.setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
|
.setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
|
||||||
.setClipped(true)
|
.setClipped(true)
|
||||||
.setPresentMode(present_mode)
|
.setPresentMode(get_present_mode())
|
||||||
.setSurface(surface)
|
.setSurface(surface)
|
||||||
.setPreTransform(vk::SurfaceTransformFlagBitsKHR::eIdentity)
|
.setPreTransform(vk::SurfaceTransformFlagBitsKHR::eIdentity)
|
||||||
.setImageArrayLayers(1)
|
.setImageArrayLayers(1)
|
||||||
|
@ -224,7 +233,7 @@ bool Swapchain::create_resources()
|
||||||
auto command_buffers = device.allocateCommandBuffersUnique(command_buffer_allocate_info).value;
|
auto command_buffers = device.allocateCommandBuffersUnique(command_buffer_allocate_info).value;
|
||||||
|
|
||||||
frames.resize(num_swapchain_images);
|
frames.resize(num_swapchain_images);
|
||||||
imageviewfbs.resize(num_swapchain_images);
|
image_data.resize(num_swapchain_images);
|
||||||
|
|
||||||
vk::FenceCreateInfo fence_create_info(vk::FenceCreateFlagBits::eSignaled);
|
vk::FenceCreateInfo fence_create_info(vk::FenceCreateFlagBits::eSignaled);
|
||||||
|
|
||||||
|
@ -234,7 +243,6 @@ bool Swapchain::create_resources()
|
||||||
auto &frame = frames[i];
|
auto &frame = frames[i];
|
||||||
frame.command_buffer = std::move(command_buffers[i]);
|
frame.command_buffer = std::move(command_buffers[i]);
|
||||||
frame.fence = device.createFenceUnique(fence_create_info).value;
|
frame.fence = device.createFenceUnique(fence_create_info).value;
|
||||||
frame.freeable = device.createFenceUnique(fence_create_info).value;
|
|
||||||
frame.acquire = device.createSemaphoreUnique({}).value;
|
frame.acquire = device.createSemaphoreUnique({}).value;
|
||||||
frame.complete = device.createSemaphoreUnique({}).value;
|
frame.complete = device.createSemaphoreUnique({}).value;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +250,7 @@ bool Swapchain::create_resources()
|
||||||
for (unsigned int i = 0; i < num_swapchain_images; i++)
|
for (unsigned int i = 0; i < num_swapchain_images; i++)
|
||||||
{
|
{
|
||||||
// Create resources associated with swapchain images
|
// Create resources associated with swapchain images
|
||||||
auto &image = imageviewfbs[i];
|
auto &image = image_data[i];
|
||||||
image.image = swapchain_images[i];
|
image.image = swapchain_images[i];
|
||||||
auto image_view_create_info = vk::ImageViewCreateInfo{}
|
auto image_view_create_info = vk::ImageViewCreateInfo{}
|
||||||
.setImage(swapchain_images[i])
|
.setImage(swapchain_images[i])
|
||||||
|
@ -259,6 +267,8 @@ bool Swapchain::create_resources()
|
||||||
.setLayers(1)
|
.setLayers(1)
|
||||||
.setRenderPass(render_pass.get());
|
.setRenderPass(render_pass.get());
|
||||||
image.framebuffer = device.createFramebufferUnique(framebuffer_create_info).value;
|
image.framebuffer = device.createFramebufferUnique(framebuffer_create_info).value;
|
||||||
|
|
||||||
|
image.fence = device.createFenceUnique(fence_create_info).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_swapchain_image = 0;
|
current_swapchain_image = 0;
|
||||||
|
@ -277,7 +287,7 @@ bool Swapchain::begin_frame()
|
||||||
|
|
||||||
auto &frame = frames[current_frame];
|
auto &frame = frames[current_frame];
|
||||||
|
|
||||||
auto result = device.waitForFences({ frame.fence.get(), frame.freeable.get() }, true, 33333333);
|
auto result = device.waitForFences({ frame.fence.get() }, true, 33333333);
|
||||||
if (result != vk::Result::eSuccess)
|
if (result != vk::Result::eSuccess)
|
||||||
{
|
{
|
||||||
printf("Timed out waiting for fence.\n");
|
printf("Timed out waiting for fence.\n");
|
||||||
|
@ -339,19 +349,13 @@ bool Swapchain::swap()
|
||||||
.setImageIndices(current_swapchain_image);
|
.setImageIndices(current_swapchain_image);
|
||||||
|
|
||||||
vk::SwapchainPresentModeInfoEXT present_mode_info;
|
vk::SwapchainPresentModeInfoEXT present_mode_info;
|
||||||
vk::PresentModeKHR present_mode = vk::PresentModeKHR::eFifo;
|
auto present_mode = get_present_mode();
|
||||||
if (!vsync)
|
|
||||||
{
|
|
||||||
if (supports_mailbox)
|
|
||||||
present_mode = vk::PresentModeKHR::eMailbox;
|
|
||||||
if (supports_immediate)
|
|
||||||
present_mode = vk::PresentModeKHR::eImmediate;
|
|
||||||
}
|
|
||||||
present_mode_info.setPresentModes(present_mode);
|
present_mode_info.setPresentModes(present_mode);
|
||||||
present_info.setPNext(&present_mode_info);
|
present_info.setPNext(&present_mode_info);
|
||||||
|
|
||||||
device.resetFences(frames[current_frame].freeable.get());
|
auto &present_fence = image_data[current_swapchain_image].fence.get();
|
||||||
vk::SwapchainPresentFenceInfoEXT present_fence_info(frames[current_frame].freeable.get());
|
device.resetFences(present_fence);
|
||||||
|
vk::SwapchainPresentFenceInfoEXT present_fence_info(present_fence);
|
||||||
present_mode_info.setPNext(&present_fence_info);
|
present_mode_info.setPNext(&present_fence_info);
|
||||||
|
|
||||||
vk::Result result = queue.presentKHR(present_info);
|
vk::Result result = queue.presentKHR(present_info);
|
||||||
|
@ -376,7 +380,7 @@ bool Swapchain::end_frame()
|
||||||
|
|
||||||
vk::Framebuffer Swapchain::get_framebuffer()
|
vk::Framebuffer Swapchain::get_framebuffer()
|
||||||
{
|
{
|
||||||
return imageviewfbs[current_swapchain_image].framebuffer.get();
|
return image_data[current_swapchain_image].framebuffer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::CommandBuffer &Swapchain::get_cmd()
|
vk::CommandBuffer &Swapchain::get_cmd()
|
||||||
|
@ -393,7 +397,7 @@ void Swapchain::begin_render_pass()
|
||||||
|
|
||||||
auto render_pass_begin_info = vk::RenderPassBeginInfo{}
|
auto render_pass_begin_info = vk::RenderPassBeginInfo{}
|
||||||
.setRenderPass(render_pass.get())
|
.setRenderPass(render_pass.get())
|
||||||
.setFramebuffer(imageviewfbs[current_swapchain_image].framebuffer.get())
|
.setFramebuffer(image_data[current_swapchain_image].framebuffer.get())
|
||||||
.setRenderArea(vk::Rect2D({}, extents))
|
.setRenderArea(vk::Rect2D({}, extents))
|
||||||
.setClearValues(value);
|
.setClearValues(value);
|
||||||
get_cmd().beginRenderPass(render_pass_begin_info, vk::SubpassContents::eInline);
|
get_cmd().beginRenderPass(render_pass_begin_info, vk::SubpassContents::eInline);
|
||||||
|
@ -412,13 +416,13 @@ void Swapchain::end_render_pass()
|
||||||
|
|
||||||
bool Swapchain::wait_on_frame(int frame_num)
|
bool Swapchain::wait_on_frame(int frame_num)
|
||||||
{
|
{
|
||||||
auto result = device.waitForFences({ frames[frame_num].fence.get(), frames[frame_num].freeable.get() }, true, 133000000);
|
auto result = device.waitForFences({ image_data[frame_num].fence.get() }, true, 33000000);
|
||||||
return (result == vk::Result::eSuccess);
|
return (result == vk::Result::eSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swapchain::wait_on_frames()
|
void Swapchain::wait_on_frames()
|
||||||
{
|
{
|
||||||
for (auto i = 0; i < frames.size(); i++)
|
for (auto i = 0; i < image_data.size(); i++)
|
||||||
wait_on_frame(i);
|
wait_on_frame(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@ class Swapchain
|
||||||
void end_frame_without_swap();
|
void end_frame_without_swap();
|
||||||
bool swap();
|
bool swap();
|
||||||
void wait_on_frames();
|
void wait_on_frames();
|
||||||
// Returns true if vsync setting was changed, false if it was the same
|
void set_vsync(bool on);
|
||||||
bool set_vsync(bool on);
|
|
||||||
void on_render_pass_end(std::function<void()> function);
|
void on_render_pass_end(std::function<void()> function);
|
||||||
int get_num_frames() { return num_swapchain_images; }
|
int get_num_frames() { return num_swapchain_images; }
|
||||||
|
vk::PresentModeKHR get_present_mode();
|
||||||
|
|
||||||
vk::Image get_image();
|
vk::Image get_image();
|
||||||
vk::Framebuffer get_framebuffer();
|
vk::Framebuffer get_framebuffer();
|
||||||
|
@ -45,15 +45,15 @@ class Swapchain
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
vk::UniqueFence fence;
|
vk::UniqueFence fence;
|
||||||
vk::UniqueFence freeable;
|
|
||||||
vk::UniqueSemaphore acquire;
|
vk::UniqueSemaphore acquire;
|
||||||
vk::UniqueSemaphore complete;
|
vk::UniqueSemaphore complete;
|
||||||
vk::UniqueCommandBuffer command_buffer;
|
vk::UniqueCommandBuffer command_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImageViewFB
|
struct ImageData
|
||||||
{
|
{
|
||||||
vk::Image image;
|
vk::Image image;
|
||||||
|
vk::UniqueFence fence;
|
||||||
vk::UniqueImageView image_view;
|
vk::UniqueImageView image_view;
|
||||||
vk::UniqueFramebuffer framebuffer;
|
vk::UniqueFramebuffer framebuffer;
|
||||||
};
|
};
|
||||||
|
@ -69,8 +69,9 @@ class Swapchain
|
||||||
bool vsync = true;
|
bool vsync = true;
|
||||||
bool supports_immediate = false;
|
bool supports_immediate = false;
|
||||||
bool supports_mailbox = false;
|
bool supports_mailbox = false;
|
||||||
|
bool supports_relaxed = false;
|
||||||
std::vector<Frame> frames;
|
std::vector<Frame> frames;
|
||||||
std::vector<ImageViewFB> imageviewfbs;
|
std::vector<ImageData> image_data;
|
||||||
|
|
||||||
vk::Device device;
|
vk::Device device;
|
||||||
vk::SurfaceKHR surface;
|
vk::SurfaceKHR surface;
|
||||||
|
|
|
@ -70,6 +70,8 @@ bool CVulkan::Initialize(HWND hWnd)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context->swapchain->set_vsync(GUI.Vsync);
|
||||||
|
|
||||||
if (!Settings.AutoDisplayMessages)
|
if (!Settings.AutoDisplayMessages)
|
||||||
{
|
{
|
||||||
Settings.DisplayIndicators = true;
|
Settings.DisplayIndicators = true;
|
||||||
|
@ -91,11 +93,6 @@ bool CVulkan::Initialize(HWND hWnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->swapchain->set_vsync(GUI.Vsync))
|
|
||||||
{
|
|
||||||
context->recreate_swapchain();
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_output = std::make_unique<Vulkan::SimpleOutput>(context.get(), vk::Format::eR5G6B5UnormPack16);
|
simple_output = std::make_unique<Vulkan::SimpleOutput>(context.get(), vk::Format::eR5G6B5UnormPack16);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -181,9 +178,7 @@ bool CVulkan::ChangeRenderSize(unsigned int newWidth, unsigned int newHeight)
|
||||||
if (!context)
|
if (!context)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool vsync_changed = context->swapchain->set_vsync(GUI.Vsync);
|
if (newWidth != current_width || newHeight != current_height)
|
||||||
|
|
||||||
if (newWidth != current_width || newHeight != current_height || vsync_changed)
|
|
||||||
{
|
{
|
||||||
context->recreate_swapchain(newWidth, newHeight);
|
context->recreate_swapchain(newWidth, newHeight);
|
||||||
context->wait_idle();
|
context->wait_idle();
|
||||||
|
@ -218,10 +213,7 @@ bool CVulkan::ApplyDisplayChanges(void)
|
||||||
current_shadername = shadername;
|
current_shadername = shadername;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->swapchain->set_vsync(GUI.Vsync))
|
context->swapchain->set_vsync(GUI.Vsync);
|
||||||
{
|
|
||||||
context->recreate_swapchain();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue