Commit cd5d9e03 authored by Michael Spang's avatar Michael Spang Committed by Commit Bot

ozone: drm: Allow creating vulkan-renderable scanout buffers

Use vkCreateDmaBufImageINTEL until VK_EXT_image_drm_format_modifier is
available. We can't import buffers created with modifiers using this
method, so work around this for by adding a new flag to buffer creation.

Bug: 851997
Test: ozone_demo --enable-vulkan on vulkan-enabled eve

Change-Id: If91c678d7ee4ce52c610f55f9c7a2dbd561a4158
Reviewed-on: https://chromium-review.googlesource.com/1104866
Commit-Queue: Michael Spang <spang@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570233}
parent 9c97e58e
...@@ -119,6 +119,7 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget, ...@@ -119,6 +119,7 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size, const gfx::Size& size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
uint32_t client_flags,
scoped_refptr<GbmBuffer>* buffer) { scoped_refptr<GbmBuffer>* buffer) {
scoped_refptr<GbmDevice> gbm = scoped_refptr<GbmDevice> gbm =
static_cast<GbmDevice*>(device_manager_->GetDrmDevice(widget).get()); static_cast<GbmDevice*>(device_manager_->GetDrmDevice(widget).get());
...@@ -169,7 +170,8 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget, ...@@ -169,7 +170,8 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
// buffer in that case. // buffer in that case.
bool retry_without_scanout = usage != gfx::BufferUsage::SCANOUT; bool retry_without_scanout = usage != gfx::BufferUsage::SCANOUT;
do { do {
if (modifiers.size() > 0 && !(flags & GBM_BO_USE_LINEAR)) if (modifiers.size() > 0 && !(flags & GBM_BO_USE_LINEAR) &&
!(client_flags & GbmBuffer::kFlagNoModifiers))
*buffer = GbmBuffer::CreateBufferWithModifiers(gbm, fourcc_format, size, *buffer = GbmBuffer::CreateBufferWithModifiers(gbm, fourcc_format, size,
flags, modifiers); flags, modifiers);
else else
......
...@@ -70,6 +70,7 @@ class DrmThread : public base::Thread, ...@@ -70,6 +70,7 @@ class DrmThread : public base::Thread,
const gfx::Size& size, const gfx::Size& size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage, gfx::BufferUsage usage,
uint32_t flags,
scoped_refptr<GbmBuffer>* buffer); scoped_refptr<GbmBuffer>* buffer);
void CreateBufferFromFds(gfx::AcceleratedWidget widget, void CreateBufferFromFds(gfx::AcceleratedWidget widget,
const gfx::Size& size, const gfx::Size& size,
......
...@@ -36,7 +36,8 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer( ...@@ -36,7 +36,8 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer(
gfx::AcceleratedWidget widget, gfx::AcceleratedWidget widget,
const gfx::Size& size, const gfx::Size& size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage) { gfx::BufferUsage usage,
uint32_t flags) {
DCHECK(drm_thread_.task_runner()) DCHECK(drm_thread_.task_runner())
<< "no task runner! in DrmThreadProxy::CreateBuffer"; << "no task runner! in DrmThreadProxy::CreateBuffer";
scoped_refptr<GbmBuffer> buffer; scoped_refptr<GbmBuffer> buffer;
...@@ -44,7 +45,7 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer( ...@@ -44,7 +45,7 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer(
PostSyncTask( PostSyncTask(
drm_thread_.task_runner(), drm_thread_.task_runner(),
base::BindOnce(&DrmThread::CreateBuffer, base::Unretained(&drm_thread_), base::BindOnce(&DrmThread::CreateBuffer, base::Unretained(&drm_thread_),
widget, size, format, usage, &buffer)); widget, size, format, usage, flags, &buffer));
return buffer; return buffer;
} }
......
...@@ -35,7 +35,8 @@ class DrmThreadProxy { ...@@ -35,7 +35,8 @@ class DrmThreadProxy {
scoped_refptr<GbmBuffer> CreateBuffer(gfx::AcceleratedWidget widget, scoped_refptr<GbmBuffer> CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size, const gfx::Size& size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage); gfx::BufferUsage usage,
uint32_t flags);
scoped_refptr<GbmBuffer> CreateBufferFromFds( scoped_refptr<GbmBuffer> CreateBufferFromFds(
gfx::AcceleratedWidget widget, gfx::AcceleratedWidget widget,
......
...@@ -23,6 +23,8 @@ class GbmSurfaceFactory; ...@@ -23,6 +23,8 @@ class GbmSurfaceFactory;
class GbmBuffer : public ScanoutBuffer { class GbmBuffer : public ScanoutBuffer {
public: public:
static constexpr uint32_t kFlagNoModifiers = 1U << 0;
static scoped_refptr<GbmBuffer> CreateBuffer( static scoped_refptr<GbmBuffer> CreateBuffer(
const scoped_refptr<GbmDevice>& gbm, const scoped_refptr<GbmDevice>& gbm,
uint32_t format, uint32_t format,
......
...@@ -29,7 +29,11 @@ ...@@ -29,7 +29,11 @@
#include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/ozone/public/surface_ozone_canvas.h"
#if BUILDFLAG(ENABLE_VULKAN) #if BUILDFLAG(ENABLE_VULKAN)
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h" #include "ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h"
#if defined(OS_CHROMEOS)
#include <vulkan/vulkan_intel.h>
#endif
#endif #endif
namespace ui { namespace ui {
...@@ -135,6 +139,60 @@ std::unique_ptr<gpu::VulkanImplementation> ...@@ -135,6 +139,60 @@ std::unique_ptr<gpu::VulkanImplementation>
GbmSurfaceFactory::CreateVulkanImplementation() { GbmSurfaceFactory::CreateVulkanImplementation() {
return std::make_unique<ui::VulkanImplementationGbm>(); return std::make_unique<ui::VulkanImplementationGbm>();
} }
scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
const gpu::VulkanFunctionPointers* vulkan_function_pointers,
VkDevice vk_device,
VkDeviceMemory* vk_device_memory,
VkImage* vk_image) {
#if defined(OS_CHROMEOS)
scoped_refptr<GbmBuffer> buffer = drm_thread_proxy_->CreateBuffer(
widget, size, format, usage, GbmBuffer::kFlagNoModifiers);
if (!buffer.get())
return nullptr;
PFN_vkCreateDmaBufImageINTEL create_dma_buf_image_intel =
reinterpret_cast<PFN_vkCreateDmaBufImageINTEL>(
vulkan_function_pointers->vkGetDeviceProcAddr(
vk_device, "vkCreateDmaBufImageINTEL"));
if (!create_dma_buf_image_intel) {
LOG(ERROR) << "Scanout buffers can only be imported into vulkan when "
"vkCreateDmaBufImageINTEL is available.";
return nullptr;
}
DCHECK(buffer->AreFdsValid());
DCHECK_EQ(buffer->GetFdCount(), 1U);
base::ScopedFD vk_image_fd(dup(buffer->GetFd(0)));
DCHECK(vk_image_fd.is_valid());
VkDmaBufImageCreateInfo dma_buf_image_create_info = {
.sType = static_cast<VkStructureType>(
VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL),
.fd = vk_image_fd.release(),
.format = VK_FORMAT_B8G8R8A8_SRGB,
.extent = (VkExtent3D){size.width(), size.height(), 1},
.strideInBytes = buffer->GetStride(0),
};
VkResult result =
create_dma_buf_image_intel(vk_device, &dma_buf_image_create_info, nullptr,
vk_device_memory, vk_image);
if (result != VK_SUCCESS) {
LOG(ERROR) << "Failed to create a Vulkan image from a dmabuf.";
return nullptr;
}
return base::MakeRefCounted<GbmPixmap>(this, buffer);
#else
return nullptr;
#endif
}
#endif #endif
std::unique_ptr<OverlaySurface> GbmSurfaceFactory::CreateOverlaySurface( std::unique_ptr<OverlaySurface> GbmSurfaceFactory::CreateOverlaySurface(
...@@ -162,8 +220,8 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( ...@@ -162,8 +220,8 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
gfx::Size size, gfx::Size size,
gfx::BufferFormat format, gfx::BufferFormat format,
gfx::BufferUsage usage) { gfx::BufferUsage usage) {
scoped_refptr<GbmBuffer> buffer = scoped_refptr<GbmBuffer> buffer = drm_thread_proxy_->CreateBuffer(
drm_thread_proxy_->CreateBuffer(widget, size, format, usage); widget, size, format, usage, 0 /* flags */);
if (!buffer.get()) if (!buffer.get())
return nullptr; return nullptr;
......
...@@ -41,6 +41,15 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone { ...@@ -41,6 +41,15 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone {
#if BUILDFLAG(ENABLE_VULKAN) #if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation() std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation()
override; override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmapForVulkan(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
const gpu::VulkanFunctionPointers* vulkan_function_pointers,
VkDevice vk_device,
VkDeviceMemory* vk_device_memory,
VkImage* vk_image) override;
#endif #endif
std::unique_ptr<OverlaySurface> CreateOverlaySurface( std::unique_ptr<OverlaySurface> CreateOverlaySurface(
......
...@@ -36,6 +36,20 @@ std::unique_ptr<gpu::VulkanImplementation> ...@@ -36,6 +36,20 @@ std::unique_ptr<gpu::VulkanImplementation>
SurfaceFactoryOzone::CreateVulkanImplementation() { SurfaceFactoryOzone::CreateVulkanImplementation() {
return nullptr; return nullptr;
} }
scoped_refptr<gfx::NativePixmap>
SurfaceFactoryOzone::CreateNativePixmapForVulkan(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
const gpu::VulkanFunctionPointers* vulkan_function_pointers,
VkDevice vk_device,
VkDeviceMemory* vk_device_memory,
VkImage* vk_image) {
NOTIMPLEMENTED();
return nullptr;
}
#endif #endif
std::unique_ptr<OverlaySurface> SurfaceFactoryOzone::CreateOverlaySurface( std::unique_ptr<OverlaySurface> SurfaceFactoryOzone::CreateOverlaySurface(
......
...@@ -32,6 +32,10 @@ namespace gfx { ...@@ -32,6 +32,10 @@ namespace gfx {
class NativePixmap; class NativePixmap;
} }
namespace gpu {
struct VulkanFunctionPointers;
}
namespace ui { namespace ui {
class SurfaceOzoneCanvas; class SurfaceOzoneCanvas;
...@@ -80,6 +84,19 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone { ...@@ -80,6 +84,19 @@ class OZONE_BASE_EXPORT SurfaceFactoryOzone {
// creating surfaces that swap to a platform window. // creating surfaces that swap to a platform window.
virtual std::unique_ptr<gpu::VulkanImplementation> virtual std::unique_ptr<gpu::VulkanImplementation>
CreateVulkanImplementation(); CreateVulkanImplementation();
// Creates a scanout NativePixmap that can be rendered using Vulkan.
// TODO(spang): Remove this once VK_EXT_image_drm_format_modifier is
// available.
virtual scoped_refptr<gfx::NativePixmap> CreateNativePixmapForVulkan(
gfx::AcceleratedWidget widget,
gfx::Size size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
const gpu::VulkanFunctionPointers* vulkan_function_pointers,
VkDevice vk_device,
VkDeviceMemory* vk_device_memory,
VkImage* vk_image);
#endif #endif
// Creates an overlay surface for a platform window. // Creates an overlay surface for a platform window.
......
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