mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 17:19:18 +01:00
Vulkan: Several swapchain fixes and refactors (#1132)
This commit is contained in:
parent
4d609f06b8
commit
17060752b6
@ -1,15 +1,34 @@
|
|||||||
#include "SwapchainInfoVk.h"
|
#include "SwapchainInfoVk.h"
|
||||||
|
|
||||||
#include "config/CemuConfig.h"
|
#include "config/CemuConfig.h"
|
||||||
|
#include "gui/guiWrapper.h"
|
||||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||||
#include "Cafe/HW/Latte/Core/LatteTiming.h"
|
#include "Cafe/HW/Latte/Core/LatteTiming.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
||||||
|
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h"
|
||||||
|
|
||||||
void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDevice)
|
SwapchainInfoVk::SwapchainInfoVk(bool mainWindow, Vector2i size) : mainWindow(mainWindow), m_desiredExtent(size)
|
||||||
{
|
{
|
||||||
m_physicalDevice = physicalDevice;
|
auto& windowHandleInfo = mainWindow ? gui_getWindowInfo().canvas_main : gui_getWindowInfo().canvas_pad;
|
||||||
m_logicalDevice = logicalDevice;
|
auto renderer = VulkanRenderer::GetInstance();
|
||||||
const auto details = QuerySwapchainSupport(surface, physicalDevice);
|
m_instance = renderer->GetVkInstance();
|
||||||
|
m_logicalDevice = renderer->GetLogicalDevice();
|
||||||
|
m_physicalDevice = renderer->GetPhysicalDevice();
|
||||||
|
|
||||||
|
m_surface = renderer->CreateFramebufferSurface(m_instance, windowHandleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SwapchainInfoVk::~SwapchainInfoVk()
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
if(m_surface != VK_NULL_HANDLE)
|
||||||
|
vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapchainInfoVk::Create()
|
||||||
|
{
|
||||||
|
const auto details = QuerySwapchainSupport(m_surface, m_physicalDevice);
|
||||||
m_surfaceFormat = ChooseSurfaceFormat(details.formats);
|
m_surfaceFormat = ChooseSurfaceFormat(details.formats);
|
||||||
m_actualExtent = ChooseSwapExtent(details.capabilities);
|
m_actualExtent = ChooseSwapExtent(details.capabilities);
|
||||||
|
|
||||||
@ -20,28 +39,28 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
if(image_count < 2)
|
if(image_count < 2)
|
||||||
cemuLog_log(LogType::Force, "Vulkan: Swapchain image count less than 2 may cause problems");
|
cemuLog_log(LogType::Force, "Vulkan: Swapchain image count less than 2 may cause problems");
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR create_info = CreateSwapchainCreateInfo(surface, details, m_surfaceFormat, image_count, m_actualExtent);
|
VkSwapchainCreateInfoKHR create_info = CreateSwapchainCreateInfo(m_surface, details, m_surfaceFormat, image_count, m_actualExtent);
|
||||||
create_info.oldSwapchain = nullptr;
|
create_info.oldSwapchain = nullptr;
|
||||||
create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||||
|
|
||||||
VkResult result = vkCreateSwapchainKHR(logicalDevice, &create_info, nullptr, &swapchain);
|
VkResult result = vkCreateSwapchainKHR(m_logicalDevice, &create_info, nullptr, &m_swapchain);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Error attempting to create a swapchain");
|
UnrecoverableError("Error attempting to create a swapchain");
|
||||||
|
|
||||||
result = vkGetSwapchainImagesKHR(logicalDevice, swapchain, &image_count, nullptr);
|
result = vkGetSwapchainImagesKHR(m_logicalDevice, m_swapchain, &image_count, nullptr);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Error attempting to retrieve the count of swapchain images");
|
UnrecoverableError("Error attempting to retrieve the count of swapchain images");
|
||||||
|
|
||||||
|
|
||||||
m_swapchainImages.resize(image_count);
|
m_swapchainImages.resize(image_count);
|
||||||
result = vkGetSwapchainImagesKHR(logicalDevice, swapchain, &image_count, m_swapchainImages.data());
|
result = vkGetSwapchainImagesKHR(m_logicalDevice, m_swapchain, &image_count, m_swapchainImages.data());
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Error attempting to retrieve swapchain images");
|
UnrecoverableError("Error attempting to retrieve swapchain images");
|
||||||
// create default renderpass
|
// create default renderpass
|
||||||
VkAttachmentDescription colorAttachment = {};
|
VkAttachmentDescription colorAttachment = {};
|
||||||
colorAttachment.format = m_surfaceFormat.format;
|
colorAttachment.format = m_surfaceFormat.format;
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
@ -62,7 +81,7 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
renderPassInfo.pAttachments = &colorAttachment;
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
renderPassInfo.subpassCount = 1;
|
renderPassInfo.subpassCount = 1;
|
||||||
renderPassInfo.pSubpasses = &subpass;
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
result = vkCreateRenderPass(logicalDevice, &renderPassInfo, nullptr, &m_swapchainRenderPass);
|
result = vkCreateRenderPass(m_logicalDevice, &renderPassInfo, nullptr, &m_swapchainRenderPass);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create renderpass for swapchain");
|
UnrecoverableError("Failed to create renderpass for swapchain");
|
||||||
|
|
||||||
@ -84,7 +103,7 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
createInfo.subresourceRange.levelCount = 1;
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
result = vkCreateImageView(logicalDevice, &createInfo, nullptr, &m_swapchainImageViews[i]);
|
result = vkCreateImageView(m_logicalDevice, &createInfo, nullptr, &m_swapchainImageViews[i]);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create imageviews for swapchain");
|
UnrecoverableError("Failed to create imageviews for swapchain");
|
||||||
}
|
}
|
||||||
@ -104,7 +123,7 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
framebufferInfo.width = m_actualExtent.width;
|
framebufferInfo.width = m_actualExtent.width;
|
||||||
framebufferInfo.height = m_actualExtent.height;
|
framebufferInfo.height = m_actualExtent.height;
|
||||||
framebufferInfo.layers = 1;
|
framebufferInfo.layers = 1;
|
||||||
result = vkCreateFramebuffer(logicalDevice, &framebufferInfo, nullptr, &m_swapchainFramebuffers[i]);
|
result = vkCreateFramebuffer(m_logicalDevice, &framebufferInfo, nullptr, &m_swapchainFramebuffers[i]);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create framebuffer for swapchain");
|
UnrecoverableError("Failed to create framebuffer for swapchain");
|
||||||
}
|
}
|
||||||
@ -114,7 +133,7 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
VkSemaphoreCreateInfo info = {};
|
VkSemaphoreCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
for (auto& semaphore : m_presentSemaphores){
|
for (auto& semaphore : m_presentSemaphores){
|
||||||
if (vkCreateSemaphore(logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
|
if (vkCreateSemaphore(m_logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create semaphore for swapchain present");
|
UnrecoverableError("Failed to create semaphore for swapchain present");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,14 +142,14 @@ void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDe
|
|||||||
info = {};
|
info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
for (auto& semaphore : m_acquireSemaphores){
|
for (auto& semaphore : m_acquireSemaphores){
|
||||||
if (vkCreateSemaphore(logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
|
if (vkCreateSemaphore(m_logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create semaphore for swapchain acquire");
|
UnrecoverableError("Failed to create semaphore for swapchain acquire");
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFenceCreateInfo fenceInfo = {};
|
VkFenceCreateInfo fenceInfo = {};
|
||||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
result = vkCreateFence(logicalDevice, &fenceInfo, nullptr, &m_imageAvailableFence);
|
result = vkCreateFence(m_logicalDevice, &fenceInfo, nullptr, &m_imageAvailableFence);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
UnrecoverableError("Failed to create fence for swapchain");
|
UnrecoverableError("Failed to create fence for swapchain");
|
||||||
|
|
||||||
@ -167,19 +186,20 @@ void SwapchainInfoVk::Cleanup()
|
|||||||
|
|
||||||
if (m_imageAvailableFence)
|
if (m_imageAvailableFence)
|
||||||
{
|
{
|
||||||
|
WaitAvailableFence();
|
||||||
vkDestroyFence(m_logicalDevice, m_imageAvailableFence, nullptr);
|
vkDestroyFence(m_logicalDevice, m_imageAvailableFence, nullptr);
|
||||||
m_imageAvailableFence = nullptr;
|
m_imageAvailableFence = nullptr;
|
||||||
}
|
}
|
||||||
if (swapchain)
|
if (m_swapchain)
|
||||||
{
|
{
|
||||||
vkDestroySwapchainKHR(m_logicalDevice, swapchain, nullptr);
|
vkDestroySwapchainKHR(m_logicalDevice, m_swapchain, nullptr);
|
||||||
swapchain = VK_NULL_HANDLE;
|
m_swapchain = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwapchainInfoVk::IsValid() const
|
bool SwapchainInfoVk::IsValid() const
|
||||||
{
|
{
|
||||||
return swapchain && !m_acquireSemaphores.empty();
|
return m_swapchain && !m_acquireSemaphores.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapchainInfoVk::WaitAvailableFence()
|
void SwapchainInfoVk::WaitAvailableFence()
|
||||||
@ -207,7 +227,7 @@ bool SwapchainInfoVk::AcquireImage(uint64 timeout)
|
|||||||
ResetAvailableFence();
|
ResetAvailableFence();
|
||||||
|
|
||||||
VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
|
VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
|
||||||
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, swapchain, timeout, acquireSemaphore, m_imageAvailableFence, &swapchainImageIndex);
|
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, m_swapchain, timeout, acquireSemaphore, m_imageAvailableFence, &swapchainImageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||||
m_shouldRecreate = true;
|
m_shouldRecreate = true;
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
@ -231,35 +251,6 @@ void SwapchainInfoVk::UnrecoverableError(const char* errMsg)
|
|||||||
throw std::runtime_error(errMsg);
|
throw std::runtime_error(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapchainInfoVk::QueueFamilyIndices SwapchainInfoVk::FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device)
|
|
||||||
{
|
|
||||||
uint32_t queueFamilyCount = 0;
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
|
|
||||||
|
|
||||||
QueueFamilyIndices indices;
|
|
||||||
for (int i = 0; i < (int)queueFamilies.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto& queueFamily = queueFamilies[i];
|
|
||||||
if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
||||||
indices.graphicsFamily = i;
|
|
||||||
|
|
||||||
VkBool32 presentSupport = false;
|
|
||||||
const VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
|
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
throw std::runtime_error(fmt::format("Error while attempting to check if a surface supports presentation: {}", result));
|
|
||||||
|
|
||||||
if (queueFamily.queueCount > 0 && presentSupport)
|
|
||||||
indices.presentFamily = i;
|
|
||||||
|
|
||||||
if (indices.IsComplete())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwapchainInfoVk::SwapchainSupportDetails SwapchainInfoVk::QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device)
|
SwapchainInfoVk::SwapchainSupportDetails SwapchainInfoVk::QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device)
|
||||||
{
|
{
|
||||||
@ -391,7 +382,7 @@ VkSwapchainCreateInfoKHR SwapchainInfoVk::CreateSwapchainCreateInfo(VkSurfaceKHR
|
|||||||
createInfo.imageArrayLayers = 1;
|
createInfo.imageArrayLayers = 1;
|
||||||
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
const QueueFamilyIndices indices = FindQueueFamilies(surface, m_physicalDevice);
|
const VulkanRenderer::QueueFamilyIndices indices = VulkanRenderer::GetInstance()->FindQueueFamilies(surface, m_physicalDevice);
|
||||||
m_swapchainQueueFamilyIndices = { (uint32)indices.graphicsFamily, (uint32)indices.presentFamily };
|
m_swapchainQueueFamilyIndices = { (uint32)indices.graphicsFamily, (uint32)indices.presentFamily };
|
||||||
if (indices.graphicsFamily != indices.presentFamily)
|
if (indices.graphicsFamily != indices.presentFamily)
|
||||||
{
|
{
|
||||||
|
@ -14,14 +14,6 @@ struct SwapchainInfoVk
|
|||||||
SYNC_AND_LIMIT = 3, // synchronize emulated vsync events to monitor vsync. But skip events if rate higher than virtual vsync period
|
SYNC_AND_LIMIT = 3, // synchronize emulated vsync events to monitor vsync. But skip events if rate higher than virtual vsync period
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueueFamilyIndices
|
|
||||||
{
|
|
||||||
int32_t graphicsFamily = -1;
|
|
||||||
int32_t presentFamily = -1;
|
|
||||||
|
|
||||||
bool IsComplete() const { return graphicsFamily >= 0 && presentFamily >= 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SwapchainSupportDetails
|
struct SwapchainSupportDetails
|
||||||
{
|
{
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
@ -30,7 +22,7 @@ struct SwapchainInfoVk
|
|||||||
};
|
};
|
||||||
|
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void Create(VkPhysicalDevice physicalDevice, VkDevice logicalDevice);
|
void Create();
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
@ -45,8 +37,6 @@ struct SwapchainInfoVk
|
|||||||
|
|
||||||
static void UnrecoverableError(const char* errMsg);
|
static void UnrecoverableError(const char* errMsg);
|
||||||
|
|
||||||
// todo: move this function somewhere more sensible. Not directly swapchain related
|
|
||||||
static QueueFamilyIndices FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device);
|
|
||||||
static SwapchainSupportDetails QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device);
|
static SwapchainSupportDetails QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device);
|
||||||
|
|
||||||
VkPresentModeKHR ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes);
|
VkPresentModeKHR ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes);
|
||||||
@ -61,14 +51,10 @@ struct SwapchainInfoVk
|
|||||||
return m_actualExtent;
|
return m_actualExtent;
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapchainInfoVk(VkSurfaceKHR surface, bool mainWindow)
|
SwapchainInfoVk(bool mainWindow, Vector2i size);
|
||||||
: surface(surface), mainWindow(mainWindow) {}
|
|
||||||
SwapchainInfoVk(const SwapchainInfoVk&) = delete;
|
SwapchainInfoVk(const SwapchainInfoVk&) = delete;
|
||||||
SwapchainInfoVk(SwapchainInfoVk&&) noexcept = default;
|
SwapchainInfoVk(SwapchainInfoVk&&) noexcept = default;
|
||||||
~SwapchainInfoVk()
|
~SwapchainInfoVk();
|
||||||
{
|
|
||||||
Cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mainWindow{};
|
bool mainWindow{};
|
||||||
|
|
||||||
@ -77,11 +63,12 @@ struct SwapchainInfoVk
|
|||||||
VSync m_vsyncState = VSync::Immediate;
|
VSync m_vsyncState = VSync::Immediate;
|
||||||
bool hasDefinedSwapchainImage{}; // indicates if the swapchain image is in a defined state
|
bool hasDefinedSwapchainImage{}; // indicates if the swapchain image is in a defined state
|
||||||
|
|
||||||
|
VkInstance m_instance{};
|
||||||
VkPhysicalDevice m_physicalDevice{};
|
VkPhysicalDevice m_physicalDevice{};
|
||||||
VkDevice m_logicalDevice{};
|
VkDevice m_logicalDevice{};
|
||||||
VkSurfaceKHR surface{};
|
VkSurfaceKHR m_surface{};
|
||||||
VkSurfaceFormatKHR m_surfaceFormat{};
|
VkSurfaceFormatKHR m_surfaceFormat{};
|
||||||
VkSwapchainKHR swapchain{};
|
VkSwapchainKHR m_swapchain{};
|
||||||
Vector2i m_desiredExtent{};
|
Vector2i m_desiredExtent{};
|
||||||
uint32 swapchainImageIndex = (uint32)-1;
|
uint32 swapchainImageIndex = (uint32)-1;
|
||||||
|
|
||||||
|
@ -167,6 +167,7 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
|||||||
result.emplace_back(physDeviceProps.properties.deviceName, physDeviceIDProps.deviceUUID);
|
result.emplace_back(physDeviceProps.properties.deviceName, physDeviceIDProps.deviceUUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -441,7 +442,7 @@ VulkanRenderer::VulkanRenderer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create logical device
|
// create logical device
|
||||||
m_indices = SwapchainInfoVk::FindQueueFamilies(surface, m_physicalDevice);
|
m_indices = FindQueueFamilies(surface, m_physicalDevice);
|
||||||
std::set<int> uniqueQueueFamilies = { m_indices.graphicsFamily, m_indices.presentFamily };
|
std::set<int> uniqueQueueFamilies = { m_indices.graphicsFamily, m_indices.presentFamily };
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos = CreateQueueCreateInfos(uniqueQueueFamilies);
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos = CreateQueueCreateInfos(uniqueQueueFamilies);
|
||||||
VkPhysicalDeviceFeatures deviceFeatures = {};
|
VkPhysicalDeviceFeatures deviceFeatures = {};
|
||||||
@ -510,7 +511,7 @@ VulkanRenderer::VulkanRenderer()
|
|||||||
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(m_instance, "vkCreateDebugUtilsMessengerEXT"));
|
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(m_instance, "vkCreateDebugUtilsMessengerEXT"));
|
||||||
|
|
||||||
VkDebugUtilsMessengerCreateInfoEXT debugCallback{};
|
VkDebugUtilsMessengerCreateInfoEXT debugCallback{};
|
||||||
debugCallback.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
debugCallback.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||||
debugCallback.pNext = nullptr;
|
debugCallback.pNext = nullptr;
|
||||||
debugCallback.flags = 0;
|
debugCallback.flags = 0;
|
||||||
debugCallback.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
debugCallback.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
||||||
@ -673,24 +674,19 @@ VulkanRenderer* VulkanRenderer::GetInstance()
|
|||||||
|
|
||||||
void VulkanRenderer::InitializeSurface(const Vector2i& size, bool mainWindow)
|
void VulkanRenderer::InitializeSurface(const Vector2i& size, bool mainWindow)
|
||||||
{
|
{
|
||||||
auto& windowHandleInfo = mainWindow ? gui_getWindowInfo().canvas_main : gui_getWindowInfo().canvas_pad;
|
|
||||||
|
|
||||||
const auto surface = CreateFramebufferSurface(m_instance, windowHandleInfo);
|
|
||||||
if (mainWindow)
|
if (mainWindow)
|
||||||
{
|
{
|
||||||
m_mainSwapchainInfo = std::make_unique<SwapchainInfoVk>(surface, mainWindow);
|
m_mainSwapchainInfo = std::make_unique<SwapchainInfoVk>(mainWindow, size);
|
||||||
m_mainSwapchainInfo->m_desiredExtent = size;
|
m_mainSwapchainInfo->Create();
|
||||||
m_mainSwapchainInfo->Create(m_physicalDevice, m_logicalDevice);
|
|
||||||
|
|
||||||
// aquire first command buffer
|
// aquire first command buffer
|
||||||
InitFirstCommandBuffer();
|
InitFirstCommandBuffer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_padSwapchainInfo = std::make_unique<SwapchainInfoVk>(surface, mainWindow);
|
m_padSwapchainInfo = std::make_unique<SwapchainInfoVk>(mainWindow, size);
|
||||||
m_padSwapchainInfo->m_desiredExtent = size;
|
|
||||||
// todo: figure out a way to exclusively create swapchain on main LatteThread
|
// todo: figure out a way to exclusively create swapchain on main LatteThread
|
||||||
m_padSwapchainInfo->Create(m_physicalDevice, m_logicalDevice);
|
m_padSwapchainInfo->Create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,6 +1070,36 @@ RendererShader* VulkanRenderer::shader_create(RendererShader::ShaderType type, u
|
|||||||
return new RendererShaderVk(type, baseHash, auxHash, isGameShader, isGfxPackShader, source);
|
return new RendererShaderVk(type, baseHash, auxHash, isGameShader, isGfxPackShader, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VulkanRenderer::QueueFamilyIndices VulkanRenderer::FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t queueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
|
||||||
|
|
||||||
|
QueueFamilyIndices indices;
|
||||||
|
for (int i = 0; i < (int)queueFamilies.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto& queueFamily = queueFamilies[i];
|
||||||
|
if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
indices.graphicsFamily = i;
|
||||||
|
|
||||||
|
VkBool32 presentSupport = false;
|
||||||
|
const VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
throw std::runtime_error(fmt::format("Error while attempting to check if a surface supports presentation: {}", result));
|
||||||
|
|
||||||
|
if (queueFamily.queueCount > 0 && presentSupport)
|
||||||
|
indices.presentFamily = i;
|
||||||
|
|
||||||
|
if (indices.IsComplete())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device, FeatureControl& info)
|
bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device, FeatureControl& info)
|
||||||
{
|
{
|
||||||
std::vector<VkExtensionProperties> availableDeviceExtensions;
|
std::vector<VkExtensionProperties> availableDeviceExtensions;
|
||||||
@ -1215,7 +1241,7 @@ std::vector<const char*> VulkanRenderer::CheckInstanceExtensionSupport(FeatureCo
|
|||||||
|
|
||||||
bool VulkanRenderer::IsDeviceSuitable(VkSurfaceKHR surface, const VkPhysicalDevice& device)
|
bool VulkanRenderer::IsDeviceSuitable(VkSurfaceKHR surface, const VkPhysicalDevice& device)
|
||||||
{
|
{
|
||||||
if (!SwapchainInfoVk::FindQueueFamilies(surface, device).IsComplete())
|
if (!FindQueueFamilies(surface, device).IsComplete())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check API version (using Vulkan 1.0 way of querying properties)
|
// check API version (using Vulkan 1.0 way of querying properties)
|
||||||
@ -2605,7 +2631,7 @@ void VulkanRenderer::RecreateSwapchain(bool mainWindow, bool skipCreate)
|
|||||||
chainInfo.m_desiredExtent = size;
|
chainInfo.m_desiredExtent = size;
|
||||||
if(!skipCreate)
|
if(!skipCreate)
|
||||||
{
|
{
|
||||||
chainInfo.Create(m_physicalDevice, m_logicalDevice);
|
chainInfo.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainWindow)
|
if (mainWindow)
|
||||||
@ -2675,7 +2701,7 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
|
|||||||
VkPresentInfoKHR presentInfo = {};
|
VkPresentInfoKHR presentInfo = {};
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
presentInfo.swapchainCount = 1;
|
presentInfo.swapchainCount = 1;
|
||||||
presentInfo.pSwapchains = &chainInfo.swapchain;
|
presentInfo.pSwapchains = &chainInfo.m_swapchain;
|
||||||
presentInfo.pImageIndices = &chainInfo.swapchainImageIndex;
|
presentInfo.pImageIndices = &chainInfo.swapchainImageIndex;
|
||||||
// wait on command buffer semaphore
|
// wait on command buffer semaphore
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
|
@ -127,7 +127,6 @@ class VulkanRenderer : public Renderer
|
|||||||
friend class PipelineCompiler;
|
friend class PipelineCompiler;
|
||||||
|
|
||||||
using VSync = SwapchainInfoVk::VSync;
|
using VSync = SwapchainInfoVk::VSync;
|
||||||
using QueueFamilyIndices = SwapchainInfoVk::QueueFamilyIndices;
|
|
||||||
|
|
||||||
static const inline int UNIFORMVAR_RINGBUFFER_SIZE = 1024 * 1024 * 16; // 16MB
|
static const inline int UNIFORMVAR_RINGBUFFER_SIZE = 1024 * 1024 * 16; // 16MB
|
||||||
|
|
||||||
@ -421,6 +420,18 @@ private:
|
|||||||
|
|
||||||
VkDescriptorPool m_descriptorPool;
|
VkDescriptorPool m_descriptorPool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct QueueFamilyIndices
|
||||||
|
{
|
||||||
|
int32_t graphicsFamily = -1;
|
||||||
|
int32_t presentFamily = -1;
|
||||||
|
|
||||||
|
bool IsComplete() const { return graphicsFamily >= 0 && presentFamily >= 0; }
|
||||||
|
};
|
||||||
|
static QueueFamilyIndices FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
struct FeatureControl
|
struct FeatureControl
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
Loading…
Reference in New Issue
Block a user