Vulkan: Simplify some code.

This commit is contained in:
BearOso 2024-04-19 16:24:54 -05:00
parent 0ae69cd518
commit bb905521df
6 changed files with 50 additions and 57 deletions

View File

@ -40,7 +40,6 @@ class S9xVulkanDisplayDriver : public S9xDisplayDriver
std::unique_ptr<Vulkan::Context> context; std::unique_ptr<Vulkan::Context> context;
vk::Device device; vk::Device device;
vk::UniqueDescriptorPool imgui_descriptor_pool; vk::UniqueDescriptorPool imgui_descriptor_pool;
vk::UniqueRenderPass imgui_render_pass;
GdkDisplay *gdk_display; GdkDisplay *gdk_display;
GdkWindow *gdk_window; GdkWindow *gdk_window;

View File

@ -13,8 +13,6 @@
#include <QThread> #include <QThread>
#include <QStyleHints> #include <QStyleHints>
#include <thread> #include <thread>
#include <chrono>
using namespace std::chrono_literals;
#undef SOUND_BUFFER_WINDOW #undef SOUND_BUFFER_WINDOW
@ -65,7 +63,11 @@ void EmuApplication::restartAudio()
} }
#ifdef SOUND_BUFFER_WINDOW #ifdef SOUND_BUFFER_WINDOW
#include <QProgressDialog> #include <QProgressDialog>
#include <chrono>
using namespace std::chrono_literals;
static void trackBufferLevel(int percent, QWidget *parent) static void trackBufferLevel(int percent, QWidget *parent)
{ {
static uint64_t total = 0; static uint64_t total = 0;
@ -139,13 +141,6 @@ void EmuApplication::startGame()
if (window->canvas) if (window->canvas)
{ {
window->output((uint8_t *)data, width, height, QImage::Format_RGB16, stride_bytes, frame_rate); window->output((uint8_t *)data, width, height, QImage::Format_RGB16, stride_bytes, frame_rate);
// QMetaObject::invokeMethod(window.get(), "output", Qt::ConnectionType::DirectConnection,
// Q_ARG(uint8_t *, (uint8_t *)data),
// Q_ARG(int, width),
// Q_ARG(int, height),
// Q_ARG(QImage::Format, QImage::Format_RGB16),
// Q_ARG(int, stride_bytes),
// Q_ARG(double, frame_rate));
} }
}; };

View File

@ -277,7 +277,6 @@ void EmuCanvasVulkan::deinit()
if (context) if (context)
context->wait_idle(); context->wait_idle();
imgui_descriptor_pool.reset(); imgui_descriptor_pool.reset();
imgui_render_pass.reset();
ImGui_ImplVulkan_Shutdown(); ImGui_ImplVulkan_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
} }
@ -339,7 +338,6 @@ void EmuCanvasVulkan::recreateUIAssets()
{ {
context->wait_idle(); context->wait_idle();
imgui_descriptor_pool.reset(); imgui_descriptor_pool.reset();
imgui_render_pass.reset();
ImGui_ImplVulkan_Shutdown(); ImGui_ImplVulkan_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
} }

View File

@ -31,7 +31,6 @@ class EmuCanvasVulkan : public EmuCanvas
bool initImGui(); bool initImGui();
void recreateUIAssets() override; void recreateUIAssets() override;
vk::UniqueRenderPass imgui_render_pass;
vk::UniqueDescriptorPool imgui_descriptor_pool; vk::UniqueDescriptorPool imgui_descriptor_pool;
std::unique_ptr<Vulkan::Context> context; std::unique_ptr<Vulkan::Context> context;

View File

@ -1,9 +1,7 @@
#include <cstring> #include <cstring>
#include <tuple>
#include <vector> #include <vector>
#include <string> #include <string>
#include "vulkan_context.hpp" #include "vulkan_context.hpp"
#include "slang_shader.hpp"
namespace Vulkan namespace Vulkan
{ {
@ -18,18 +16,14 @@ Context::~Context()
{ {
if (!device) if (!device)
return; return;
wait_idle(); wait_idle();
swapchain.reset();
swapchain = nullptr;
command_pool.reset(); command_pool.reset();
descriptor_pool.reset(); descriptor_pool.reset();
allocator.destroy(); allocator.destroy();
surface.reset(); surface.reset();
wait_idle(); wait_idle();
device.destroy(); device.destroy();
} }
@ -58,8 +52,11 @@ static vk::UniqueInstance create_instance_preamble(const char *wsi_extension)
if (!dl || !dl->success()) if (!dl || !dl->success())
return {}; return {};
std::vector<const char *> extensions = { wsi_extension, VK_KHR_SURFACE_EXTENSION_NAME }; std::vector<const char *> extensions = {
vk::ApplicationInfo application_info({}, {}, {}, {}, VK_API_VERSION_1_0); wsi_extension,
VK_KHR_SURFACE_EXTENSION_NAME
};
vk::ApplicationInfo application_info({}, {}, {}, {}, VK_API_VERSION_1_1);
vk::InstanceCreateInfo instance_create_info({}, &application_info, {}, extensions); vk::InstanceCreateInfo instance_create_info({}, &application_info, {}, extensions);
auto [result, instance] = vk::createInstanceUnique(instance_create_info); auto [result, instance] = vk::createInstanceUnique(instance_create_info);
@ -118,7 +115,7 @@ bool Context::init_Xlib(Display *dpy, Window xid, int preferred_device)
instance = create_instance_preamble(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); instance = create_instance_preamble(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
if (!instance) if (!instance)
return false; return false;
auto retval = instance->createXlibSurfaceKHRUnique({ {}, dpy, xid }); auto retval = instance->createXlibSurfaceKHRUnique({ {}, dpy, xid });
if (retval.result != vk::Result::eSuccess) if (retval.result != vk::Result::eSuccess)
return false; return false;
@ -144,24 +141,18 @@ bool Context::init_wayland(wl_display *dpy, wl_surface *parent, int initial_widt
return false; return false;
surface = std::move(new_surface); surface = std::move(new_surface);
init_device(preferred_device); return init(preferred_device, initial_width, initial_height)
init_vma();
init_command_pool();
init_descriptor_pool();
create_swapchain(initial_width, initial_height);
wait_idle();
return true;
} }
#endif #endif
bool Context::init(int preferred_device) bool Context::init(int preferred_device, int initial_width, int initial_height)
{ {
init_device(preferred_device); init_device(preferred_device);
init_vma(); init_vma();
init_command_pool(); init_command_pool();
init_descriptor_pool(); init_descriptor_pool();
create_swapchain(); create_swapchain(initial_width, initial_height);
wait_idle(); wait_idle();
return true; return true;
} }
@ -175,7 +166,7 @@ bool Context::init_descriptor_pool()
.setPoolSizes(descriptor_pool_size) .setPoolSizes(descriptor_pool_size)
.setMaxSets(20) .setMaxSets(20)
.setFlags(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet); .setFlags(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet);
auto retval = device.createDescriptorPoolUnique(descriptor_pool_create_info); auto retval = device.createDescriptorPoolUnique(descriptor_pool_create_info);
descriptor_pool = std::move(retval.value); descriptor_pool = std::move(retval.value);
@ -194,49 +185,62 @@ bool Context::init_command_pool()
bool Context::init_device(int preferred_device) bool Context::init_device(int preferred_device)
{ {
auto device_list = instance->enumeratePhysicalDevices().value; const char *required_extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
auto find_device = [&]() -> vk::PhysicalDevice { // VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME
for (auto &d : device_list) };
{ auto check_extensions = [&](vk::PhysicalDevice &device) -> bool {
auto [retval, ep] = d.enumerateDeviceExtensionProperties(); auto [retval, props] = device.enumerateDeviceExtensionProperties();
auto exists = std::find_if(ep.begin(), ep.end(), [](vk::ExtensionProperties &ext) { for (const auto &extension : required_extensions) {
return (std::string(ext.extensionName.data()) == VK_KHR_SWAPCHAIN_EXTENSION_NAME); auto found = std::find_if(
props.begin(), props.end(), [&](vk::ExtensionProperties &ext) {
return (std::string(ext.extensionName.data()) == extension);
}); });
return found != props.end();
if (exists != ep.end())
return d;
} }
return device_list[0]; return true;
}; };
if (preferred_device > -1 && (size_t)preferred_device < device_list.size()) auto device_list = instance->enumeratePhysicalDevices().value;
if (preferred_device > -1 &&
preferred_device < device_list.size() &&
check_extensions(device_list[preferred_device]))
{
physical_device = device_list[preferred_device]; physical_device = device_list[preferred_device];
}
else else
physical_device = find_device(); {
for (auto &device : device_list)
if (check_extensions(device))
{
physical_device = device;
break;
}
}
physical_device.getProperties(&physical_device_props); physical_device.getProperties(&physical_device_props);
printf("Vulkan: Using device \"%s\"\n", (const char *)physical_device_props.deviceName);
graphics_queue_family_index = UINT32_MAX; graphics_queue_family_index = UINT32_MAX;
auto queue_props = physical_device.getQueueFamilyProperties(); auto queue_props = physical_device.getQueueFamilyProperties();
for (size_t i = 0; i < queue_props.size(); i++) for (size_t i = 0; i < queue_props.size(); i++)
{ {
if (queue_props[i].queueFlags & vk::QueueFlagBits::eGraphics) if (queue_props[i].queueFlags & vk::QueueFlagBits::eGraphics)
{
graphics_queue_family_index = i; graphics_queue_family_index = i;
break;
}
} }
if (graphics_queue_family_index == UINT32_MAX) if (graphics_queue_family_index == UINT32_MAX)
return false; return false;
std::vector<const char *> extension_names = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; vk::DeviceQueueCreateInfo dqci({}, graphics_queue_family_index, 1);
std::vector<float> priorities { 1.0f }; vk::DeviceCreateInfo dci({}, dqci, {}, required_extensions, {});
vk::DeviceQueueCreateInfo dqci({}, graphics_queue_family_index, priorities);
vk::DeviceCreateInfo dci({}, dqci, {}, extension_names, {});
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);
auto [retval, surface_formats] = physical_device.getSurfaceFormatsKHR(surface.get()); auto surface_formats = physical_device.getSurfaceFormatsKHR(surface.get()).value;
auto format = std::find_if(surface_formats.begin(), surface_formats.end(), [](vk::SurfaceFormatKHR &f) { auto format = std::find_if(surface_formats.begin(), surface_formats.end(), [](vk::SurfaceFormatKHR &f) {
return (f.format == vk::Format::eB8G8R8A8Unorm); return (f.format == vk::Format::eB8G8R8A8Unorm);
}); });

View File

@ -7,13 +7,11 @@
#undef WINVER #undef WINVER
#define WINVER 0x599 #define WINVER 0x599
#endif #endif
#include <cstdio>
#include <cstdint> #include <cstdint>
#include "vulkan/vulkan_hpp_wrapper.hpp" #include "vulkan/vulkan_hpp_wrapper.hpp"
#include "../external/VulkanMemoryAllocator-Hpp/include/vk_mem_alloc.hpp" #include "../external/VulkanMemoryAllocator-Hpp/include/vk_mem_alloc.hpp"
#include "vulkan_swapchain.hpp" #include "vulkan_swapchain.hpp"
#include <memory> #include <memory>
#include <optional>
namespace Vulkan namespace Vulkan
{ {
@ -32,7 +30,7 @@ class Context
#ifdef VK_USE_PLATFORM_WIN32_KHR #ifdef VK_USE_PLATFORM_WIN32_KHR
bool init_win32(HINSTANCE hinstance, HWND hwnd, int preferred_device = -1); bool init_win32(HINSTANCE hinstance, HWND hwnd, int preferred_device = -1);
#endif #endif
bool init(int preferred_device = -1); bool init(int preferred_device = -1, int initial_width = -1, int initial_height = -1);
bool create_swapchain(int width = -1, int height = -1); bool create_swapchain(int width = -1, int height = -1);
bool recreate_swapchain(int width = -1, int height = -1); bool recreate_swapchain(int width = -1, int height = -1);
void wait_idle(); void wait_idle();