Add implementation of the multi-image-format sysmem extension
Bug:62789
Change-Id: I1e9452fc3f7369c635598a12ea002cadcfd05248
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/mesa/+/445976
Reviewed-by: John Bauman <jbauman@google.com>
diff --git a/src/intel/vulkan/anv_magma_buffer_collection.c b/src/intel/vulkan/anv_magma_buffer_collection.c
index 24546bf..6b67f30 100644
--- a/src/intel/vulkan/anv_magma_buffer_collection.c
+++ b/src/intel/vulkan/anv_magma_buffer_collection.c
@@ -23,14 +23,21 @@
#include "anv_magma.h"
#include "anv_private.h"
-#include "isl/isl.h"
#include "magma_sysmem.h"
#include "vk_util.h"
+#include "isl/isl.h"
#if VK_USE_PLATFORM_FUCHSIA
+#define MAX_FORMAT_INDICES 128
+const uint32_t kMaxFormatIndices = MAX_FORMAT_INDICES;
+
struct anv_buffer_collection {
magma_buffer_collection_t buffer_collection;
+
+ magma_sysmem_buffer_constraints_t constraints;
+
+ uint32_t format_index_input_index_map[MAX_FORMAT_INDICES];
};
ANV_DEFINE_HANDLE_CASTS(anv_buffer_collection, VkBufferCollectionFUCHSIA)
@@ -56,7 +63,10 @@
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;
+ buffer_collection->constraints = 0;
+
*pCollection = anv_buffer_collection_to_handle(buffer_collection);
return VK_SUCCESS;
@@ -73,13 +83,18 @@
if (status != MAGMA_STATUS_OK)
return;
+ if (buffer_collection->constraints) {
+ magma_buffer_constraints_release(sysmem_connection, buffer_collection->constraints);
+ }
+
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, VkFormat format, const VkImageCreateInfo* pImageInfo,
- magma_image_format_constraints_t* image_constraints_out, isl_tiling_flags_t isl_tiling_flags)
+ magma_image_format_constraints_t* image_constraints_out, isl_tiling_flags_t isl_tiling_flags,
+ VkImageFormatConstraintsInfoFUCHSIA* format_constraints)
{
ANV_FROM_HANDLE(anv_device, device, vk_device);
@@ -100,7 +115,7 @@
dim = ISL_SURF_DIM_2D;
break;
default:
- return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
struct isl_surf_init_info isl_surf_init_info = {
@@ -118,8 +133,10 @@
.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);
+ if (!isl_surf_init_s(&device->isl_dev, &isl_surf, &isl_surf_init_info)) {
+ intel_loge("get_image_format_constraints: isl_surf_init_s failed");
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ }
assert(pImageInfo->extent.width);
magma_image_format_constraints_t image_constraints = {.width = pImageInfo->extent.width,
@@ -145,7 +162,7 @@
image_constraints.format_modifier = MAGMA_FORMAT_MODIFIER_INTEL_YF_TILED;
break;
default:
- return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
switch (format) {
@@ -171,8 +188,21 @@
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
image_constraints.image_format = MAGMA_FORMAT_I420;
break;
+ case VK_FORMAT_R8_UNORM:
+ image_constraints.image_format = MAGMA_FORMAT_R8;
+ if (format_constraints && format_constraints->sysmemFormat) {
+ if (format_constraints->sysmemFormat == MAGMA_FORMAT_L8) {
+ image_constraints.image_format = MAGMA_FORMAT_L8;
+ } else if (format_constraints->sysmemFormat != MAGMA_FORMAT_R8) {
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ }
+ }
+ break;
+ case VK_FORMAT_R8G8_UNORM:
+ image_constraints.image_format = MAGMA_FORMAT_R8G8;
+ break;
default:
- return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
*image_constraints_out = image_constraints;
@@ -195,8 +225,7 @@
uint32_t slot_count = 0;
VkResult result;
- const VkFormat kDefaultFormatList[] = {VK_FORMAT_B8G8R8A8_UNORM,
- VK_FORMAT_R8G8B8A8_UNORM,
+ const VkFormat kDefaultFormatList[] = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM};
magma_image_format_constraints_t image_constraints[3 * ARRAY_SIZE(kDefaultFormatList)];
@@ -206,6 +235,7 @@
const VkFormat* format_list_to_try = &pImageInfo->format;
uint32_t num_formats_to_try = 1;
+
if (pImageInfo->format == VK_FORMAT_UNDEFINED) {
format_list_to_try = kDefaultFormatList;
num_formats_to_try = ARRAY_SIZE(kDefaultFormatList);
@@ -227,8 +257,9 @@
// optimal formats do.
assert(!(optimal_flags & ~linear_flags));
#endif
- result = get_image_format_constraints(vk_device, format, pImageInfo,
- &image_constraints[slot_count], ISL_TILING_LINEAR_BIT);
+ result =
+ get_image_format_constraints(vk_device, format, pImageInfo,
+ &image_constraints[slot_count], ISL_TILING_LINEAR_BIT, NULL);
if (result != VK_SUCCESS) {
return result;
}
@@ -238,14 +269,15 @@
image_constraints[slot_count - 1].image_format != MAGMA_FORMAT_NV12 &&
image_constraints[slot_count - 1].image_format != MAGMA_FORMAT_I420) {
// We always support X tiled for scanout but there may be a more optimal tiling format.
- result = get_image_format_constraints(vk_device, format, pImageInfo,
- &image_constraints[slot_count], ISL_TILING_X_BIT);
+ result = get_image_format_constraints(
+ vk_device, format, pImageInfo, &image_constraints[slot_count], ISL_TILING_X_BIT, NULL);
if (result == VK_SUCCESS) {
assert(image_constraints[slot_count].has_format_modifier);
slot_count++;
assert(slot_count < ARRAY_SIZE(image_constraints));
- result = get_image_format_constraints(
- vk_device, format, pImageInfo, &image_constraints[slot_count], ISL_TILING_ANY_MASK);
+ result = get_image_format_constraints(vk_device, format, pImageInfo,
+ &image_constraints[slot_count],
+ ISL_TILING_ANY_MASK, NULL);
if (result == VK_SUCCESS) {
assert(image_constraints[slot_count].has_format_modifier);
if (image_constraints[slot_count].format_modifier !=
@@ -365,6 +397,374 @@
return VK_SUCCESS;
}
+VkFormat sysmem_to_vk_format(uint32_t sysmem_format)
+{
+ switch (sysmem_format) {
+ case MAGMA_FORMAT_BGRA32:
+ return VK_FORMAT_B8G8R8A8_UNORM;
+ case MAGMA_FORMAT_R8G8B8A8:
+ return VK_FORMAT_R8G8B8A8_UNORM;
+ case MAGMA_FORMAT_NV12:
+ return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ case MAGMA_FORMAT_I420:
+ return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
+ case MAGMA_FORMAT_L8:
+ case MAGMA_FORMAT_R8:
+ return VK_FORMAT_R8_UNORM;
+ case MAGMA_FORMAT_R8G8:
+ return VK_FORMAT_R8G8_UNORM;
+ default:
+ return VK_FORMAT_UNDEFINED;
+ }
+}
+
+VkResult
+anv_GetBufferCollectionProperties2FUCHSIA(VkDevice vk_device,
+ VkBufferCollectionFUCHSIA vk_collection,
+ VkBufferCollectionProperties2FUCHSIA* pProperties)
+{
+ 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_buffer_format_description_t description;
+ status = magma_sysmem_get_description_from_collection(
+ sysmem_connection, buffer_collection->buffer_collection, &description);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ uint32_t count;
+ status = magma_get_buffer_count(description, &count);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_format_description_release(description);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ uint32_t sysmem_format;
+ status = magma_get_buffer_format(description, &sysmem_format);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_format_description_release(description);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ pProperties->sysmemFormat = sysmem_format;
+
+ magma_bool_t has_format_modifier;
+ uint64_t format_modifier = 0;
+ status = magma_get_buffer_format_modifier(description, &has_format_modifier, &format_modifier);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_format_description_release(description);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ uint32_t color_space = MAGMA_COLORSPACE_INVALID;
+ magma_get_buffer_color_space(description, &color_space);
+ // Colorspace may be invalid for non-images, so ignore error.
+
+ pProperties->colorSpace.colorSpace = color_space;
+ pProperties->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+ pProperties->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+ pProperties->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+ pProperties->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+
+ pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW;
+ pProperties->suggestedXChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
+ pProperties->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+
+ switch (color_space) {
+ case MAGMA_COLORSPACE_REC601_NTSC:
+ case MAGMA_COLORSPACE_REC601_PAL:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+ break;
+
+ case MAGMA_COLORSPACE_REC601_NTSC_FULL_RANGE:
+ case MAGMA_COLORSPACE_REC601_PAL_FULL_RANGE:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+ pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+ break;
+
+ case MAGMA_COLORSPACE_REC709:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709;
+ break;
+
+ case MAGMA_COLORSPACE_REC2020:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020;
+ break;
+
+ case MAGMA_COLORSPACE_SRGB:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
+ pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+ break;
+
+ default:
+ pProperties->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
+ pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+ break;
+ }
+
+ pProperties->createInfoIndex = 0;
+
+ if (buffer_collection->constraints) {
+ magma_bool_t format_valid[kMaxFormatIndices];
+ status = magma_get_description_format_index(sysmem_connection, description,
+ buffer_collection->constraints, format_valid,
+ kMaxFormatIndices);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_format_description_release(description);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ // Choose the first valid format for now.
+ for (uint32_t i = 0; i < kMaxFormatIndices; i++) {
+ if (format_valid[i]) {
+ pProperties->createInfoIndex = buffer_collection->format_index_input_index_map[i];
+ break;
+ }
+ }
+ }
+
+ if (!has_format_modifier) {
+ format_modifier = MAGMA_FORMAT_MODIFIER_LINEAR;
+ }
+
+ {
+ VkFormat format = sysmem_to_vk_format(sysmem_format);
+ const struct anv_physical_device* physical_device = device->physical;
+ const struct gen_device_info* devinfo = &physical_device->info;
+ const struct anv_format* anv_format = anv_get_format(format);
+ if (has_format_modifier) {
+ pProperties->formatFeatures =
+ anv_get_image_format_features(devinfo, format, anv_format, VK_IMAGE_TILING_OPTIMAL);
+ } else {
+ pProperties->formatFeatures =
+ anv_get_image_format_features(devinfo, format, anv_format, VK_IMAGE_TILING_LINEAR);
+ }
+ }
+
+ magma_buffer_format_description_release(description);
+
+ pProperties->bufferCount = count;
+
+ if (pProperties->bufferCount < 1) {
+ pProperties->memoryTypeBits = 0u;
+ } else {
+ struct anv_physical_device* pdevice = device->physical;
+ // All memory types supported.
+ pProperties->memoryTypeBits = (1ull << pdevice->memory.type_count) - 1;
+ }
+
+ return VK_SUCCESS;
+}
+
+VkResult anv_SetBufferCollectionImageConstraintsFUCHSIA(
+ VkDevice vk_device, VkBufferCollectionFUCHSIA vk_collection,
+ const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo)
+{
+ ANV_FROM_HANDLE(anv_device, device, vk_device);
+ ANV_FROM_HANDLE(anv_buffer_collection, collection, vk_collection);
+
+ // Can't set constraints twice.
+ if (collection->constraints)
+ return ANV_MAGMA_DRET(VK_ERROR_INITIALIZATION_FAILED);
+
+ 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);
+
+ if (pImageConstraintsInfo->createInfoCount < 1) {
+ assert(!(pImageConstraintsInfo->createInfoCount < 1));
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ const bool have_format_constraints = (pImageConstraintsInfo->pFormatConstraints != NULL);
+
+ // Secure formats not supported.
+ for (uint32_t i = 0; i < pImageConstraintsInfo->createInfoCount; ++i) {
+ bool secure_required =
+ (pImageConstraintsInfo->pCreateInfos[i].flags & VK_IMAGE_CREATE_PROTECTED_BIT);
+
+ const VkImageFormatConstraintsInfoFUCHSIA* format_constraints =
+ have_format_constraints ? &pImageConstraintsInfo->pFormatConstraints[i] : NULL;
+
+ bool this_secure_optional =
+ have_format_constraints && (pImageConstraintsInfo->pFormatConstraints[i].flags &
+ VK_IMAGE_FORMAT_CONSTRAINTS_PROTECTED_OPTIONAL_FUCHSIA);
+
+ if (secure_required || this_secure_optional) {
+ assert(!(secure_required || this_secure_optional));
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+ }
+
+ magma_sysmem_buffer_constraints_t constraints;
+
+ // Create the buffer constraints.
+ {
+ magma_buffer_format_constraints_t format_constraints = {
+ .count = pImageConstraintsInfo->minBufferCount,
+ .usage = 0,
+ .secure_permitted = false,
+ .secure_required = false,
+ .ram_domain_supported = true,
+ .cpu_domain_supported = true,
+ .min_size_bytes = 0,
+ };
+
+ status =
+ magma_buffer_constraints_create(sysmem_connection, &format_constraints, &constraints);
+ if (status != MAGMA_STATUS_OK)
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
+ // Add additional constraints.
+ {
+ magma_buffer_format_additional_constraints_t additional = {
+ .min_buffer_count_for_camping = pImageConstraintsInfo->minBufferCountForCamping,
+ .min_buffer_count_for_shared_slack = pImageConstraintsInfo->minBufferCountForSharedSlack,
+ .min_buffer_count_for_dedicated_slack =
+ pImageConstraintsInfo->minBufferCountForDedicatedSlack,
+ .max_buffer_count = pImageConstraintsInfo->maxBufferCount};
+
+ status = magma_buffer_constraints_add_additional(sysmem_connection, constraints, &additional);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+ }
+
+ uint32_t format_index = 0;
+
+ // Set format slots for each image info.
+ for (uint32_t i = 0; i < pImageConstraintsInfo->createInfoCount; ++i) {
+ const VkImageCreateInfo* pCreateInfo = &pImageConstraintsInfo->pCreateInfos[i];
+ VkFormat format = pCreateInfo->format;
+
+ const struct anv_physical_device* physical_device = device->physical;
+ const struct gen_device_info* devinfo = &physical_device->info;
+ const struct anv_format* anv_format = anv_get_format(format);
+ const VkFormatFeatureFlags linear_flags =
+ anv_get_image_format_features(devinfo, format, anv_format, VK_IMAGE_TILING_LINEAR);
+ const VkFormatFeatureFlags optimal_flags =
+ anv_get_image_format_features(devinfo, format, anv_format, VK_IMAGE_TILING_OPTIMAL);
+
+ const VkImageFormatConstraintsInfoFUCHSIA* format_constraints =
+ have_format_constraints ? &pImageConstraintsInfo->pFormatConstraints[i] : NULL;
+
+ const uint32_t colorSpaceCount = format_constraints ? format_constraints->colorSpaceCount : 0;
+ uint32_t color_spaces[colorSpaceCount];
+
+ for (uint32_t j = 0; j < colorSpaceCount; ++j) {
+ color_spaces[j] = format_constraints->pColorSpaces[j].colorSpace;
+ }
+
+ enum { SLOT0_LINEAR, SLOT1_X_TILED, SLOT2_TILED };
+ const uint32_t kSlotCount = 3;
+ magma_image_format_constraints_t image_constraints[kSlotCount];
+ bool image_constraints_valid[kSlotCount];
+
+ status = get_image_format_constraints(vk_device, format, pCreateInfo,
+ &image_constraints[SLOT0_LINEAR], ISL_TILING_LINEAR_BIT,
+ format_constraints);
+ if (status != VK_SUCCESS)
+ continue;
+
+ // Sysmem can't handle certain formats tiled, so don't attempt it.
+ bool skip_optimal = (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) ||
+ (image_constraints[SLOT0_LINEAR].image_format == MAGMA_FORMAT_NV12) ||
+ (image_constraints[SLOT0_LINEAR].image_format == MAGMA_FORMAT_I420) ||
+ (image_constraints[SLOT0_LINEAR].image_format == MAGMA_FORMAT_L8) ||
+ (image_constraints[SLOT0_LINEAR].image_format == MAGMA_FORMAT_R8) ||
+ (image_constraints[SLOT0_LINEAR].image_format == MAGMA_FORMAT_R8G8);
+
+ image_constraints_valid[SLOT0_LINEAR] =
+ !format_constraints || !(~linear_flags & format_constraints->requiredFormatFeatures);
+
+ if (skip_optimal) {
+ image_constraints_valid[SLOT1_X_TILED] = false;
+ } else {
+ image_constraints_valid[SLOT1_X_TILED] =
+ !format_constraints || !(~optimal_flags & format_constraints->requiredFormatFeatures);
+ }
+
+ image_constraints_valid[SLOT2_TILED] = image_constraints_valid[SLOT1_X_TILED];
+
+ for (uint32_t slot = 0; slot < kSlotCount; slot++) {
+ if (!image_constraints_valid[slot])
+ continue;
+
+ switch (slot) {
+ case SLOT0_LINEAR:
+ // Image constraints already initialized.
+ break;
+ case SLOT1_X_TILED:
+ status = get_image_format_constraints(vk_device, format, pCreateInfo,
+ &image_constraints[SLOT1_X_TILED],
+ ISL_TILING_X_BIT, format_constraints);
+ break;
+ case SLOT2_TILED:
+ status = get_image_format_constraints(vk_device, format, pCreateInfo,
+ &image_constraints[SLOT2_TILED],
+ ISL_TILING_ANY_MASK, format_constraints);
+ break;
+ default:
+ assert(false);
+ }
+
+ if (status != VK_SUCCESS)
+ continue;
+
+ // Currently every vulkan format maps to only 1 sysmem format, so ensure the client is
+ // using the same format.
+ if (format_constraints && format_constraints->sysmemFormat &&
+ (format_constraints->sysmemFormat != image_constraints[slot].image_format)) {
+ continue;
+ }
+
+ collection->format_index_input_index_map[format_index] = i;
+
+ status = magma_buffer_constraints_set_format(sysmem_connection, constraints, format_index,
+ &image_constraints[slot]);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ if (colorSpaceCount) {
+ magma_buffer_constraints_set_colorspaces(sysmem_connection, constraints, format_index,
+ colorSpaceCount, color_spaces);
+ }
+
+ format_index += 1;
+ if (format_index >= kMaxFormatIndices) {
+ assert(!(format_index >= kMaxFormatIndices));
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+ return ANV_MAGMA_DRET(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+ }
+ }
+
+ if (format_index == 0) {
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ status = magma_buffer_collection_set_constraints(sysmem_connection,
+ collection->buffer_collection, constraints);
+ if (status != MAGMA_STATUS_OK) {
+ magma_buffer_constraints_release(sysmem_connection, constraints);
+ return ANV_MAGMA_DRET(VK_ERROR_FORMAT_NOT_SUPPORTED);
+ }
+
+ collection->constraints = constraints;
+
+ return VK_SUCCESS;
+}
+
// Takes ownership of the buffer format description.
static VkResult anv_image_params_from_description(
magma_buffer_format_description_t description, uint32_t width, uint32_t height,
diff --git a/src/vulkan/registry/vk.xml b/src/vulkan/registry/vk.xml
index 5452635..08fa87d 100644
--- a/src/vulkan/registry/vk.xml
+++ b/src/vulkan/registry/vk.xml
@@ -345,6 +345,7 @@
<type category="bitmask">typedef <type>VkFlags</type> <name>VkPipelineRasterizationDepthClipStateCreateFlagsEXT</name>;</type>
<type requires="VkSwapchainImageUsageFlagBitsANDROID" category="bitmask">typedef <type>VkFlags</type> <name>VkSwapchainImageUsageFlagsANDROID</name>;</type>
<type requires="VkToolPurposeFlagBitsEXT" category="bitmask">typedef <type>VkFlags</type> <name>VkToolPurposeFlagsEXT</name>;</type>
+ <type requires="VkImageFormatConstraintsFlagBitsFUCHSIA" category="bitmask">typedef <type>VkFlags</type> <name>VkImageFormatConstraintsFlagsFUCHSIA</name>;</type>
<comment>Types which can be void pointers or class pointers, selected at compile time</comment>
<type category="handle"><type>VK_DEFINE_HANDLE</type>(<name>VkInstance</name>)</type>
@@ -537,6 +538,7 @@
<type name="VkPipelineCompilerControlFlagBitsAMD" category="enum"/>
<type name="VkShaderCorePropertiesFlagBitsAMD" category="enum"/>
<type name="VkToolPurposeFlagBitsEXT" category="enum"/>
+ <type name="VkImageFormatConstraintsFlagBitsFUCHSIA" category="enum"/>
<comment>WSI extensions</comment>
<type name="VkColorSpaceKHR" category="enum"/>
@@ -2252,13 +2254,54 @@
<member><type>uint32_t</type> <name>memoryTypeBits</name></member>
<member><type>uint32_t</type> <name>count</name></member>
</type>
+ <type category="struct" name="VkBufferCollectionProperties2FUCHSIA">
+ <member values="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES2_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member><type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>memoryTypeBits</name></member>
+ <member><type>uint32_t</type> <name>bufferCount</name></member>
+ <member><type>uint32_t</type> <name>createInfoIndex</name></member>
+ <member><type>uint64_t</type> <name>sysmemFormat</name></member>
+ <member><type>VkFormatFeatureFlags</type> <name>formatFeatures</name></member>
+ <member><type>VkSysmemColorSpaceFUCHSIA</type> <name>colorSpace</name></member>
+ <member><type>VkComponentMapping</type> <name>samplerYcbcrConversionComponents</name></member>
+ <member><type>VkSamplerYcbcrModelConversion</type> <name>suggestedYcbcrModel</name></member>
+ <member><type>VkSamplerYcbcrRange</type> <name>suggestedYcbcrRange</name></member>
+ <member><type>VkChromaLocation</type> <name>suggestedXChromaOffset</name></member>
+ <member><type>VkChromaLocation</type> <name>suggestedYChromaOffset</name></member>
+ </type>
<type category="struct" name="VkBufferConstraintsInfoFUCHSIA">
<member values="VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
<member>const <type>void</type>* <name>pNext</name></member>
<member>const <type>VkBufferCreateInfo</type>* <name>pBufferCreateInfo</name></member>
- <member><type>VkFormatFeatureFlags</type> <name>requiredFormatFeatures</name></member>
+ <member optional="true"> <type>VkFormatFeatureFlags</type> <name>requiredFormatFeatures</name></member>
<member><type>uint32_t</type> <name>minCount</name></member>
</type>
+ <type category="struct" name="VkSysmemColorSpaceFUCHSIA">
+ <member values="VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>colorSpace</name></member>
+ </type>
+ <type category="struct" name="VkImageFormatConstraintsInfoFUCHSIA">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member optional="true"><type>VkFormatFeatureFlags</type> <name>requiredFormatFeatures</name></member>
+ <member optional="true"><type>VkImageFormatConstraintsFlagsFUCHSIA</type> <name>flags</name></member>
+ <member><type>uint64_t</type> <name>sysmemFormat</name></member>
+ <member><type>uint32_t</type> <name>colorSpaceCount</name></member>
+ <member optional="true">const <type>VkSysmemColorSpaceFUCHSIA</type>* <name>pColorSpaces</name></member>
+ </type>
+ <type category="struct" name="VkImageConstraintsInfoFUCHSIA">
+ <member values="VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA"><type>VkStructureType</type> <name>sType</name></member>
+ <member>const <type>void</type>* <name>pNext</name></member>
+ <member><type>uint32_t</type> <name>createInfoCount</name></member>
+ <member len="createInfoCount">const <type>VkImageCreateInfo</type>* <name>pCreateInfos</name></member>
+ <member len="createInfoCount" optional="true">const <type>VkImageFormatConstraintsInfoFUCHSIA</type>* <name>pFormatConstraints</name></member>
+ <member><type>uint32_t</type> <name>minBufferCount</name></member>
+ <member><type>uint32_t</type> <name>maxBufferCount</name></member>
+ <member><type>uint32_t</type> <name>minBufferCountForCamping</name></member>
+ <member><type>uint32_t</type> <name>minBufferCountForDedicatedSlack</name></member>
+ <member><type>uint32_t</type> <name>minBufferCountForSharedSlack</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>
@@ -5926,6 +5969,13 @@
<enum bitpos="3" name="VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT"/>
<enum bitpos="4" name="VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT"/>
</enums>
+ <enums name="VkImageFormatConstraintsFlagBitsFUCHSIA" type="bitmask">
+ <enum bitpos="0" name="VK_IMAGE_FORMAT_CONSTRAINTS_CPU_READ_RARELY_FUCHSIA"/>
+ <enum bitpos="1" name="VK_IMAGE_FORMAT_CONSTRAINTS_CPU_READ_OFTEN_FUCHSIA"/>
+ <enum bitpos="2" name="VK_IMAGE_FORMAT_CONSTRAINTS_CPU_WRITE_RARELY_FUCHSIA"/>
+ <enum bitpos="3" name="VK_IMAGE_FORMAT_CONSTRAINTS_CPU_WRITE_OFTEN_FUCHSIA"/>
+ <enum bitpos="4" name="VK_IMAGE_FORMAT_CONSTRAINTS_PROTECTED_OPTIONAL_FUCHSIA"/>
+ </enums>
<commands comment="Vulkan command definitions">
<command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED,VK_ERROR_LAYER_NOT_PRESENT,VK_ERROR_EXTENSION_NOT_PRESENT,VK_ERROR_INCOMPATIBLE_DRIVER">
@@ -7106,6 +7156,12 @@
<param>const <type>VkImageCreateInfo</type>* <name>pImageInfo</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>vkSetBufferCollectionImageConstraintsFUCHSIA</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
+ <param>const <type>VkImageConstraintsInfoFUCHSIA</type>* <name>pImageConstraintsInfo</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>vkSetBufferCollectionBufferConstraintsFUCHSIA</name></proto>
<param><type>VkDevice</type> <name>device</name></param>
<param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
@@ -7123,6 +7179,12 @@
<param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
<param><type>VkBufferCollectionPropertiesFUCHSIA</type>* <name>pProperties</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>vkGetBufferCollectionProperties2FUCHSIA</name></proto>
+ <param><type>VkDevice</type> <name>device</name></param>
+ <param><type>VkBufferCollectionFUCHSIA</type> <name>collection</name></param>
+ <param><type>VkBufferCollectionProperties2FUCHSIA</type>* <name>pProperties</name></param>
+ </command>
<command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_NATIVE_WINDOW_IN_USE_KHR">
<proto><type>VkResult</type> <name>vkCreateStreamDescriptorSurfaceGGP</name></proto>
<param><type>VkInstance</type> <name>instance</name></param>
@@ -12577,7 +12639,7 @@
<enum bitpos="2" extends="VkMemoryHeapFlagBits" name="VK_MEMORY_HEAP_RESERVED_2_BIT_KHR"/>
</require>
</extension>
- <extension name="VK_FUCHSIA_buffer_collection" number="1005" type="device" requires="VK_FUCHSIA_external_memory" author="FUCHSIA" contact="John Bauman @jbauman" supported="vulkan" platform="fuchsia">
+ <extension name="VK_FUCHSIA_buffer_collection" number="1005" type="device" requires="VK_FUCHSIA_external_memory,VK_KHR_sampler_ycbcr_conversion" 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"/>
@@ -12590,6 +12652,10 @@
<enum offset="6" extends="VkStructureType" name="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA"/>
<enum offset="7" extends="VkStructureType" name="VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA"/>
<enum offset="8" extends="VkStructureType" name="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA"/>
+ <enum offset="9" extends="VkStructureType" name="VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA"/>
+ <enum offset="10" extends="VkStructureType" name="VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA"/>
+ <enum offset="11" extends="VkStructureType" name="VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES2_FUCHSIA"/>
+ <enum offset="12" extends="VkStructureType" name="VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA"/>
<type name="VkBufferCollectionFUCHSIA"/>
<type name="VkBufferCollectionCreateInfoFUCHSIA"/>
<type name="VkFuchsiaImageFormatFUCHSIA"/>
@@ -12598,11 +12664,19 @@
<type name="VkBufferConstraintsInfoFUCHSIA"/>
<type name="VkBufferCollectionBufferCreateInfoFUCHSIA"/>
<type name="VkBufferCollectionPropertiesFUCHSIA"/>
+ <type name="VkBufferCollectionProperties2FUCHSIA"/>
+ <type name="VkImageFormatConstraintsFlagBitsFUCHSIA"/>
+ <type name="VkImageFormatConstraintsFlagsFUCHSIA"/>
+ <type name="VkSysmemColorSpaceFUCHSIA"/>
+ <type name="VkImageConstraintsInfoFUCHSIA"/>
+ <type name="VkImageFormatConstraintsInfoFUCHSIA"/>
<command name="vkCreateBufferCollectionFUCHSIA"/>
<command name="vkSetBufferCollectionConstraintsFUCHSIA"/>
<command name="vkSetBufferCollectionBufferConstraintsFUCHSIA"/>
+ <command name="vkSetBufferCollectionImageConstraintsFUCHSIA"/>
<command name="vkDestroyBufferCollectionFUCHSIA"/>
<command name="vkGetBufferCollectionPropertiesFUCHSIA"/>
+ <command name="vkGetBufferCollectionProperties2FUCHSIA"/>
</require>
</extension>
<extension name="VK_FUCHSIA_external_memory" number="1006" type="device" requires="VK_KHR_external_memory_capabilities,VK_KHR_external_memory" author="FUCHSIA" contact="Craig Stout @cdotstout" supported="vulkan" platform="fuchsia">