Commit 7b9bcca1 authored by Michael Spang's avatar Michael Spang Committed by Commit Bot

ozone: drm: Implement VkFence export to sync_file

Implement sync_file export for fences so we can submit fences with planes
to DRM atomic.

This does not work unless you have a fairly recent kernel (requires
syncobj support, I915_EXEC_FENCE_ARRAY).

Bug: 851997
Test: ozone_demo on eve with USE=vulkan and kernel 4.14

Change-Id: I5859b64690e9b45ccb95698a9ca096f0847ec51b
Reviewed-on: https://chromium-review.googlesource.com/1115570Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: Michael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572262}
parent 1998932e
......@@ -12,6 +12,10 @@
#include "gpu/vulkan/vulkan_export.h"
#include "ui/gfx/native_widget_types.h"
namespace gfx {
class GpuFence;
}
namespace gpu {
class VulkanDeviceQueue;
......@@ -39,6 +43,16 @@ class VULKAN_EXPORT VulkanImplementation {
virtual std::vector<const char*> GetRequiredDeviceExtensions() = 0;
// Creates a VkFence that is exportable to a gfx::GpuFence.
virtual VkFence CreateVkFenceForGpuFence(VkDevice vk_device) = 0;
// Exports a VkFence to a gfx::GpuFence.
//
// The fence should have been created via CreateVkFenceForGpuFence().
virtual std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(VulkanImplementation);
};
......
......@@ -80,4 +80,17 @@ VulkanImplementationAndroid::GetRequiredDeviceExtensions() {
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
}
VkFence VulkanImplementationAndroid::CreateVkFenceForGpuFence(
VkDevice vk_device) {
NOTREACHED();
return VK_NULL_HANDLE;
}
std::unique_ptr<gfx::GpuFence>
VulkanImplementationAndroid::ExportVkFenceToGpuFence(VkDevice vk_device,
VkFence vk_fence) {
NOTREACHED();
return nullptr;
}
} // namespace gpu
......@@ -29,6 +29,10 @@ class VULKAN_EXPORT VulkanImplementationAndroid : public VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
virtual std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) override;
private:
VulkanInstance vulkan_instance_;
......
......@@ -26,6 +26,7 @@ component("x") {
configs += [ "//build/config/linux:x11" ]
deps = [
"//ui/gfx",
"//ui/gfx/x",
]
......
......@@ -8,6 +8,7 @@
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/x/x11_types.h"
namespace gpu {
......@@ -96,4 +97,16 @@ VulkanImplementationX11::GetRequiredDeviceExtensions() {
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
}
VkFence VulkanImplementationX11::CreateVkFenceForGpuFence(VkDevice vk_device) {
NOTREACHED();
return VK_NULL_HANDLE;
}
std::unique_ptr<gfx::GpuFence> VulkanImplementationX11::ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) {
NOTREACHED();
return nullptr;
}
} // namespace gpu
......@@ -31,6 +31,10 @@ class COMPONENT_EXPORT(VULKAN_X11) VulkanImplementationX11
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) override;
private:
XDisplay* const x_display_;
......
......@@ -9,6 +9,7 @@
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "ui/gfx/gpu_fence.h"
namespace ui {
......@@ -26,12 +27,33 @@ bool VulkanImplementationGbm::InitializeVulkanInstance() {
if (!vulkan_function_pointers->vulkan_loader_library_)
return false;
std::vector<const char*> required_extensions;
std::vector<const char*> required_extensions = {
"VK_KHR_external_fence_capabilities",
"VK_KHR_get_physical_device_properties2",
};
if (!vulkan_instance_.Initialize(required_extensions)) {
vulkan_instance_.Destroy();
return false;
}
vkGetPhysicalDeviceExternalFencePropertiesKHR_ =
reinterpret_cast<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>(
vulkan_function_pointers->vkGetInstanceProcAddr(
vulkan_instance_.vk_instance(),
"vkGetPhysicalDeviceExternalFencePropertiesKHR"));
if (!vkGetPhysicalDeviceExternalFencePropertiesKHR_) {
vulkan_instance_.Destroy();
return false;
}
vkGetFenceFdKHR_ = reinterpret_cast<PFN_vkGetFenceFdKHR>(
vulkan_function_pointers->vkGetInstanceProcAddr(
vulkan_instance_.vk_instance(), "vkGetFenceFdKHR"));
if (!vkGetFenceFdKHR_) {
vulkan_instance_.Destroy();
return false;
}
return true;
}
......@@ -45,15 +67,69 @@ std::unique_ptr<gpu::VulkanSurface> VulkanImplementationGbm::CreateViewSurface(
}
bool VulkanImplementationGbm::GetPhysicalDevicePresentationSupport(
VkPhysicalDevice device,
VkPhysicalDevice physical_device,
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) {
VkPhysicalDeviceExternalFenceInfo external_fence_info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT};
VkExternalFenceProperties external_fence_properties;
vkGetPhysicalDeviceExternalFencePropertiesKHR_(
physical_device, &external_fence_info, &external_fence_properties);
if (!(external_fence_properties.externalFenceFeatures &
VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT)) {
return false;
}
return true;
}
std::vector<const char*>
VulkanImplementationGbm::GetRequiredDeviceExtensions() {
return std::vector<const char*>();
return {
"VK_KHR_external_fence", "VK_KHR_external_fence_fd",
};
}
VkFence VulkanImplementationGbm::CreateVkFenceForGpuFence(VkDevice vk_device) {
VkFenceCreateInfo fence_create_info = {};
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
VkExportFenceCreateInfo fence_export_create_info = {};
fence_create_info.pNext = &fence_export_create_info;
fence_export_create_info.sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO;
fence_export_create_info.handleTypes =
VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
VkFence fence;
VkResult result = gpu::GetVulkanFunctionPointers()->vkCreateFence(
vk_device, &fence_create_info, nullptr, &fence);
if (result != VK_SUCCESS) {
DLOG(ERROR) << "vkCreateFence failed: " << result;
return VK_NULL_HANDLE;
}
return fence;
}
std::unique_ptr<gfx::GpuFence> VulkanImplementationGbm::ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) {
VkFenceGetFdInfoKHR fence_get_fd_info = {};
fence_get_fd_info.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
fence_get_fd_info.fence = vk_fence;
fence_get_fd_info.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
int fence_fd = -1;
VkResult result = vkGetFenceFdKHR_(vk_device, &fence_get_fd_info, &fence_fd);
if (result != VK_SUCCESS) {
DLOG(ERROR) << "vkGetFenceFdKHR failed: " << result;
return nullptr;
}
gfx::GpuFenceHandle gpu_fence_handle;
gpu_fence_handle.type = gfx::GpuFenceHandleType::kAndroidNativeFenceSync;
gpu_fence_handle.native_fd =
base::FileDescriptor(fence_fd, true /* auto_close */);
return std::make_unique<gfx::GpuFence>(gpu_fence_handle);
}
} // namespace ui
......@@ -27,10 +27,18 @@ class VulkanImplementationGbm : public gpu::VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
virtual std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
VkFence vk_fence) override;
private:
gpu::VulkanInstance vulkan_instance_;
PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR
vkGetPhysicalDeviceExternalFencePropertiesKHR_ = nullptr;
PFN_vkGetFenceFdKHR vkGetFenceFdKHR_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(VulkanImplementationGbm);
};
......
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