[intel][vulkan] Add VK_FUCHSIA_buffer_collection
Minimal implementation that passes current tests:
all plane bytes_per_row must match, and plane offsets
are just checked.
Change-Id: Ia13527936dd2a9351fea3790a7f33bb1198d65a4
diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h
index 8c69900..1d03fc2 100644
--- a/include/vulkan/vulkan_core.h
+++ b/include/vulkan/vulkan_core.h
@@ -456,6 +456,8 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1001004000,
+ VK_STRUCTURE_TYPE_FUCHSIA_IMAGE_FORMAT_FUCHSIA = 1001004001,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FUCHSIA_HANDLE_INFO_KHR = 1001000000,
VK_STRUCTURE_TYPE_MEMORY_FUCHSIA_HANDLE_PROPERTIES_KHR = 1001000001,
VK_STRUCTURE_TYPE_MEMORY_GET_FUCHSIA_HANDLE_INFO_KHR = 1001000002,
@@ -1285,6 +1287,7 @@
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX = 1000165000,
+ VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1001004002,
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN,
@@ -6191,6 +6194,7 @@
VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NVX_EXT = 1000165000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1001004003,
VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
diff --git a/include/vulkan/vulkan_fuchsia.h b/include/vulkan/vulkan_fuchsia.h
index 73a3152..9f32a9f 100644
--- a/include/vulkan/vulkan_fuchsia.h
+++ b/include/vulkan/vulkan_fuchsia.h
@@ -131,9 +131,50 @@
#define VK_GOOGLE_IMAGE_USAGE_SCANOUT_SPEC_VERSION 1
#define VK_GOOGLE_IMAGE_USAGE_SCANOUT_EXTENSION_NAME "VK_GOOGLE_image_usage_scanout"
+#define VK_FUCHSIA_buffer_collection 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA)
+
+#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 1
+#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection"
+
+typedef struct VkBufferCollectionCreateInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ zx_handle_t collectionToken;
+} VkBufferCollectionCreateInfoFUCHSIA;
+
+typedef struct VkFuchsiaImageFormatFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ const void* imageFormat;
+ uint32_t imageFormatSize;
+} VkFuchsiaImageFormatFUCHSIA;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferCollectionFUCHSIA)(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pImportInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection);
+typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageCreateInfo* pImageInfo);
+typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA(
+ VkDevice device,
+ const VkBufferCollectionCreateInfoFUCHSIA* pImportInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBufferCollectionFUCHSIA* pCollection);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionConstraintsFUCHSIA(
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkImageCreateInfo* pImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA(
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkAllocationCallbacks* pAllocator);
+#endif
#ifdef __cplusplus
}
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/src/intel/vulkan/BUILD.gn b/src/intel/vulkan/BUILD.gn
index 7d95bad..8b39ea1 100644
--- a/src/intel/vulkan/BUILD.gn
+++ b/src/intel/vulkan/BUILD.gn
@@ -109,6 +109,7 @@
"anv_image.c",
"anv_intel.c",
"anv_magma.c",
+ "anv_magma_buffer_collection.c",
"anv_magma_connection.cc",
"anv_nir.h",
"anv_nir_add_base_work_group_id.c",
@@ -242,6 +243,7 @@
inputs = [
"anv_entrypoints_gen.py",
+ "anv_extensions.py",
"$mesa_build_root/src/vulkan/registry/vk.xml",
]
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index 27b1153..c038ef1 100755
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -515,6 +515,8 @@
ext = '_KHR'
if platform.upper() == 'XLIB_XRANDR':
ext = '_EXT'
+ if platform.upper() == 'FUCHSIA':
+ ext = ''
define = 'VK_USE_PLATFORM_' + platform.upper() + ext
if 'protect' in extension.attrib:
define = extension.attrib['protect']
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index 7ad7a19..82f1435 100755
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -127,6 +127,7 @@
Extension('VK_KHR_external_memory_fuchsia', 1, 'VK_USE_PLATFORM_FUCHSIA'),
Extension('VK_KHR_external_semaphore_fuchsia', 1, 'VK_USE_PLATFORM_FUCHSIA'),
Extension('VK_GOOGLE_image_usage_scanout', 1, 'VK_USE_PLATFORM_FUCHSIA'),
+ Extension('VK_FUCHSIA_buffer_collection', 1, 'VK_USE_PLATFORM_FUCHSIA'),
]
class VkVersion:
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index c63c72b..6b6d2ee 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -35,7 +35,7 @@
#include "vk_format_info.h"
-static isl_surf_usage_flags_t
+isl_surf_usage_flags_t
choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
VkImageUsageFlags vk_usage,
isl_surf_usage_flags_t isl_extra_usage,
@@ -642,6 +642,46 @@
pAllocator, pImage);
#endif
+#if VK_USE_PLATFORM_FUCHSIA
+ const struct VkFuchsiaImageFormatFUCHSIA *image_format_fuchsia =
+ vk_find_struct_const(pCreateInfo->pNext, FUCHSIA_IMAGE_FORMAT_FUCHSIA);
+ if (image_format_fuchsia) {
+ const int kParamCount = 4;
+ struct anv_fuchsia_image_plane_params params[kParamCount];
+ isl_tiling_flags_t tiling_flags;
+ VkResult result = anv_image_params_from_fuchsia_image(device, pCreateInfo, params, &tiling_flags);
+ if (result != VK_SUCCESS)
+ return result;
+
+ // We support only one bytes_per_row for all planes.
+ uint32_t bytes_per_row = params[0].bytes_per_row;
+ for (uint32_t i = 1; i < kParamCount; i++) {
+ assert(params[i].bytes_per_row == 0 || params[i].bytes_per_row == bytes_per_row);
+ }
+ result = anv_image_create(device,
+ &(struct anv_image_create_info) {
+ .vk_info = pCreateInfo,
+ .stride = bytes_per_row,
+ .isl_tiling_flags = tiling_flags,
+ // Disable compression bc sysmem doesn't support it.
+ .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT,
+ },
+ pAllocator,
+ pImage);
+ if (result != VK_SUCCESS)
+ return result;
+
+ // Check that byte offsets match.
+ ANV_FROM_HANDLE(anv_image, image, *pImage);
+ for (uint32_t i = 0; i < kParamCount; i++) {
+ if (params[i].bytes_per_row) {
+ assert(params[i].byte_offset == image->planes[i].offset);
+ }
+ }
+ return VK_SUCCESS;
+ }
+#endif
+
return anv_image_create(device,
&(struct anv_image_create_info) {
.vk_info = pCreateInfo,
diff --git a/src/intel/vulkan/anv_magma.h b/src/intel/vulkan/anv_magma.h
index c67e2824..9272702 100644
--- a/src/intel/vulkan/anv_magma.h
+++ b/src/intel/vulkan/anv_magma.h
@@ -10,6 +10,14 @@
#include "i915_drm.h"
#include "magma.h"
+#include <stdio.h>
+
+#if DEBUG
+#define ANV_MAGMA_DRET(ret) (ret == 0 ? ret : anv_magma_dret(__FILE__, __LINE__, ret))
+#else
+#define ANV_MAGMA_DRET(ret) (ret)
+#endif
+
struct anv_connection {
magma_connection_t connection;
};
@@ -28,6 +36,9 @@
void AnvMagmaReleaseConnection(struct anv_connection* connection);
+magma_status_t AnvMagmaGetSysmemConnection(struct anv_connection* connection,
+ magma_sysmem_connection_t* sysmem_connection_out);
+
void AnvMagmaConnectionWait(struct anv_connection* connection, uint64_t buffer_id,
int64_t* timeout_ns);
@@ -42,6 +53,12 @@
void AnvMagmaReleaseBuffer(struct anv_connection* connection, struct anv_magma_buffer* buffer);
+static inline int anv_magma_dret(const char* file, const int line, const int64_t ret)
+{
+ printf("%s:%d returning %ld\n", file, line, ret);
+ return ret;
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/src/intel/vulkan/anv_magma_buffer_collection.c b/src/intel/vulkan/anv_magma_buffer_collection.c
new file mode 100644
index 0000000..431b51d
--- /dev/null
+++ b/src/intel/vulkan/anv_magma_buffer_collection.c
@@ -0,0 +1,314 @@
+// Copyright 2019 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_magma.h"
+#include "anv_private.h"
+#include "isl.h"
+#include "magma_sysmem.h"
+#include "vk_util.h"
+
+#if VK_USE_PLATFORM_FUCHSIA
+
+struct anv_buffer_collection {
+ magma_buffer_collection_t buffer_collection;
+};
+
+ANV_DEFINE_HANDLE_CASTS(anv_buffer_collection, VkBufferCollectionFUCHSIA)
+
+VkResult anv_CreateBufferCollectionFUCHSIA(VkDevice vk_device,
+ const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBufferCollectionFUCHSIA* pCollection)
+{
+ ANV_FROM_HANDLE(anv_device, device, vk_device);
+
+ magma_sysmem_connection_t sysmem_connection;
+ magma_status_t status = AnvMagmaGetSysmemConnection(device->connection, &sysmem_connection);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_DEVICE_LOST);
+
+ magma_buffer_collection_t magma_buffer_collection;
+ status = magma_buffer_collection_import(sysmem_connection, pCreateInfo->collectionToken,
+ &magma_buffer_collection);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_INVALID_EXTERNAL_HANDLE);
+
+ struct anv_buffer_collection* buffer_collection =
+ vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer_collection), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ buffer_collection->buffer_collection = magma_buffer_collection;
+ *pCollection = anv_buffer_collection_to_handle(buffer_collection);
+
+ return VK_SUCCESS;
+}
+
+void anv_DestroyBufferCollectionFUCHSIA(VkDevice vk_device, VkBufferCollectionFUCHSIA vk_collection,
+ const VkAllocationCallbacks* pAllocator)
+{
+ ANV_FROM_HANDLE(anv_device, device, vk_device);
+ ANV_FROM_HANDLE(anv_buffer_collection, buffer_collection, vk_collection);
+
+ magma_sysmem_connection_t sysmem_connection;
+ magma_status_t status = AnvMagmaGetSysmemConnection(device->connection, &sysmem_connection);
+ if (status != MAGMA_STATUS_OK)
+ return;
+
+ magma_buffer_collection_release(sysmem_connection, buffer_collection->buffer_collection);
+ vk_free2(&device->alloc, pAllocator, buffer_collection);
+}
+
+static VkResult
+get_image_format_constraints(VkDevice vk_device, const VkImageCreateInfo* pImageInfo,
+ magma_image_format_constraints_t* image_constraints_out,
+ isl_tiling_flags_t isl_tiling_flags)
+{
+ ANV_FROM_HANDLE(anv_device, device, vk_device);
+
+ const struct anv_format_plane plane_format = anv_get_format_plane(
+ &device->info, pImageInfo->format, VK_IMAGE_ASPECT_COLOR_BIT, pImageInfo->tiling);
+
+ const isl_surf_usage_flags_t isl_surf_usage =
+ choose_isl_surf_usage(pImageInfo->flags, // vk_create_flags
+ pImageInfo->usage, // vk_usage
+ 0, // isl_extra_usage
+ VK_IMAGE_ASPECT_COLOR_BIT);
+ enum isl_surf_dim dim;
+ switch (pImageInfo->imageType) {
+ case VK_IMAGE_TYPE_1D:
+ dim = ISL_SURF_DIM_1D;
+ break;
+ case VK_IMAGE_TYPE_2D:
+ dim = ISL_SURF_DIM_2D;
+ break;
+ default:
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ struct isl_surf_init_info isl_surf_init_info = {
+ .dim = dim,
+ .format = plane_format.isl_format,
+ .width = pImageInfo->extent.width / plane_format.denominator_scales[0],
+ .height = pImageInfo->extent.height / plane_format.denominator_scales[1],
+ .depth = pImageInfo->extent.depth,
+ .levels = pImageInfo->mipLevels,
+ .array_len = pImageInfo->arrayLayers,
+ .samples = pImageInfo->samples,
+ .min_alignment = 0,
+ .row_pitch = 0,
+ .usage = isl_surf_usage,
+ .tiling_flags = isl_tiling_flags};
+
+ struct isl_surf isl_surf;
+ if (!isl_surf_init_s(&device->isl_dev, &isl_surf, &isl_surf_init_info))
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+
+ assert(pImageInfo->extent.width);
+ magma_image_format_constraints_t image_constraints = {.width = pImageInfo->extent.width,
+ .height = pImageInfo->extent.height,
+ .layers = 1,
+ .bytes_per_row_divisor = 1,
+ .min_bytes_per_row = isl_surf.row_pitch};
+
+ switch (isl_surf.tiling) {
+ case ISL_TILING_LINEAR:
+ image_constraints.has_format_modifier = false;
+ break;
+ case ISL_TILING_X:
+ image_constraints.has_format_modifier = true;
+ image_constraints.format_modifier = MAGMA_FORMAT_MODIFIER_INTEL_X_TILED;
+ break;
+ case ISL_TILING_Y0:
+ image_constraints.has_format_modifier = true;
+ image_constraints.format_modifier = MAGMA_FORMAT_MODIFIER_INTEL_Y_TILED;
+ break;
+ case ISL_TILING_Yf:
+ image_constraints.has_format_modifier = true;
+ image_constraints.format_modifier = MAGMA_FORMAT_MODIFIER_INTEL_YF_TILED;
+ break;
+ default:
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ switch (pImageInfo->format) {
+ case VK_FORMAT_B8G8R8A8_SINT:
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ case VK_FORMAT_B8G8R8A8_SRGB:
+ case VK_FORMAT_B8G8R8A8_SNORM:
+ case VK_FORMAT_B8G8R8A8_SSCALED:
+ case VK_FORMAT_B8G8R8A8_USCALED:
+ image_constraints.image_format = MAGMA_FORMAT_BGRA32;
+ break;
+ case VK_FORMAT_R8G8B8A8_SINT:
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ case VK_FORMAT_R8G8B8A8_SNORM:
+ case VK_FORMAT_R8G8B8A8_SSCALED:
+ case VK_FORMAT_R8G8B8A8_USCALED:
+ image_constraints.image_format = MAGMA_FORMAT_R8G8B8A8;
+ break;
+ case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+ image_constraints.image_format = MAGMA_FORMAT_NV12;
+ break;
+ default:
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ *image_constraints_out = image_constraints;
+
+ return VK_SUCCESS;
+}
+
+VkResult anv_SetBufferCollectionConstraintsFUCHSIA(VkDevice vk_device,
+ VkBufferCollectionFUCHSIA vk_collection,
+ const VkImageCreateInfo* pImageInfo)
+{
+ ANV_FROM_HANDLE(anv_device, device, vk_device);
+ ANV_FROM_HANDLE(anv_buffer_collection, buffer_collection, vk_collection);
+
+ magma_sysmem_connection_t sysmem_connection;
+ magma_status_t status = AnvMagmaGetSysmemConnection(device->connection, &sysmem_connection);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_DEVICE_LOST);
+
+ magma_image_format_constraints_t image_constraints[2];
+ uint32_t slot_count = 0;
+ VkResult result;
+
+ switch (pImageInfo->tiling) {
+ case VK_IMAGE_TILING_OPTIMAL: {
+ // We always support X tiled for scanout but there may be a more optimal tiling format.
+ result = get_image_format_constraints(vk_device, pImageInfo, &image_constraints[slot_count],
+ ISL_TILING_X_BIT);
+ if (result != VK_SUCCESS) {
+ break;
+ }
+
+ if (image_constraints[0].image_format == MAGMA_FORMAT_NV12) {
+ // Sysmem can't handle tiled NV12.
+ result = get_image_format_constraints(vk_device, pImageInfo, &image_constraints[0],
+ ISL_TILING_LINEAR_BIT);
+ if (result == VK_SUCCESS) {
+ slot_count = 1;
+ }
+ } else {
+ assert(image_constraints[0].has_format_modifier);
+ slot_count = 1;
+ result = get_image_format_constraints(vk_device, pImageInfo, &image_constraints[1],
+ ISL_TILING_ANY_MASK);
+ if (result == VK_SUCCESS) {
+ assert(image_constraints[1].has_format_modifier);
+ if (image_constraints[1].format_modifier != image_constraints[0].format_modifier) {
+ slot_count++;
+ }
+ }
+ }
+ break;
+ }
+ case VK_IMAGE_TILING_LINEAR: {
+ result = get_image_format_constraints(vk_device, pImageInfo, &image_constraints[0],
+ ISL_TILING_LINEAR_BIT);
+ if (result == VK_SUCCESS) {
+ assert(!image_constraints[0].has_format_modifier);
+ slot_count = 1;
+ }
+ break;
+ }
+ default:
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ if (result != VK_SUCCESS)
+ return result;
+
+ magma_buffer_format_constraints_t format_constraints = {
+ .count = 1, .usage = 0, .secure_permitted = false, .secure_required = false};
+
+ magma_sysmem_buffer_constraints_t constraints;
+ status = magma_buffer_constraints_create(sysmem_connection, &format_constraints, &constraints);
+ if (status != MAGMA_STATUS_OK)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ for (uint32_t slot = 0; slot < slot_count; slot++) {
+ assert(slot < sizeof(image_constraints) / sizeof(image_constraints[0]));
+ status = magma_buffer_constraints_set_format(sysmem_connection, constraints, slot,
+ &image_constraints[slot]);
+ if (status != MAGMA_STATUS_OK) {
+ break;
+ }
+ }
+
+ if (status == MAGMA_STATUS_OK) {
+ status = magma_buffer_collection_set_constraints(
+ sysmem_connection, buffer_collection->buffer_collection, constraints);
+ }
+
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+
+ if (status != MAGMA_STATUS_OK)
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+ return VK_SUCCESS;
+}
+
+VkResult anv_image_params_from_fuchsia_image(
+ VkDevice vk_device, const VkImageCreateInfo* pCreateInfo,
+ struct anv_fuchsia_image_plane_params params_out[MAGMA_MAX_IMAGE_PLANES],
+ isl_tiling_flags_t* tiling_flags_out)
+{
+ assert(pCreateInfo->arrayLayers == 1);
+ assert(pCreateInfo->extent.depth == 1);
+
+ const struct VkFuchsiaImageFormatFUCHSIA* image_format_fuchsia =
+ vk_find_struct_const(pCreateInfo->pNext, FUCHSIA_IMAGE_FORMAT_FUCHSIA);
+ assert(image_format_fuchsia);
+
+ magma_buffer_format_description_t description;
+ magma_status_t status;
+ status = magma_get_buffer_format_description(
+ image_format_fuchsia->imageFormat, image_format_fuchsia->imageFormatSize, &description);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+
+ magma_bool_t has_format_modifier;
+ uint64_t format_modifier;
+ magma_image_plane_t planes[MAGMA_MAX_IMAGE_PLANES];
+
+ status = magma_get_buffer_format_plane_info(description, planes);
+ if (status == MAGMA_STATUS_OK) {
+ status =
+ magma_get_buffer_format_modifier(description, &has_format_modifier, &format_modifier);
+ }
+
+ magma_buffer_format_description_release(description);
+
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+
+ *tiling_flags_out = ISL_TILING_LINEAR_BIT;
+
+ if (has_format_modifier) {
+ switch (format_modifier) {
+ case MAGMA_FORMAT_MODIFIER_INTEL_X_TILED:
+ *tiling_flags_out = ISL_TILING_X_BIT;
+ break;
+ case MAGMA_FORMAT_MODIFIER_INTEL_Y_TILED:
+ *tiling_flags_out = ISL_TILING_Y0_BIT;
+ break;
+ case MAGMA_FORMAT_MODIFIER_INTEL_YF_TILED:
+ *tiling_flags_out = ISL_TILING_Yf_BIT;
+ break;
+ default:
+ assert(false);
+ }
+ }
+
+ for (uint32_t i = 0; i < MAGMA_MAX_IMAGE_PLANES; i++) {
+ params_out[i].bytes_per_row = planes[i].bytes_per_row;
+ params_out[i].byte_offset = planes[i].byte_offset;
+ }
+
+ return VK_SUCCESS;
+}
+
+#endif // VK_USE_PLATFORM_FUCHSIA
diff --git a/src/intel/vulkan/anv_magma_connection.cc b/src/intel/vulkan/anv_magma_connection.cc
index 32c4d6e..4384472 100644
--- a/src/intel/vulkan/anv_magma_connection.cc
+++ b/src/intel/vulkan/anv_magma_connection.cc
@@ -4,6 +4,7 @@
#include "anv_magma.h"
#include "drm_command_buffer.h"
+#include "magma_sysmem.h"
#include "magma_util/inflight_list.h"
#include "magma_util/macros.h"
#include "magma_util/simple_allocator.h"
@@ -78,7 +79,13 @@
anv_connection::connection = magma_connection;
}
- ~Connection() { magma_release_connection(magma_connection()); }
+ ~Connection()
+ {
+ if (sysmem_connection_) {
+ magma_sysmem_connection_release(sysmem_connection_);
+ }
+ magma_release_connection(magma_connection());
+ }
magma_connection_t magma_connection() { return anv_connection::connection; }
@@ -102,12 +109,24 @@
void UnmapGpu(uint64_t gpu_addr) { allocator_->Free(gpu_addr); }
+ magma_status_t GetSysmemConnection(magma_sysmem_connection_t* sysmem_connection_out)
+ {
+ if (!sysmem_connection_) {
+ magma_status_t status = magma_sysmem_connection_create(&sysmem_connection_);
+ if (status != MAGMA_STATUS_OK)
+ return DRET(status);
+ }
+ *sysmem_connection_out = sysmem_connection_;
+ return MAGMA_STATUS_OK;
+ }
+
static Connection* cast(anv_connection* connection)
{
return static_cast<Connection*>(connection);
}
private:
+ magma_sysmem_connection_t sysmem_connection_{};
magma::InflightList inflight_list_;
std::unique_ptr<magma::AddressSpaceAllocator> allocator_;
uint64_t guard_page_count_;
@@ -123,6 +142,12 @@
delete static_cast<Connection*>(connection);
}
+magma_status_t AnvMagmaGetSysmemConnection(struct anv_connection* connection,
+ magma_sysmem_connection_t* sysmem_connection_out)
+{
+ return Connection::cast(connection)->GetSysmemConnection(sysmem_connection_out);
+}
+
void AnvMagmaConnectionWait(anv_connection* connection, uint64_t buffer_id, int64_t* timeout_ns)
{
magma::InflightList* inflight_list = Connection::cast(connection)->inflight_list();
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 50df89c..a75b005 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -3315,6 +3315,26 @@
return subpass_id;
}
+isl_surf_usage_flags_t
+choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
+ VkImageUsageFlags vk_usage,
+ isl_surf_usage_flags_t isl_extra_usage,
+ VkImageAspectFlagBits aspect);
+
+#if VK_USE_PLATFORM_FUCHSIA
+struct anv_fuchsia_image_plane_params {
+ uint32_t bytes_per_row;
+ uint32_t byte_offset;
+};
+
+VkResult anv_image_params_from_fuchsia_image(
+ VkDevice vk_device,
+ const VkImageCreateInfo *pCreateInfo,
+ struct anv_fuchsia_image_plane_params params_out[4],
+ isl_tiling_flags_t* tiling_flags_out);
+
+#endif
+
#define ANV_DEFINE_HANDLE_CASTS(__anv_type, __VkType) \
\
static inline struct __anv_type * \
diff --git a/src/vulkan/registry/vk.xml b/src/vulkan/registry/vk.xml
index 82df3d6..73fbf99 100644
--- a/src/vulkan/registry/vk.xml
+++ b/src/vulkan/registry/vk.xml
@@ -352,6 +352,7 @@
<type category="handle" name="VkSamplerYcbcrConversionKHR" alias="VkSamplerYcbcrConversion"/>
<type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkValidationCacheEXT</name>)</type>
<type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkAccelerationStructureNVX</name>)</type>
+ <type category="handle" parent="VkDevice"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkBufferCollectionFUCHSIA</name>)</type>
<comment>WSI extensions</comment>
<type category="handle"><type>VK_DEFINE_NON_DISPATCHABLE_HANDLE</type>(<name>VkDisplayKHR</name>)</type>
@@ -2142,6 +2143,17 @@
<member><type>VkDeviceMemory</type> <name>memory</name></member>
<member><type>VkExternalMemoryHandleTypeFlagBits</type> <name>handleType</name></member>
</type>
+ <type category="struct" name="VkFuchsiaImageFormatFUCHSIA" structextends="VkImageCreateInfo">
+ <member values="VK_STRUCTURE_TYPE_FUCHSIA_IMAGE_FORMAT_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member>const <type>void</type>* <name>imageFormat</name></member>
+ <member><type>uint32_t</type> <name>imageFormatSize</name></member>
+ </type>
+ <type category="struct" name="VkBufferCollectionCreateInfoFUCHSIA">
+ <member values="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>zx_handle_t</type> <name>collectionToken</name></member>
+ </type>
<type category="struct" name="VkWin32KeyedMutexAcquireReleaseInfoKHR" structextends="VkSubmitInfo">
<member values="VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR"><type>VkStructureType</type> <name>sType</name></member>
<member>const <type>void</type>* <name>pNext</name></member>
@@ -5937,6 +5949,25 @@
<param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
<param><type>VkSurfaceKHR</type>* <name>pSurface</name></param>
</command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkCreateBufferCollectionFUCHSIA</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param>const <type>VkBufferCollectionCreateInfoFUCHSIA</type>* <name>pImportInfo</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ <param><type>VkBufferCollectionFUCHSIA</type>* <name>pCollection</name></param>
+ </command>
+ <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
+ <proto><type>VkResult</type> <name>vkSetBufferCollectionConstraintsFUCHSIA</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
+ <param>const <type>VkImageCreateInfo</type>* <name>pImageInfo</name></param>
+ </command>
+ <command>
+ <proto><type>void</type> <name>vkDestroyBufferCollectionFUCHSIA</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
+ <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
+ </command>
<command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY">
<proto><type>VkResult</type> <name>vkCreateDebugReportCallbackEXT</name></proto>
<param><type>VkInstance</type> <name>instance</name></param>
@@ -10196,5 +10227,21 @@
<command name="vkGetSemaphoreFuchsiaHandleKHR"/>
</require>
</extension>
+ <extension name="VK_FUCHSIA_buffer_collection" number="1005" type="device" requires="VK_KHR_external_memory_fuchsia" author="FUCHSIA" contact="John Bauman @jbauman" supported="vulkan" platform="fuchsia">
+ <require>
+ <enum value="1" name="VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION"/>
+ <enum value=""VK_FUCHSIA_buffer_collection"" name="VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME"/>
+ <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA"/>
+ <enum offset="1" extends="VkStructureType" name="VK_STRUCTURE_TYPE_FUCHSIA_IMAGE_FORMAT_FUCHSIA"/>
+ <enum offset="2" extends="VkObjectType" name="VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA" comment="VkBufferCollectionFUCHSIA"/>
+ <enum offset="3" extends="VkDebugReportObjectTypeEXT" name="VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT"/>
+ <type name="VkBufferCollectionFUCHSIA"/>
+ <type name="VkBufferCollectionCreateInfoFUCHSIA"/>
+ <type name="VkFuchsiaImageFormatFUCHSIA"/>
+ <command name="vkCreateBufferCollectionFUCHSIA"/>
+ <command name="vkSetBufferCollectionConstraintsFUCHSIA"/>
+ <command name="vkDestroyBufferCollectionFUCHSIA"/>
+ </require>
+ </extension>
</extensions>
</registry>