Migrate vulkan to new zx display APIs
Change-Id: I54cdaa577cf9b1c2048cd82a518655f7c8da1ec1
diff --git a/include/vulkan/vk_icd.h b/include/vulkan/vk_icd.h
index f0f02f2..d95fe50 100644
--- a/include/vulkan/vk_icd.h
+++ b/include/vulkan/vk_icd.h
@@ -121,8 +121,7 @@
#ifdef VK_USE_PLATFORM_MAGMA_KHR
typedef struct _VkIcdSurfaceMagma {
VkIcdSurfaceBase base;
- int fd;
- void* connection;
+ bool has_fb;
} VkIcdSurfaceMagma;
#endif // VK_USE_PLATFORM_MAGMA_KHR
diff --git a/src/intel/vulkan/BUILD.gn b/src/intel/vulkan/BUILD.gn
index 2d8154b..aa67109 100644
--- a/src/intel/vulkan/BUILD.gn
+++ b/src/intel/vulkan/BUILD.gn
@@ -84,6 +84,7 @@
"$mesa_build_root/src/util",
"$mesa_build_root/src/vulkan/util",
"$msd_intel_gen_build_root/include",
+ "//zircon/public/lib/framebuffer",
]
sources = [
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 861cfc6..d891d07 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -41,7 +41,7 @@
.create_wsi_image = anv_wsi_magma_image_create,
.free_wsi_image = anv_wsi_magma_image_free,
.get_platform_semaphore = anv_wsi_magma_get_platform_semaphore,
- .vk_import_semaphore_fuchsia_handle_khr = anv_ImportSemaphoreFuchsiaHandleKHR,
+ .signal_semaphore = anv_wsi_magma_signal_semaphore,
};
#endif
diff --git a/src/intel/vulkan/anv_wsi_magma.cc b/src/intel/vulkan/anv_wsi_magma.cc
index 34922d1..6da4622 100644
--- a/src/intel/vulkan/anv_wsi_magma.cc
+++ b/src/intel/vulkan/anv_wsi_magma.cc
@@ -6,6 +6,7 @@
#include "anv_magma.h"
#include "wsi_common_magma.h"
#include <fcntl.h>
+#include <lib/framebuffer/framebuffer.h>
#include "vk_format_info.h"
@@ -36,12 +37,8 @@
return VK_ERROR_OUT_OF_HOST_MEMORY;
surface->base.platform = VK_ICD_WSI_PLATFORM_MAGMA;
- surface->fd = open("/dev/class/display/000", O_RDONLY);
-
- if (surface->fd >= 0)
- surface->connection = magma_create_connection(surface->fd, MAGMA_CAPABILITY_DISPLAY);
- else
- surface->connection = nullptr;
+ const char* err;
+ surface->has_fb = fb_bind(false, &err) == ZX_OK;
*pSurface = VkIcdSurfaceBase_to_handle(&surface->base);
@@ -56,10 +53,8 @@
void anv_wsi_magma_destroy_surface(VkIcdSurfaceBase* icd_surface)
{
auto surface = reinterpret_cast<VkIcdSurfaceMagma*>(icd_surface);
- if (surface->connection)
- magma_release_connection(reinterpret_cast<magma_connection_t*>(surface->connection));
- if (surface->fd >= 0)
- close(surface->fd);
+ if (surface->has_fb)
+ fb_release();
}
VkResult anv_wsi_magma_image_create(VkDevice device_h, const VkSwapchainCreateInfoKHR* pCreateInfo,
@@ -148,3 +143,11 @@
? &semaphore->temporary : &semaphore->permanent;
return impl->syncobj;
}
+
+void anv_wsi_magma_signal_semaphore(VkSemaphore vk_semaphore)
+{
+ ANV_FROM_HANDLE(anv_semaphore, semaphore, vk_semaphore);
+ anv_semaphore_impl* impl = semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE
+ ? &semaphore->temporary : &semaphore->permanent;
+ magma_signal_semaphore(impl->syncobj);
+}
diff --git a/src/intel/vulkan/anv_wsi_magma.h b/src/intel/vulkan/anv_wsi_magma.h
index dda05ea..32b9f38 100644
--- a/src/intel/vulkan/anv_wsi_magma.h
+++ b/src/intel/vulkan/anv_wsi_magma.h
@@ -25,6 +25,8 @@
uintptr_t anv_wsi_magma_get_platform_semaphore(VkDevice device, VkSemaphore semaphore);
+void anv_wsi_magma_signal_semaphore(VkSemaphore semaphore);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/vulkan/wsi/BUILD.gn b/src/vulkan/wsi/BUILD.gn
index 2b465f3..732f309 100644
--- a/src/vulkan/wsi/BUILD.gn
+++ b/src/vulkan/wsi/BUILD.gn
@@ -37,7 +37,8 @@
"$magma_build_root/include:magma_abi",
"$magma_build_root/src/magma_util",
"$mesa_build_root/include:vulkan",
- "$mesa_build_root/src/util"
+ "$mesa_build_root/src/util",
+ "//zircon/public/lib/framebuffer",
]
include_dirs = [ "$mesa_build_root/src/vulkan/util" ]
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index c91b7b0..2e01016 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -136,7 +136,7 @@
VkImage image_h,
VkDeviceMemory memory_h);
uintptr_t (*get_platform_semaphore)(VkDevice device, VkSemaphore semaphore);
- PFN_vkImportSemaphoreFuchsiaHandleKHR vk_import_semaphore_fuchsia_handle_khr;
+ void (*signal_semaphore)(VkSemaphore semaphore);
};
#define WSI_DEFINE_NONDISP_HANDLE_CASTS(__wsi_type, __VkType) \
diff --git a/src/vulkan/wsi/wsi_common_magma.cc b/src/vulkan/wsi/wsi_common_magma.cc
index 8fa0811..c2da472 100644
--- a/src/vulkan/wsi/wsi_common_magma.cc
+++ b/src/vulkan/wsi/wsi_common_magma.cc
@@ -3,8 +3,10 @@
// found in the LICENSE file.
#include <functional>
+#include <lib/framebuffer/framebuffer.h>
#include <memory>
#include <vector>
+#include <zircon/syscalls.h>
#include "util/macros.h"
#include "wsi_common_magma.h"
@@ -42,20 +44,16 @@
class WsiMagmaConnections {
public:
WsiMagmaConnections(magma_connection_t* render_connection,
- magma_connection_t* display_connection, const wsi_magma_callbacks* callbacks)
- : callbacks_(callbacks), render_connection_(render_connection),
- display_connection_(display_connection)
+ const wsi_magma_callbacks* callbacks)
+ : callbacks_(callbacks), render_connection_(render_connection)
{
}
magma_connection_t* render_connection() { return render_connection_; }
- magma_connection_t* display_connection() { return display_connection_; }
-
private:
const wsi_magma_callbacks* callbacks_; // not owned
magma_connection_t* render_connection_; // not owned
- magma_connection_t* display_connection_;
};
//////////////////////////////////////////////////////////////////////////////
@@ -69,11 +67,11 @@
~MagmaImage();
- magma_buffer_t display_buffer() { return display_buffer_; }
+ uint64_t display_buffer() { return display_buffer_; }
- magma_semaphore_t display_semaphore() { return display_semaphore_; }
+ zx_handle_t buffer_presented_semaphore() { return buffer_presented_semaphore_; }
- magma_semaphore_t buffer_presented_semaphore() { return buffer_presented_semaphore_; }
+ uint64_t buffer_presented_semaphore_id() { return buffer_presented_semaphore_id_; }
VkImage image() { return image_; }
@@ -84,13 +82,13 @@
private:
MagmaImage(VkDevice device, const wsi_magma_callbacks* callbacks,
std::shared_ptr<WsiMagmaConnections> connections, magma_buffer_t render_buffer,
- magma_buffer_t display_buffer, magma_semaphore_t display_semaphore, VkImage image,
- VkDeviceMemory device_memory, const VkAllocationCallbacks* allocator,
- magma_semaphore_t buffer_presented_semaphore)
+ uint64_t display_buffer, zx_handle_t buffer_presented_semaphore,
+ uint64_t buffer_presented_semaphore_id, VkImage image, VkDeviceMemory device_memory,
+ const VkAllocationCallbacks* allocator)
: device_(device), image_(image), device_memory_(device_memory), callbacks_(callbacks),
connections_(std::move(connections)), render_buffer_(render_buffer),
- display_buffer_(display_buffer), display_semaphore_(display_semaphore),
- buffer_presented_semaphore_(buffer_presented_semaphore), allocator_(allocator)
+ display_buffer_(display_buffer), buffer_presented_semaphore_(buffer_presented_semaphore),
+ buffer_presented_semaphore_id_(buffer_presented_semaphore_id), allocator_(allocator)
{
}
@@ -99,9 +97,10 @@
VkDeviceMemory device_memory_;
const wsi_magma_callbacks* callbacks_;
std::shared_ptr<WsiMagmaConnections> connections_;
- magma_buffer_t render_buffer_, display_buffer_; // render_buffer is not owned
- magma_semaphore_t display_semaphore_;
- magma_semaphore_t buffer_presented_semaphore_;
+ magma_buffer_t render_buffer_; // render_buffer is not owned
+ uint64_t display_buffer_;
+ zx_handle_t buffer_presented_semaphore_;
+ uint64_t buffer_presented_semaphore_id_;
const VkAllocationCallbacks* allocator_;
};
@@ -115,9 +114,9 @@
uint32_t row_pitch;
uint32_t offset;
uint32_t bpp = 32;
- magma_buffer_t render_buffer, display_buffer;
- magma_semaphore_t display_semaphore;
- magma_semaphore_t buffer_presented_semaphore;
+ magma_buffer_t render_buffer;
+ uint64_t display_buffer;
+ zx_handle_t buffer_presented_semaphore;
uint32_t buffer_handle, semaphore_handle;
uint32_t size;
VkImage image;
@@ -133,31 +132,40 @@
if (status != MAGMA_STATUS_OK)
return DRETP(nullptr, "failed to export buffer");
- status = magma_import(connections->display_connection(), buffer_handle, &display_buffer);
+ // Must be consistent with intel-gpu-core.h and the tiling format
+ // used by VK_IMAGE_USAGE_SCANOUT_BIT_GOOGLE.
+ const uint32_t kImageTypeXTiled = 1;
+ status = fb_import_image(buffer_handle, kImageTypeXTiled, &display_buffer);
if (status != MAGMA_STATUS_OK)
return DRETP(nullptr, "failed to import buffer");
- status = magma_create_semaphore(connections->display_connection(), &display_semaphore);
- if (status != MAGMA_STATUS_OK)
- return DRETP(nullptr, "failed to create semaphore");
+ if (zx_event_create(0, &buffer_presented_semaphore) != ZX_OK
+ || zx_object_signal(buffer_presented_semaphore, 0, ZX_EVENT_SIGNALED) != ZX_OK)
+ return DRETP(nullptr, "failed to create or signal semaphore");
- magma_signal_semaphore(display_semaphore);
+ zx_info_handle_basic_t info;
+ if (zx_object_get_info(buffer_presented_semaphore, ZX_INFO_HANDLE_BASIC,
+ &info, sizeof(info), nullptr, nullptr) != ZX_OK)
+ return DRETP(nullptr, "failed to get semaphore id");
- status = magma_create_semaphore(connections->display_connection(), &buffer_presented_semaphore);
- if (status != MAGMA_STATUS_OK)
- return DRETP(nullptr, "failed to create semaphore");
+ zx_handle_t dup;
+ if (zx_handle_duplicate(buffer_presented_semaphore, ZX_RIGHT_SAME_RIGHTS, &dup) != ZX_OK
+ || fb_import_event(dup, info.koid) != ZX_OK)
+ return DRETP(nullptr, "failed to duplicate or import display semaphore");
return std::unique_ptr<MagmaImage>(new MagmaImage(
- device, callbacks, std::move(connections), render_buffer, display_buffer, display_semaphore,
- image, device_memory, allocator, buffer_presented_semaphore));
+ device, callbacks, std::move(connections), render_buffer, display_buffer,
+ buffer_presented_semaphore, info.koid, image, device_memory, allocator));
}
MagmaImage::~MagmaImage()
{
callbacks_->free_wsi_image(device_, allocator_, image_, device_memory_);
- magma_release_buffer(connections_->display_connection(), display_buffer_);
- magma_release_semaphore(connections_->display_connection(), display_semaphore_);
+ fb_release_image(display_buffer_);
+ fb_release_event(buffer_presented_semaphore_id_);
+
+ zx_handle_close(buffer_presented_semaphore_);
}
//////////////////////////////////////////////////////////////////////////////
@@ -182,8 +190,6 @@
this->queue_present = QueuePresent;
}
- magma_connection_t* display_connection() { return connections_->display_connection(); }
-
magma_connection_t* render_connection() { return connections_->render_connection(); }
uint32_t image_count() { return images_.size(); }
@@ -224,7 +230,7 @@
return VK_SUCCESS;
}
- static VkResult AcquireNextImage(wsi_swapchain* wsi_chain, uint64_t timeout,
+ static VkResult AcquireNextImage(wsi_swapchain* wsi_chain, uint64_t timeout_ns,
VkSemaphore semaphore, uint32_t* pImageIndex)
{
MagmaSwapchain* chain = cast(wsi_chain);
@@ -233,26 +239,22 @@
MagmaImage* image = chain->get_image(index);
DLOG("AcquireNextImage semaphore id 0x%" PRIx64,
- magma_get_semaphore_id(image->display_semaphore()));
+ image->buffer_presented_semaphore_id());
+ // The zircon display APIs don't support providing an image back to the driver
+ // before the image is retired. Returning the presented semaphore from the vulkan API
+ // only prevents clients from rendering into the buffer, not from presenting the
+ // buffer (with a wait semaphore). So we can't return the buffer until this is signaled.
+ zx_signals_t observed;
+ zx_status_t status;
+ if ((status = zx_object_wait_one(image->buffer_presented_semaphore(), ZX_EVENT_SIGNALED,
+ zx_deadline_after(timeout_ns), &observed)) != ZX_OK) {
+ return VK_TIMEOUT;
+ }
+ // Unsignal the event.
+ zx_object_signal(image->buffer_presented_semaphore(), ZX_EVENT_SIGNALED, 0);
if (semaphore) {
- uint32_t semaphore_handle;
- magma_status_t status = magma_export_semaphore(
- chain->display_connection(), image->display_semaphore(), &semaphore_handle);
- if (status == MAGMA_STATUS_OK) {
- VkImportSemaphoreFuchsiaHandleInfoKHR info = {
- .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FUCHSIA_HANDLE_INFO_KHR,
- .semaphore = semaphore,
- .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
- .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FUCHSIA_FENCE_BIT_KHR,
- .handle = semaphore_handle};
- VkResult result =
- image->callbacks()->vk_import_semaphore_fuchsia_handle_khr(image->device(), &info);
- if (result != VK_SUCCESS)
- DLOG("vkImportSemaphoreFuchsiaHandleKHR failed: %d", result);
- } else {
- DLOG("magma_export_semaphore failed: %d", status);
- }
+ image->callbacks()->signal_semaphore(semaphore);
}
if (++chain->next_index_ >= chain->image_count())
@@ -260,7 +262,7 @@
*pImageIndex = index;
DLOG("AcquireNextImage returning index %u id 0x%" PRIx64, *pImageIndex,
- magma_get_buffer_id(image->display_buffer()));
+ image->display_buffer());
return VK_SUCCESS;
}
@@ -273,36 +275,37 @@
MagmaImage* image = magma_swapchain->get_image(image_index);
DLOG("QueuePresent image_index %u id 0x%" PRIx64, image_index,
- magma_get_buffer_id(image->display_buffer()));
+ image->display_buffer());
- magma_semaphore_t display_semaphores[wait_semaphore_count];
magma_status_t status;
+ // TODO(MA-375): Support more than 1 wait semaphore
+ assert(wait_semaphore_count <= 1);
+
+ uint64_t wait_sem_id = FB_INVALID_ID;
for (uint32_t i = 0; i < wait_semaphore_count; i++) {
uint32_t semaphore_handle;
+ uintptr_t platform_sem = image->callbacks()
+ ->get_platform_semaphore(swapchain->device, wait_semaphores[i]);
+ wait_sem_id = magma_get_semaphore_id(platform_sem);
+
status = magma_export_semaphore(
- magma_swapchain->render_connection(),
- image->callbacks()->get_platform_semaphore(swapchain->device, wait_semaphores[i]),
- &semaphore_handle);
+ magma_swapchain->render_connection(), platform_sem, &semaphore_handle);
if (status != MAGMA_STATUS_OK) {
DLOG("Failed to export wait semaphore");
continue;
}
magma_semaphore_t semaphore;
- status = magma_import_semaphore(magma_swapchain->display_connection(), semaphore_handle,
- &display_semaphores[i]);
- if (status != MAGMA_STATUS_OK)
+ status = fb_import_event(semaphore_handle, wait_sem_id);
+ if (status != ZX_OK)
DLOG("failed to import wait semaphore");
}
- magma_semaphore_t signal_semaphores[1]{image->display_semaphore()};
-
- magma_display_page_flip(magma_swapchain->display_connection(), image->display_buffer(),
- wait_semaphore_count, display_semaphores, 1, signal_semaphores,
- image->buffer_presented_semaphore());
+ fb_present_image(image->display_buffer(),
+ wait_sem_id, FB_INVALID_ID, image->buffer_presented_semaphore_id());
for (uint32_t i = 0; i < wait_semaphore_count; i++) {
- magma_release_semaphore(magma_swapchain->display_connection(), display_semaphores[i]);
+ fb_release_event(wait_sem_id);
}
return VK_SUCCESS;
@@ -333,9 +336,9 @@
VkBool32* pSupported)
{
auto surface = reinterpret_cast<VkIcdSurfaceMagma*>(icd_surface);
- DLOG("magma_surface_get_support queue %u connection %p", queueFamilyIndex, surface->connection);
+ DLOG("magma_surface_get_support queue %u connection %d", queueFamilyIndex, surface->has_fb);
- *pSupported = surface->connection != nullptr;
+ *pSupported = surface->has_fb;
return VK_SUCCESS;
}
@@ -343,14 +346,14 @@
VkSurfaceCapabilitiesKHR* caps)
{
auto surface = reinterpret_cast<VkIcdSurfaceMagma*>(icd_surface);
- DLOG("magma_surface_get_capabilities connection %p", surface->connection);
+ DLOG("magma_surface_get_capabilities connection %d", surface->has_fb);
VkExtent2D extent = {0xFFFFFFFF, 0xFFFFFFFF};
- magma_display_size display_size;
- magma_status_t status = magma_display_get_size(surface->fd, &display_size);
- if (status == MAGMA_STATUS_OK)
- extent = {display_size.width, display_size.height};
+ uint32_t width, height, stride;
+ zx_pixel_format_t format;
+ fb_get_config(&width, &height, &stride, &format);
+ extent = {width, height};
caps->minImageExtent = {1, 1};
caps->maxImageExtent = {extent};
@@ -425,10 +428,9 @@
auto render_connection =
reinterpret_cast<magma_connection_t*>(wsi_magma->callbacks()->get_render_connection(device));
auto magma_surface = reinterpret_cast<VkIcdSurfaceMagma*>(icd_surface);
- auto display_connection = reinterpret_cast<magma_connection_t*>(magma_surface->connection);
// TODO(MA-115): use pAllocator here and for images (and elsewhere in magma?)
- auto connections = std::make_shared<WsiMagmaConnections>(render_connection, display_connection,
+ auto connections = std::make_shared<WsiMagmaConnections>(render_connection,
wsi_magma->callbacks());
auto chain = std::make_unique<MagmaSwapchain>(device, connections);