blob: 6da4622d41cdda712b4c360636359ebfbbfa9bad [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "anv_wsi_magma.h"
#include "anv_magma.h"
#include "wsi_common_magma.h"
#include <fcntl.h>
#include <lib/framebuffer/framebuffer.h>
#include "vk_format_info.h"
VkBool32 anv_GetPhysicalDeviceMagmaPresentationSupportKHR(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex)
{
ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
return wsi_get_physical_device_magma_presentation_support(
&device->wsi_device, &device->instance->alloc, queueFamilyIndex);
}
VkResult anv_CreateMagmaSurfaceKHR(VkInstance _instance,
const VkMagmaSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
{
ANV_FROM_HANDLE(anv_instance, instance, _instance);
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_MAGMA_SURFACE_CREATE_INFO_KHR);
assert(pCreateInfo->imagePipeHandle == 0);
if (!pAllocator)
pAllocator = &instance->alloc;
auto surface = reinterpret_cast<VkIcdSurfaceMagma*>(
vk_alloc(pAllocator, sizeof(VkIcdSurfaceMagma), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
if (!surface)
return VK_ERROR_OUT_OF_HOST_MEMORY;
surface->base.platform = VK_ICD_WSI_PLATFORM_MAGMA;
const char* err;
surface->has_fb = fb_bind(false, &err) == ZX_OK;
*pSurface = VkIcdSurfaceBase_to_handle(&surface->base);
return VK_SUCCESS;
}
void* anv_wsi_magma_get_render_connection(VkDevice device)
{
return anv_device_from_handle(device)->connection;
}
void anv_wsi_magma_destroy_surface(VkIcdSurfaceBase* icd_surface)
{
auto surface = reinterpret_cast<VkIcdSurfaceMagma*>(icd_surface);
if (surface->has_fb)
fb_release();
}
VkResult anv_wsi_magma_image_create(VkDevice device_h, const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkImage* image_p,
VkDeviceMemory* memory_p, uint32_t* size, uint32_t* offset,
uint32_t* row_pitch, uintptr_t* buffer_handle_p)
{
struct anv_device* device = anv_device_from_handle(device_h);
VkImage image_h;
struct anv_image* image;
int ret;
VkImageCreateInfo create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = pCreateInfo->imageFormat,
.extent = {.width = pCreateInfo->imageExtent.width,
.height = pCreateInfo->imageExtent.height,
.depth = 1},
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = (pCreateInfo->imageUsage |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_SCANOUT_BIT_GOOGLE),
.flags = 0,
};
anv_image_create_info image_create_info = {
.isl_tiling_flags = 0, .stride = 0, .vk_info = &create_info};
VkResult result;
result = anv_image_create(anv_device_to_handle(device), &image_create_info, NULL, &image_h);
if (result != VK_SUCCESS)
return result;
image = anv_image_from_handle(image_h);
assert(vk_format_is_color(image->vk_format));
VkMemoryAllocateInfo allocate_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = image->size,
.memoryTypeIndex = 0,
};
VkDeviceMemory memory_h;
struct anv_device_memory* memory;
result = anv_AllocateMemory(anv_device_to_handle(device), &allocate_info,
NULL /* XXX: pAllocator */, &memory_h);
if (result != VK_SUCCESS) {
anv_DestroyImage(device_h, image_h, pAllocator);
return result;
}
memory = anv_device_memory_from_handle(memory_h);
anv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0);
assert(image->planes[0].offset == 0);
struct anv_surface *surface = &image->planes[0].surface;
*row_pitch = surface->isl.row_pitch;
*image_p = image_h;
*memory_p = memory_h;
*buffer_handle_p = image->planes[0].bo->gem_handle;
*size = image->size;
*offset = 0;
return VK_SUCCESS;
}
void anv_wsi_magma_image_free(VkDevice device, const VkAllocationCallbacks* pAllocator,
VkImage image_h, VkDeviceMemory memory_h)
{
anv_DestroyImage(device, image_h, pAllocator);
anv_FreeMemory(device, memory_h, pAllocator);
}
uintptr_t anv_wsi_magma_get_platform_semaphore(VkDevice vk_device, VkSemaphore vk_semaphore)
{
anv_device* device = anv_device_from_handle(vk_device);
ANV_FROM_HANDLE(anv_semaphore, semaphore, vk_semaphore);
anv_semaphore_impl* impl = semaphore->temporary.type != ANV_SEMAPHORE_TYPE_NONE
? &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);
}