[Vulkan v2] Surface queries
This commit is contained in:
parent
db2898e386
commit
675034670e
|
@ -9,7 +9,10 @@
|
||||||
|
|
||||||
#include "xenia/ui/vk/vulkan_context.h"
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
||||||
#include "xenia/ui/vk/vulkan_util.h"
|
#include "xenia/ui/vk/vulkan_util.h"
|
||||||
|
@ -27,6 +30,7 @@ VulkanContext::~VulkanContext() { Shutdown(); }
|
||||||
bool VulkanContext::Initialize() {
|
bool VulkanContext::Initialize() {
|
||||||
auto provider = GetVulkanProvider();
|
auto provider = GetVulkanProvider();
|
||||||
auto instance = provider->GetInstance();
|
auto instance = provider->GetInstance();
|
||||||
|
auto physical_device = provider->GetPhysicalDevice();
|
||||||
auto device = provider->GetDevice();
|
auto device = provider->GetDevice();
|
||||||
|
|
||||||
context_lost_ = false;
|
context_lost_ = false;
|
||||||
|
@ -94,7 +98,7 @@ bool VulkanContext::Initialize() {
|
||||||
// FIXME(Triang3l): Separate present queue not supported - would require
|
// FIXME(Triang3l): Separate present queue not supported - would require
|
||||||
// deferring VkDevice creation because vkCreateDevice needs all used queues.
|
// deferring VkDevice creation because vkCreateDevice needs all used queues.
|
||||||
VkBool32 surface_supported = VK_FALSE;
|
VkBool32 surface_supported = VK_FALSE;
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(provider->GetPhysicalDevice(),
|
vkGetPhysicalDeviceSurfaceSupportKHR(physical_device,
|
||||||
provider->GetGraphicsQueueFamily(),
|
provider->GetGraphicsQueueFamily(),
|
||||||
surface_, &surface_supported);
|
surface_, &surface_supported);
|
||||||
if (!surface_supported) {
|
if (!surface_supported) {
|
||||||
|
@ -105,6 +109,89 @@ bool VulkanContext::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Choose the number of swapchain images and the alpha compositing mode.
|
||||||
|
VkSurfaceCapabilitiesKHR surface_capabilities;
|
||||||
|
if (vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||||
|
physical_device, surface_, &surface_capabilities) != VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to get Vulkan surface capabilities");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
surface_min_image_count_ =
|
||||||
|
std::max(uint32_t(3), surface_capabilities.minImageCount);
|
||||||
|
if (surface_capabilities.maxImageCount) {
|
||||||
|
surface_min_image_count_ = std::min(surface_min_image_count_,
|
||||||
|
surface_capabilities.maxImageCount);
|
||||||
|
}
|
||||||
|
if (surface_capabilities.supportedCompositeAlpha &
|
||||||
|
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
|
||||||
|
surface_composite_alpha_ = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
} else if (surface_capabilities.supportedCompositeAlpha &
|
||||||
|
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
|
||||||
|
surface_composite_alpha_ = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
|
||||||
|
} else {
|
||||||
|
surface_composite_alpha_ = VkCompositeAlphaFlagBitsKHR(
|
||||||
|
uint32_t(1) << xe::tzcnt(
|
||||||
|
surface_capabilities.supportedCompositeAlpha));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the preferred surface format.
|
||||||
|
uint32_t surface_format_count;
|
||||||
|
if (vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface_,
|
||||||
|
&surface_format_count,
|
||||||
|
nullptr) != VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to get Vulkan surface format count");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::vector<VkSurfaceFormatKHR> surface_formats;
|
||||||
|
surface_formats.resize(surface_format_count);
|
||||||
|
if (vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||||
|
physical_device, surface_, &surface_format_count,
|
||||||
|
surface_formats.data()) != VK_SUCCESS ||
|
||||||
|
!surface_format_count) {
|
||||||
|
XELOGE("Failed to get Vulkan surface formats");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Prefer RGB8.
|
||||||
|
for (uint32_t i = 0; i < surface_format_count; ++i) {
|
||||||
|
surface_format_ = surface_formats[i];
|
||||||
|
if (surface_format_.format == VK_FORMAT_UNDEFINED) {
|
||||||
|
surface_format_.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (surface_format_.format == VK_FORMAT_R8G8B8A8_UNORM ||
|
||||||
|
surface_format_.format == VK_FORMAT_B8G8R8A8_UNORM) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer non-vsyncing presentation modes (better without tearing), or fall
|
||||||
|
// back to FIFO.
|
||||||
|
surface_present_mode_ = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
uint32_t present_mode_count;
|
||||||
|
if (vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface_,
|
||||||
|
&present_mode_count,
|
||||||
|
nullptr) == VK_SUCCESS) {
|
||||||
|
std::vector<VkPresentModeKHR> present_modes;
|
||||||
|
present_modes.resize(present_mode_count);
|
||||||
|
if (vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||||||
|
physical_device, surface_, &present_mode_count,
|
||||||
|
present_modes.data()) == VK_SUCCESS) {
|
||||||
|
for (uint32_t i = 0; i < present_mode_count; ++i) {
|
||||||
|
VkPresentModeKHR present_mode = present_modes[i];
|
||||||
|
if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR ||
|
||||||
|
present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
|
||||||
|
surface_present_mode_ = present_mode;
|
||||||
|
if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the immediate mode drawer if not offscreen.
|
// Initialize the immediate mode drawer if not offscreen.
|
||||||
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
||||||
if (!immediate_drawer_->Initialize()) {
|
if (!immediate_drawer_->Initialize()) {
|
||||||
|
|
|
@ -72,6 +72,12 @@ class VulkanContext : public GraphicsContext {
|
||||||
VkFence fences_[kQueuedFrames] = {};
|
VkFence fences_[kQueuedFrames] = {};
|
||||||
|
|
||||||
VkSurfaceKHR surface_ = VK_NULL_HANDLE;
|
VkSurfaceKHR surface_ = VK_NULL_HANDLE;
|
||||||
|
uint32_t surface_min_image_count_ = 3;
|
||||||
|
VkSurfaceFormatKHR surface_format_ = {VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||||
|
VkPresentModeKHR surface_present_mode_ = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
VkCompositeAlphaFlagBitsKHR surface_composite_alpha_ =
|
||||||
|
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
|
||||||
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_ = nullptr;
|
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -108,20 +108,19 @@ bool VulkanProvider::Initialize() {
|
||||||
|
|
||||||
// Get a supported physical device.
|
// Get a supported physical device.
|
||||||
physical_device_ = nullptr;
|
physical_device_ = nullptr;
|
||||||
std::vector<VkPhysicalDevice> physical_devices;
|
|
||||||
uint32_t physical_device_count;
|
uint32_t physical_device_count;
|
||||||
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count, nullptr) !=
|
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count, nullptr) !=
|
||||||
VK_SUCCESS) {
|
VK_SUCCESS) {
|
||||||
XELOGE("Failed to get Vulkan physical device count");
|
XELOGE("Failed to get Vulkan physical device count");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
std::vector<VkPhysicalDevice> physical_devices;
|
||||||
physical_devices.resize(physical_device_count);
|
physical_devices.resize(physical_device_count);
|
||||||
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count,
|
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count,
|
||||||
physical_devices.data()) != VK_SUCCESS) {
|
physical_devices.data()) != VK_SUCCESS) {
|
||||||
XELOGE("Failed to get Vulkan physical devices");
|
XELOGE("Failed to get Vulkan physical devices");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
physical_devices.resize(physical_device_count);
|
|
||||||
uint32_t physical_device_index, physical_device_index_end;
|
uint32_t physical_device_index, physical_device_index_end;
|
||||||
if (cvars::vk_device >= 0) {
|
if (cvars::vk_device >= 0) {
|
||||||
physical_device_index = uint32_t(cvars::vk_device);
|
physical_device_index = uint32_t(cvars::vk_device);
|
||||||
|
|
Loading…
Reference in New Issue