[Vulkan] Refactoring and fixes for VulkanProvider and related areas

Enable portability subset physical device enumeration.

Don't use Vulkan 1.1+ logical devices on Vulkan 1.0 instances due to the
VkApplicationInfo::apiVersion specification.

Make sure all extension dependencies are enabled when creating a device.

Prefer exposing feature support over extension support via the device
interface to avoid causing confusion with regard to promoted extensions
(especially those that required some features as extensions, but had those
features made optional when they were promoted).

Allow creating presentation-only devices, not demanding any optional
features beyond the basic Vulkan 1.0, for use cases such as internal tools
or CPU rendering.

Require the independentBlend feature for GPU emulation as working around is
complicated, while support is almost ubiquitous.

Move the graphics system initialization fatal error message to xenia_main
after attempting to initialize all implementations, for automatic fallback
to other implementations in the future.

Log Vulkan driver info.

Improve Vulkan debug message logging, enabled by default.

Refactor code, with simplified logic for enabling extensions and layers.
This commit is contained in:
Triang3l
2025-08-12 23:21:59 +03:00
parent a06be03f1b
commit b5432ab83f
70 changed files with 3238 additions and 2757 deletions

View File

@@ -73,8 +73,8 @@ namespace shaders {
} // namespace shaders
VulkanPresenter::PaintContext::Submission::~Submission() {
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
if (draw_command_pool_ != VK_NULL_HANDLE) {
dfn.vkDestroyCommandPool(device, draw_command_pool_, nullptr);
@@ -89,8 +89,8 @@ VulkanPresenter::PaintContext::Submission::~Submission() {
}
bool VulkanPresenter::PaintContext::Submission::Initialize() {
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkSemaphoreCreateInfo semaphore_create_info;
semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@@ -116,7 +116,7 @@ bool VulkanPresenter::PaintContext::Submission::Initialize() {
command_pool_create_info.pNext = nullptr;
command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
command_pool_create_info.queueFamilyIndex =
provider_.queue_family_graphics_compute();
vulkan_device_->queue_family_graphics_compute();
if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr,
&draw_command_pool_) != VK_SUCCESS) {
XELOGE(
@@ -161,8 +161,8 @@ VulkanPresenter::~VulkanPresenter() {
ui_submission_tracker_.Shutdown();
guest_output_image_refresher_submission_tracker_.Shutdown();
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
if (paint_context_.swapchain_render_pass != VK_NULL_HANDLE) {
dfn.vkDestroyRenderPass(device, paint_context_.swapchain_render_pass,
@@ -207,11 +207,36 @@ VulkanPresenter::~VulkanPresenter() {
guest_output_paint_image_descriptor_set_layout_);
}
Surface::TypeFlags VulkanPresenter::GetSupportedSurfaceTypes() const {
if (!provider_.device_info().ext_VK_KHR_swapchain) {
Surface::TypeFlags VulkanPresenter::GetSurfaceTypesSupportedByInstance(
const VulkanInstance::Extensions& instance_extensions) {
if (!instance_extensions.ext_KHR_surface) {
return 0;
}
return GetSurfaceTypesSupportedByInstance(provider_.instance_extensions());
Surface::TypeFlags type_flags = 0;
#if XE_PLATFORM_ANDROID
if (instance_extensions.ext_KHR_android_surface) {
type_flags |= Surface::kTypeFlag_AndroidNativeWindow;
}
#endif
#if XE_PLATFORM_GNU_LINUX
if (instance_extensions.ext_KHR_xcb_surface) {
type_flags |= Surface::kTypeFlag_XcbWindow;
}
#endif
#if XE_PLATFORM_WIN32
if (instance_extensions.ext_KHR_win32_surface) {
type_flags |= Surface::kTypeFlag_Win32Hwnd;
}
#endif
return type_flags;
}
Surface::TypeFlags VulkanPresenter::GetSupportedSurfaceTypes() const {
if (!vulkan_device_->extensions().ext_KHR_swapchain) {
return 0;
}
return GetSurfaceTypesSupportedByInstance(
vulkan_device_->vulkan_instance()->extensions());
}
bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) {
@@ -239,14 +264,14 @@ bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) {
VkBuffer buffer;
VkDeviceMemory buffer_memory;
if (!util::CreateDedicatedAllocationBuffer(
provider_, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
vulkan_device_, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
util::MemoryPurpose::kReadback, buffer, buffer_memory)) {
XELOGE("VulkanPresenter: Failed to create the guest output capture buffer");
return false;
}
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
{
VkCommandPoolCreateInfo command_pool_create_info;
@@ -254,7 +279,7 @@ bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) {
command_pool_create_info.pNext = nullptr;
command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
command_pool_create_info.queueFamilyIndex =
provider_.queue_family_graphics_compute();
vulkan_device_->queue_family_graphics_compute();
VkCommandPool command_pool;
if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr,
&command_pool) != VK_SUCCESS) {
@@ -361,7 +386,7 @@ bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) {
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &command_buffer;
VulkanSubmissionTracker submission_tracker(provider_);
VulkanSubmissionTracker submission_tracker(vulkan_device_);
{
VulkanSubmissionTracker::FenceAcquisition fence_acqusition(
submission_tracker.AcquireFenceToAdvanceSubmission());
@@ -377,11 +402,12 @@ bool VulkanPresenter::CaptureGuestOutput(RawImage& image_out) {
}
VkResult submit_result;
{
VulkanProvider::QueueAcquisition queue_acquisition(
provider_.AcquireQueue(provider_.queue_family_graphics_compute(),
0));
submit_result = dfn.vkQueueSubmit(
queue_acquisition.queue, 1, &submit_info, fence_acqusition.fence());
const VulkanDevice::Queue::Acquisition queue_acquisition =
vulkan_device_->AcquireQueue(
vulkan_device_->queue_family_graphics_compute(), 0);
submit_result =
dfn.vkQueueSubmit(queue_acquisition.queue(), 1, &submit_info,
fence_acqusition.fence());
}
if (submit_result != VK_SUCCESS) {
XELOGE(
@@ -442,8 +468,8 @@ VkCommandBuffer VulkanPresenter::AcquireUISetupCommandBufferFromUIThread() {
.command_buffer;
}
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkCommandBufferBeginInfo command_buffer_begin_info;
command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@@ -488,7 +514,7 @@ VkCommandBuffer VulkanPresenter::AcquireUISetupCommandBufferFromUIThread() {
command_pool_create_info.pNext = nullptr;
command_pool_create_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
command_pool_create_info.queueFamilyIndex =
provider_.queue_family_graphics_compute();
vulkan_device_->queue_family_graphics_compute();
VkCommandPool new_command_pool;
if (dfn.vkCreateCommandPool(device, &command_pool_create_info, nullptr,
&new_command_pool) != VK_SUCCESS) {
@@ -529,11 +555,12 @@ VulkanPresenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(
Surface& new_surface, uint32_t new_surface_width,
uint32_t new_surface_height, bool was_paintable,
bool& is_vsync_implicit_out) {
const VulkanProvider::InstanceFunctions& ifn = provider_.ifn();
VkInstance instance = provider_.instance();
VkPhysicalDevice physical_device = provider_.physical_device();
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanInstance* const vulkan_instance =
vulkan_device_->vulkan_instance();
const VulkanInstance::Functions& ifn = vulkan_instance->functions();
const VkInstance instance = vulkan_instance->instance();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkFormat new_swapchain_format;
@@ -550,7 +577,7 @@ VulkanPresenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(
paint_context_.PrepareForSwapchainRetirement();
bool surface_unusable;
paint_context_.swapchain = PaintContext::CreateSwapchainForVulkanSurface(
provider_, paint_context_.vulkan_surface, new_surface_width,
vulkan_device_, paint_context_.vulkan_surface, new_surface_width,
new_surface_height, old_swapchain, paint_context_.present_queue_family,
new_swapchain_format, paint_context_.swapchain_extent,
paint_context_.swapchain_is_fifo, surface_unusable);
@@ -641,7 +668,7 @@ VulkanPresenter::ConnectOrReconnectPaintingToSurfaceFromUIThread(
}
bool surface_unusable;
paint_context_.swapchain = PaintContext::CreateSwapchainForVulkanSurface(
provider_, paint_context_.vulkan_surface, new_surface_width,
vulkan_device_, paint_context_.vulkan_surface, new_surface_width,
new_surface_height, VK_NULL_HANDLE, paint_context_.present_queue_family,
new_swapchain_format, paint_context_.swapchain_extent,
paint_context_.swapchain_is_fifo, surface_unusable);
@@ -837,7 +864,7 @@ bool VulkanPresenter::RefreshGuestOutputImpl(
assert_not_zero(frontbuffer_width);
assert_not_zero(frontbuffer_height);
VkExtent2D max_framebuffer_extent =
util::GetMax2DFramebufferExtent(provider_);
util::GetMax2DFramebufferExtent(vulkan_device_->properties());
if (frontbuffer_width > max_framebuffer_extent.width ||
frontbuffer_height > max_framebuffer_extent.height) {
// Writing the guest output isn't supposed to rescale, and a guest texture
@@ -856,7 +883,7 @@ bool VulkanPresenter::RefreshGuestOutputImpl(
}
if (!image_instance.image) {
std::unique_ptr<GuestOutputImage> new_image = GuestOutputImage::Create(
provider_, frontbuffer_width, frontbuffer_height);
vulkan_device_, frontbuffer_width, frontbuffer_height);
if (!new_image) {
return false;
}
@@ -883,14 +910,15 @@ bool VulkanPresenter::RefreshGuestOutputImpl(
// "Fence signal operations that are defined by vkQueueSubmit additionally
// include in the first synchronization scope all commands that occur earlier
// in submission order."
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
{
VulkanSubmissionTracker::FenceAcquisition fence_acqusition(
guest_output_image_refresher_submission_tracker_
.AcquireFenceToAdvanceSubmission());
VulkanProvider::QueueAcquisition queue_acquisition(
provider_.AcquireQueue(provider_.queue_family_graphics_compute(), 0));
if (dfn.vkQueueSubmit(queue_acquisition.queue, 0, nullptr,
const VulkanDevice::Queue::Acquisition queue_acquisition =
vulkan_device_->AcquireQueue(
vulkan_device_->queue_family_graphics_compute(), 0);
if (dfn.vkQueueSubmit(queue_acquisition.queue(), 0, nullptr,
fence_acqusition.fence()) != VK_SUCCESS) {
fence_acqusition.SubmissionSucceededSignalFailed();
}
@@ -900,18 +928,18 @@ bool VulkanPresenter::RefreshGuestOutputImpl(
}
VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
const VulkanProvider& provider, VkSurfaceKHR surface, uint32_t width,
const VulkanDevice* vulkan_device, VkSurfaceKHR surface, uint32_t width,
uint32_t height, VkSwapchainKHR old_swapchain,
uint32_t& present_queue_family_out, VkFormat& image_format_out,
VkExtent2D& image_extent_out, bool& is_fifo_out,
bool& ui_surface_unusable_out) {
ui_surface_unusable_out = false;
const VulkanProvider::InstanceFunctions& ifn = provider.ifn();
VkInstance instance = provider.instance();
VkPhysicalDevice physical_device = provider.physical_device();
const VulkanProvider::DeviceFunctions& dfn = provider.dfn();
VkDevice device = provider.device();
const VulkanInstance::Functions& ifn =
vulkan_device->vulkan_instance()->functions();
const VkPhysicalDevice physical_device = vulkan_device->physical_device();
const VulkanDevice::Functions& dfn = vulkan_device->functions();
const VkDevice device = vulkan_device->device();
// Get surface capabilities.
VkSurfaceCapabilitiesKHR surface_capabilities;
@@ -934,7 +962,8 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
// requirements - the maximum 2D framebuffer size on the specific physical
// device, and the minimum swap chain size on the whole instance - fail to
// create until the surface becomes smaller).
VkExtent2D max_framebuffer_extent = util::GetMax2DFramebufferExtent(provider);
VkExtent2D max_framebuffer_extent =
util::GetMax2DFramebufferExtent(vulkan_device->properties());
VkExtent2D image_extent;
image_extent.width =
std::min(std::max(std::min(width, max_framebuffer_extent.width),
@@ -952,17 +981,17 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
// Get the queue family for presentation.
uint32_t queue_family_index_present = UINT32_MAX;
const std::vector<VulkanProvider::QueueFamily>& queue_families =
provider.queue_families();
const std::vector<VulkanDevice::QueueFamily>& queue_families =
vulkan_device->queue_families();
VkBool32 queue_family_present_supported;
// First try the graphics and compute queue, prefer it to avoid the concurrent
// image sharing mode.
uint32_t queue_family_index_graphics_compute =
provider.queue_family_graphics_compute();
const VulkanProvider::QueueFamily& queue_family_graphics_compute =
vulkan_device->queue_family_graphics_compute();
const VulkanDevice::QueueFamily& queue_family_graphics_compute =
queue_families[queue_family_index_graphics_compute];
if (queue_family_graphics_compute.potentially_supports_present &&
queue_family_graphics_compute.queue_count &&
if (queue_family_graphics_compute.may_support_presentation &&
!queue_family_graphics_compute.queues.empty() &&
ifn.vkGetPhysicalDeviceSurfaceSupportKHR(
physical_device, queue_family_index_graphics_compute, surface,
&queue_family_present_supported) == VK_SUCCESS &&
@@ -970,9 +999,9 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
queue_family_index_present = queue_family_index_graphics_compute;
} else {
for (uint32_t i = 0; i < uint32_t(queue_families.size()); ++i) {
const VulkanProvider::QueueFamily& queue_family = queue_families[i];
if (queue_family.potentially_supports_present &&
queue_family.queue_count &&
const VulkanDevice::QueueFamily& queue_family = queue_families[i];
if (!queue_family.queues.empty() &&
queue_family.may_support_presentation &&
ifn.vkGetPhysicalDeviceSurfaceSupportKHR(
physical_device, i, surface, &queue_family_present_supported) ==
VK_SUCCESS &&
@@ -1228,7 +1257,7 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
XELOGE("VulkanPresenter: Failed to create a swapchain");
return VK_NULL_HANDLE;
}
XELOGVK(
XELOGI(
"VulkanPresenter: Created {}x{} swapchain with format {}, color space "
"{}, presentation mode {}",
swapchain_create_info.imageExtent.width,
@@ -1250,8 +1279,8 @@ VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() {
if (swapchain != VK_NULL_HANDLE) {
submission_tracker.AwaitAllSubmissionsCompletion();
}
const VulkanProvider::DeviceFunctions& dfn = provider.dfn();
VkDevice device = provider.device();
const VulkanDevice::Functions& dfn = vulkan_device->functions();
const VkDevice device = vulkan_device->device();
for (const SwapchainFramebuffer& framebuffer : swapchain_framebuffers) {
dfn.vkDestroyFramebuffer(device, framebuffer.framebuffer, nullptr);
dfn.vkDestroyImageView(device, framebuffer.image_view, nullptr);
@@ -1269,22 +1298,21 @@ VkSwapchainKHR VulkanPresenter::PaintContext::PrepareForSwapchainRetirement() {
void VulkanPresenter::PaintContext::DestroySwapchainAndVulkanSurface() {
VkSwapchainKHR old_swapchain = PrepareForSwapchainRetirement();
if (old_swapchain != VK_NULL_HANDLE) {
const VulkanProvider::DeviceFunctions& dfn = provider.dfn();
VkDevice device = provider.device();
dfn.vkDestroySwapchainKHR(device, old_swapchain, nullptr);
vulkan_device->functions().vkDestroySwapchainKHR(vulkan_device->device(),
old_swapchain, nullptr);
}
present_queue_family = UINT32_MAX;
if (vulkan_surface != VK_NULL_HANDLE) {
const VulkanProvider::InstanceFunctions& ifn = provider.ifn();
VkInstance instance = provider.instance();
ifn.vkDestroySurfaceKHR(instance, vulkan_surface, nullptr);
const VulkanInstance* vulkan_instance = vulkan_device->vulkan_instance();
vulkan_instance->functions().vkDestroySurfaceKHR(
vulkan_instance->instance(), vulkan_surface, nullptr);
vulkan_surface = VK_NULL_HANDLE;
}
}
VulkanPresenter::GuestOutputImage::~GuestOutputImage() {
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
if (view_ != VK_NULL_HANDLE) {
dfn.vkDestroyImageView(device, view_, nullptr);
}
@@ -1318,14 +1346,14 @@ bool VulkanPresenter::GuestOutputImage::Initialize() {
image_create_info.pQueueFamilyIndices = nullptr;
image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
if (!ui::vulkan::util::CreateDedicatedAllocationImage(
provider_, image_create_info,
vulkan_device_, image_create_info,
ui::vulkan::util::MemoryPurpose::kDeviceLocal, image_, memory_)) {
XELOGE("VulkanPresenter: Failed to create a guest output image");
return false;
}
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkImageViewCreateInfo image_view_create_info;
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@@ -1368,8 +1396,8 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
*paint_context_.submissions[current_paint_submission_index %
paint_submission_count];
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkCommandPool draw_command_pool = paint_submission.draw_command_pool();
if (dfn.vkResetCommandPool(device, draw_command_pool, 0) != VK_SUCCESS) {
@@ -1414,7 +1442,7 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
// Not an error, reporting just as info (may normally occur while resizing
// on some platforms).
XELOGVK(
XELOGI(
"VulkanPresenter: Presentation to the swapchain image has been "
"dropped as the swapchain or the surface has become outdated");
return PaintResult::kNotPresentedConnectionOutdated;
@@ -1482,7 +1510,7 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
if (guest_output_image) {
VkExtent2D max_framebuffer_extent =
util::GetMax2DFramebufferExtent(provider_);
util::GetMax2DFramebufferExtent(vulkan_device_->properties());
GuestOutputPaintFlow guest_output_flow = GetGuestOutputPaintFlow(
guest_output_properties, paint_context_.swapchain_extent.width,
paint_context_.swapchain_extent.height, max_framebuffer_extent.width,
@@ -1599,7 +1627,7 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
}
// Image.
intermediate_image_ptr_ref = GuestOutputImage::Create(
provider_, intermediate_needed_size.first,
vulkan_device_, intermediate_needed_size.first,
intermediate_needed_size.second);
if (!intermediate_image_ptr_ref) {
// Don't display the guest output, and don't try to create more
@@ -2029,13 +2057,14 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
}
VkResult submit_result;
{
VulkanProvider::QueueAcquisition queue_acquisition(
provider_.AcquireQueue(provider_.queue_family_graphics_compute(), 0));
submit_result = dfn.vkQueueSubmit(queue_acquisition.queue, 1,
const VulkanDevice::Queue::Acquisition queue_acquisition =
vulkan_device_->AcquireQueue(
vulkan_device_->queue_family_graphics_compute(), 0);
submit_result = dfn.vkQueueSubmit(queue_acquisition.queue(), 1,
&submit_info, fence_acqusition.fence());
if (ui_fence_acquisition.fence() != VK_NULL_HANDLE &&
submit_result == VK_SUCCESS) {
if (dfn.vkQueueSubmit(queue_acquisition.queue, 0, nullptr,
if (dfn.vkQueueSubmit(queue_acquisition.queue(), 0, nullptr,
ui_fence_acquisition.fence()) != VK_SUCCESS) {
ui_fence_acquisition.SubmissionSucceededSignalFailed();
}
@@ -2072,10 +2101,10 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
present_info.pResults = nullptr;
VkResult present_result;
{
VulkanProvider::QueueAcquisition queue_acquisition(
provider_.AcquireQueue(paint_context_.present_queue_family, 0));
const VulkanDevice::Queue::Acquisition queue_acquisition =
vulkan_device_->AcquireQueue(paint_context_.present_queue_family, 0);
present_result =
dfn.vkQueuePresentKHR(queue_acquisition.queue, &present_info);
dfn.vkQueuePresentKHR(queue_acquisition.queue(), &present_info);
}
switch (present_result) {
case VK_SUCCESS:
@@ -2092,7 +2121,7 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
// Not an error, reporting just as info (may normally occur while resizing
// on some platforms).
XELOGVK(
XELOGI(
"VulkanPresenter: Presentation to the swapchain image has been "
"dropped as the swapchain or the surface has become outdated");
// Note that the semaphore wait (followed by reset) has been enqueued,
@@ -2108,8 +2137,8 @@ Presenter::PaintResult VulkanPresenter::PaintAndPresentImpl(
}
bool VulkanPresenter::InitializeSurfaceIndependent() {
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkDescriptorSetLayoutBinding guest_output_image_sampler_bindings[2];
guest_output_image_sampler_bindings[0].binding = 0;
@@ -2119,8 +2148,8 @@ bool VulkanPresenter::InitializeSurfaceIndependent() {
guest_output_image_sampler_bindings[0].stageFlags =
VK_SHADER_STAGE_FRAGMENT_BIT;
guest_output_image_sampler_bindings[0].pImmutableSamplers = nullptr;
VkSampler sampler_linear_clamp =
provider_.GetHostSampler(VulkanProvider::HostSampler::kLinearClamp);
const VkSampler sampler_linear_clamp =
ui_samplers_->samplers()[UISamplers::kSamplerIndexLinearClampToEdge];
guest_output_image_sampler_bindings[1].binding = 1;
guest_output_image_sampler_bindings[1].descriptorType =
VK_DESCRIPTOR_TYPE_SAMPLER;
@@ -2371,7 +2400,8 @@ bool VulkanPresenter::InitializeSurfaceIndependent() {
// Initialize connection-independent parts of the painting context.
for (size_t i = 0; i < paint_context_.submissions.size(); ++i) {
paint_context_.submissions[i] = PaintContext::Submission::Create(provider_);
paint_context_.submissions[i] =
PaintContext::Submission::Create(vulkan_device_);
if (!paint_context_.submissions[i]) {
return false;
}
@@ -2536,8 +2566,8 @@ VkPipeline VulkanPresenter::CreateGuestOutputPaintPipeline(
pipeline_create_info.basePipelineHandle = VK_NULL_HANDLE;
pipeline_create_info.basePipelineIndex = -1;
const VulkanProvider::DeviceFunctions& dfn = provider_.dfn();
VkDevice device = provider_.device();
const VulkanDevice::Functions& dfn = vulkan_device_->functions();
const VkDevice device = vulkan_device_->device();
VkPipeline pipeline;
if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1,