Commit 00861a81 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

VulkanSwapChain: Use VK_KHR_incremental_present for better performance.

Bug: 1059598
Change-Id: I4ec9ae96b97606d4e64d6ce8874471b00586def8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2094235Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748280}
parent 39d7f83a
......@@ -121,13 +121,11 @@ void SkiaOutputDeviceVulkan::PostSubBuffer(
image_modified_ = false;
#endif
// TODO(penghuang): pass rect to vulkan swap chain and let swap chain use
// VK_KHR_incremental_present
StartSwapBuffers(std::move(feedback));
auto image_size = vulkan_surface_->image_size();
gfx::SwapResult result = gfx::SwapResult::SWAP_ACK;
if (!rect.IsEmpty())
result = vulkan_surface_->SwapBuffers();
result = vulkan_surface_->PostSubBuffer(rect);
FinishSwapBuffers(result, image_size, std::move(latency_info));
}
......
......@@ -128,15 +128,18 @@ std::vector<const char*>
VulkanImplementationAndroid::GetOptionalDeviceExtensions() {
// VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME also requires
// VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME as per spec.
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME};
return {
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
};
}
VkFence VulkanImplementationAndroid::CreateVkFenceForGpuFence(
......
......@@ -178,7 +178,11 @@ void VulkanSurface::Destroy() {
}
gfx::SwapResult VulkanSurface::SwapBuffers() {
return swap_chain_->PresentBuffer();
return PostSubBuffer(gfx::Rect(image_size_));
}
gfx::SwapResult VulkanSurface::PostSubBuffer(const gfx::Rect& rect) {
return swap_chain_->PresentBuffer(rect);
}
void VulkanSurface::Finish() {
......
......@@ -43,6 +43,7 @@ class VULKAN_EXPORT VulkanSurface {
void Destroy();
gfx::SwapResult SwapBuffers();
gfx::SwapResult PostSubBuffer(const gfx::Rect& rect);
void Finish();
......
......@@ -49,6 +49,9 @@ bool VulkanSwapChain::Initialize(
DCHECK(!use_protected_memory || device_queue->allow_protected_memory());
use_protected_memory_ = use_protected_memory;
device_queue_ = device_queue;
is_incremental_present_supported_ =
gfx::HasExtension(device_queue_->enabled_extensions(),
VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
device_queue_->GetFenceHelper()->ProcessCleanupTasks();
return InitializeSwapChain(surface, surface_format, image_size,
min_image_count, pre_transform,
......@@ -62,7 +65,7 @@ void VulkanSwapChain::Destroy() {
DestroySwapChain();
}
gfx::SwapResult VulkanSwapChain::PresentBuffer() {
gfx::SwapResult VulkanSwapChain::PresentBuffer(const gfx::Rect& rect) {
DCHECK(acquired_image_);
DCHECK(end_write_semaphore_ != VK_NULL_HANDLE);
......@@ -96,15 +99,31 @@ gfx::SwapResult VulkanSwapChain::PresentBuffer() {
end_write_semaphore_ = vk_semaphore;
}
// Queue the present.
VkPresentInfoKHR present_info = {};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &end_write_semaphore_;
present_info.swapchainCount = 1;
present_info.pSwapchains = &swap_chain_;
present_info.pImageIndices = &acquired_image_.value();
VkRectLayerKHR rect_layer;
VkPresentRegionKHR present_region;
VkPresentRegionsKHR present_regions;
if (is_incremental_present_supported_) {
rect_layer.offset = {rect.x(), rect.y()};
rect_layer.extent = {rect.width(), rect.height()};
rect_layer.layer = 0;
present_region.rectangleCount = 1;
present_region.pRectangles = &rect_layer;
present_regions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
present_regions.swapchainCount = 1;
present_regions.pRegions = &present_region;
present_info.pNext = &present_regions;
}
result = vkQueuePresentKHR(queue, &present_info);
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
DLOG(ERROR) << "vkQueuePresentKHR() failed: " << result;
......
......@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/optional.h"
#include "gpu/vulkan/vulkan_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/swap_result.h"
......@@ -73,7 +74,7 @@ class VULKAN_EXPORT VulkanSwapChain {
void Destroy();
// Present the current buffer.
gfx::SwapResult PresentBuffer();
gfx::SwapResult PresentBuffer(const gfx::Rect& rect);
uint32_t num_images() const { return static_cast<uint32_t>(images_.size()); }
const gfx::Size& size() const { return size_; }
......@@ -100,7 +101,8 @@ class VULKAN_EXPORT VulkanSwapChain {
bool AcquireNextImage();
bool use_protected_memory_ = false;
VulkanDeviceQueue* device_queue_;
VulkanDeviceQueue* device_queue_ = nullptr;
bool is_incremental_present_supported_ = false;
VkSwapchainKHR swap_chain_ = VK_NULL_HANDLE;
std::unique_ptr<VulkanCommandPool> command_pool_;
......
......@@ -131,7 +131,7 @@ VulkanImplementationX11::GetRequiredDeviceExtensions() {
std::vector<const char*>
VulkanImplementationX11::GetOptionalDeviceExtensions() {
return {};
return {VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME};
}
VkFence VulkanImplementationX11::CreateVkFenceForGpuFence(VkDevice vk_device) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment