fuchsia: Support upstream FUCHSIA_buffer_collection extension.
This supports the upstream 1.2.198 VK_FUCHSIA_buffer_collection
Vulkan extension. Previous FUCHSIAX extension will be still
supported until we completely finish the migration.
TEST: vkext_buffer_collection on Fuchsia
Bug: 90856
Change-Id: I84fb47479e079cf6c609293c4ba9ca2a7971a91d
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index a487bbe..139310d 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -429,6 +429,19 @@
uint32_t unused;
};
+ struct VkBufferCollectionFUCHSIA_Info {
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ android::base::Optional<
+ fuchsia_sysmem::wire::BufferCollectionConstraints>
+ constraints;
+ android::base::Optional<VkBufferCollectionPropertiesFUCHSIA> properties;
+
+ // the index of corresponding createInfo for each image format
+ // constraints in |constraints|.
+ std::vector<uint32_t> createInfoIndex;
+#endif // VK_USE_PLATFORM_FUCHSIA
+ };
+
struct VkBufferCollectionFUCHSIAX_Info {
#ifdef VK_USE_PLATFORM_FUCHSIA
android::base::Optional<
@@ -641,6 +654,14 @@
}
#ifdef VK_USE_PLATFORM_FUCHSIA
+ void unregister_VkBufferCollectionFUCHSIA(
+ VkBufferCollectionFUCHSIA collection) {
+ AutoLock<RecursiveLock> lock(mLock);
+ info_VkBufferCollectionFUCHSIA.erase(collection);
+ }
+#endif
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
void unregister_VkBufferCollectionFUCHSIAX(
VkBufferCollectionFUCHSIAX collection) {
AutoLock<RecursiveLock> lock(mLock);
@@ -2024,6 +2045,62 @@
return VK_SUCCESS;
}
+ VkResult on_vkCreateBufferCollectionFUCHSIA(
+ void*,
+ VkResult,
+ VkDevice,
+ const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
+ const VkAllocationCallbacks*,
+ VkBufferCollectionFUCHSIA* pCollection) {
+ fidl::ClientEnd<::fuchsia_sysmem::BufferCollectionToken> token_client;
+
+ if (pInfo->collectionToken) {
+ token_client =
+ fidl::ClientEnd<::fuchsia_sysmem::BufferCollectionToken>(
+ zx::channel(pInfo->collectionToken));
+ } else {
+ auto endpoints = fidl::CreateEndpoints<
+ ::fuchsia_sysmem::BufferCollectionToken>();
+ if (!endpoints.is_ok()) {
+ ALOGE("zx_channel_create failed: %d", endpoints.status_value());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto result = mSysmemAllocator->AllocateSharedCollection(
+ std::move(endpoints->server));
+ if (!result.ok()) {
+ ALOGE("AllocateSharedCollection failed: %d", result.status());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ token_client = std::move(endpoints->client);
+ }
+
+ auto endpoints =
+ fidl::CreateEndpoints<::fuchsia_sysmem::BufferCollection>();
+ if (!endpoints.is_ok()) {
+ ALOGE("zx_channel_create failed: %d", endpoints.status_value());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ auto [collection_client, collection_server] =
+ std::move(endpoints.value());
+
+ auto result = mSysmemAllocator->BindSharedCollection(
+ std::move(token_client), std::move(collection_server));
+ if (!result.ok()) {
+ ALOGE("BindSharedCollection failed: %d", result.status());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto* sysmem_collection =
+ new fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>(
+ std::move(collection_client));
+ *pCollection =
+ reinterpret_cast<VkBufferCollectionFUCHSIA>(sysmem_collection);
+
+ register_VkBufferCollectionFUCHSIA(*pCollection);
+ return VK_SUCCESS;
+ }
+
VkResult on_vkCreateBufferCollectionFUCHSIAX(
void*,
VkResult,
@@ -2077,6 +2154,23 @@
return VK_SUCCESS;
}
+ void on_vkDestroyBufferCollectionFUCHSIA(
+ void*,
+ VkResult,
+ VkDevice,
+ VkBufferCollectionFUCHSIA collection,
+ const VkAllocationCallbacks*) {
+ auto sysmem_collection = reinterpret_cast<
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
+ collection);
+ if (sysmem_collection) {
+ (*sysmem_collection)->Close();
+ }
+ delete sysmem_collection;
+
+ unregister_VkBufferCollectionFUCHSIA(collection);
+ }
+
void on_vkDestroyBufferCollectionFUCHSIAX(
void*,
VkResult,
@@ -2155,10 +2249,8 @@
}
uint32_t getBufferCollectionConstraintsVulkanBufferUsage(
- const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
+ VkBufferUsageFlags bufferUsage) {
uint32_t usage = 0u;
- VkBufferUsageFlags bufferUsage =
- pBufferConstraintsInfo->pBufferCreateInfo->usage;
#define SetUsageBit(BIT, VALUE) \
if (bufferUsage & VK_BUFFER_USAGE_##BIT##_BIT) { \
@@ -2179,6 +2271,20 @@
return usage;
}
+ uint32_t getBufferCollectionConstraintsVulkanBufferUsage(
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ VkBufferUsageFlags bufferUsage =
+ pBufferConstraintsInfo->createInfo.usage;
+ return getBufferCollectionConstraintsVulkanBufferUsage(bufferUsage);
+ }
+
+ uint32_t getBufferCollectionConstraintsVulkanBufferUsage(
+ const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
+ VkBufferUsageFlags bufferUsage =
+ pBufferConstraintsInfo->pBufferCreateInfo->usage;
+ return getBufferCollectionConstraintsVulkanBufferUsage(bufferUsage);
+ }
+
static fuchsia_sysmem::wire::PixelFormatType vkFormatTypeToSysmem(
VkFormat format) {
switch (format) {
@@ -2279,8 +2385,82 @@
}
}
- VkResult setBufferCollectionConstraints(
- VkEncoder* enc, VkDevice device,
+ // TODO(fxbug.dev/90856): This is currently only used for allocating
+ // memory for dedicated external images. It should be migrated to use
+ // SetBufferCollectionImageConstraintsFUCHSIA.
+ VkResult setBufferCollectionConstraintsFUCHSIA(
+ VkEncoder* enc,
+ VkDevice device,
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* collection,
+ const VkImageCreateInfo* pImageInfo) {
+ if (pImageInfo == nullptr) {
+ ALOGE("setBufferCollectionConstraints: pImageInfo cannot be null.");
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ const VkSysmemColorSpaceFUCHSIA kDefaultColorSpace = {
+ .sType = VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA,
+ .pNext = nullptr,
+ .colorSpace = static_cast<uint32_t>(
+ fuchsia_sysmem::wire::ColorSpaceType::kSrgb),
+ };
+
+ std::vector<VkImageFormatConstraintsInfoFUCHSIA> formatInfos;
+ if (pImageInfo->format == VK_FORMAT_UNDEFINED) {
+ const auto kFormats = {
+ VK_FORMAT_B8G8R8A8_SRGB,
+ VK_FORMAT_R8G8B8A8_SRGB,
+ };
+ for (auto format : kFormats) {
+ // shallow copy, using pNext from pImageInfo directly.
+ auto createInfo = *pImageInfo;
+ createInfo.format = format;
+ formatInfos.push_back(VkImageFormatConstraintsInfoFUCHSIA{
+ .sType =
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .imageCreateInfo = createInfo,
+ .colorSpaceCount = 1,
+ .pColorSpaces = &kDefaultColorSpace,
+ });
+ }
+ } else {
+ formatInfos.push_back(VkImageFormatConstraintsInfoFUCHSIA{
+ .sType =
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .imageCreateInfo = *pImageInfo,
+ .colorSpaceCount = 1,
+ .pColorSpaces = &kDefaultColorSpace,
+ });
+ }
+
+ VkImageConstraintsInfoFUCHSIA imageConstraints = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .formatConstraintsCount = static_cast<uint32_t>(formatInfos.size()),
+ .pFormatConstraints = formatInfos.data(),
+ .bufferCollectionConstraints =
+ VkBufferCollectionConstraintsInfoFUCHSIA{
+ .sType =
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .minBufferCount = 1,
+ .maxBufferCount = 0,
+ .minBufferCountForCamping = 0,
+ .minBufferCountForDedicatedSlack = 0,
+ .minBufferCountForSharedSlack = 0,
+ },
+ .flags = 0u,
+ };
+
+ return setBufferCollectionImageConstraintsFUCHSIA(
+ enc, device, collection, &imageConstraints);
+ }
+
+ VkResult setBufferCollectionConstraintsFUCHSIAX(
+ VkEncoder* enc,
+ VkDevice device,
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* collection,
const VkImageCreateInfo* pImageInfo) {
if (pImageInfo == nullptr) {
@@ -2318,20 +2498,21 @@
imageConstraints.minBufferCountForSharedSlack = 0;
imageConstraints.flags = 0u;
- return setBufferCollectionImageConstraints(enc, device, collection,
- &imageConstraints);
+ return setBufferCollectionImageConstraintsFUCHSIAX(
+ enc, device, collection, &imageConstraints);
}
- VkResult addImageBufferCollectionConstraints(
+ VkResult addImageBufferCollectionConstraintsFUCHSIA(
VkEncoder* enc,
VkDevice device,
VkPhysicalDevice physicalDevice,
- const VkImageCreateInfo* createInfo,
- const VkImageFormatConstraintsInfoFUCHSIAX* formatConstraints,
+ const VkImageFormatConstraintsInfoFUCHSIA*
+ formatConstraints, // always non-zero
VkImageTiling tiling,
fuchsia_sysmem::wire::BufferCollectionConstraints* constraints) {
// First check if the format, tiling and usage is supported on host.
VkImageFormatProperties imageFormatProperties;
+ auto createInfo = &formatConstraints->imageCreateInfo;
auto result = enc->vkGetPhysicalDeviceImageFormatProperties(
physicalDevice, createInfo->format, createInfo->imageType, tiling,
createInfo->usage, createInfo->flags, &imageFormatProperties,
@@ -2350,7 +2531,7 @@
}
// Check if format constraints contains unsupported format features.
- if (formatConstraints) {
+ {
VkFormatProperties formatProperties;
enc->vkGetPhysicalDeviceFormatProperties(
physicalDevice, createInfo->format, &formatProperties,
@@ -2376,15 +2557,15 @@
}
fuchsia_sysmem::wire::ImageFormatConstraints imageConstraints;
- if (formatConstraints && formatConstraints->sysmemFormat != 0) {
+ if (formatConstraints->sysmemPixelFormat != 0) {
auto pixelFormat =
static_cast<fuchsia_sysmem::wire::PixelFormatType>(
- formatConstraints->sysmemFormat);
+ formatConstraints->sysmemPixelFormat);
if (createInfo->format != VK_FORMAT_UNDEFINED &&
!vkFormatMatchesSysmemFormat(createInfo->format, pixelFormat)) {
ALOGW("%s: VkFormat %u doesn't match sysmem pixelFormat %lu",
__func__, static_cast<uint32_t>(createInfo->format),
- formatConstraints->sysmemFormat);
+ formatConstraints->sysmemPixelFormat);
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
imageConstraints.pixel_format.type = pixelFormat;
@@ -2399,18 +2580,12 @@
imageConstraints.pixel_format.type = pixel_format;
}
- if (!formatConstraints || formatConstraints->colorSpaceCount == 0u) {
- imageConstraints.color_spaces_count = 1;
+ imageConstraints.color_spaces_count =
+ formatConstraints->colorSpaceCount;
+ for (size_t i = 0; i < formatConstraints->colorSpaceCount; i++) {
imageConstraints.color_space[0].type =
- fuchsia_sysmem::wire::ColorSpaceType::kSrgb;
- } else {
- imageConstraints.color_spaces_count =
- formatConstraints->colorSpaceCount;
- for (size_t i = 0; i < formatConstraints->colorSpaceCount; i++) {
- imageConstraints.color_space[0].type =
- static_cast<fuchsia_sysmem::wire::ColorSpaceType>(
- formatConstraints->pColorSpaces[i].colorSpace);
- }
+ static_cast<fuchsia_sysmem::wire::ColorSpaceType>(
+ formatConstraints->pColorSpaces[i].colorSpace);
}
// Get row alignment from host GPU.
@@ -2452,11 +2627,18 @@
return VK_SUCCESS;
}
- VkResult setBufferCollectionImageConstraints(
+ struct SetBufferCollectionImageConstraintsResult {
+ VkResult result;
+ fuchsia_sysmem::wire::BufferCollectionConstraints constraints;
+ std::vector<uint32_t> createInfoIndex;
+ };
+
+ SetBufferCollectionImageConstraintsResult
+ setBufferCollectionImageConstraintsImpl(
VkEncoder* enc,
VkDevice device,
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
- const VkImageConstraintsInfoFUCHSIAX* pImageConstraintsInfo) {
+ const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
const auto& collection = *pCollection;
if (!pImageConstraintsInfo ||
(pImageConstraintsInfo->sType !=
@@ -2464,21 +2646,28 @@
pImageConstraintsInfo->sType !=
VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA)) {
ALOGE("%s: invalid pImageConstraintsInfo", __func__);
- return VK_ERROR_INITIALIZATION_FAILED;
+ return {VK_ERROR_INITIALIZATION_FAILED};
}
- if (pImageConstraintsInfo->createInfoCount == 0) {
- ALOGE("%s: createInfoCount must be greater than 0", __func__);
- return VK_ERROR_INITIALIZATION_FAILED;
+ if (pImageConstraintsInfo->formatConstraintsCount == 0) {
+ ALOGE("%s: formatConstraintsCount must be greater than 0",
+ __func__);
+ abort();
}
fuchsia_sysmem::wire::BufferCollectionConstraints constraints =
defaultBufferCollectionConstraints(
- /* min_size_bytes */ 0, pImageConstraintsInfo->minBufferCount,
- pImageConstraintsInfo->maxBufferCount,
- pImageConstraintsInfo->minBufferCountForCamping,
- pImageConstraintsInfo->minBufferCountForDedicatedSlack,
- pImageConstraintsInfo->minBufferCountForSharedSlack);
+ /* min_size_bytes */ 0,
+ pImageConstraintsInfo->bufferCollectionConstraints
+ .minBufferCount,
+ pImageConstraintsInfo->bufferCollectionConstraints
+ .maxBufferCount,
+ pImageConstraintsInfo->bufferCollectionConstraints
+ .minBufferCountForCamping,
+ pImageConstraintsInfo->bufferCollectionConstraints
+ .minBufferCountForDedicatedSlack,
+ pImageConstraintsInfo->bufferCollectionConstraints
+ .minBufferCountForSharedSlack);
std::vector<fuchsia_sysmem::wire::ImageFormatConstraints>
format_constraints;
@@ -2488,7 +2677,7 @@
AutoLock<RecursiveLock> lock(mLock);
auto deviceIt = info_VkDevice.find(device);
if (deviceIt == info_VkDevice.end()) {
- return VK_ERROR_INITIALIZATION_FAILED;
+ return {VK_ERROR_INITIALIZATION_FAILED};
}
physicalDevice = deviceIt->second.physdev;
}
@@ -2496,19 +2685,18 @@
std::vector<uint32_t> createInfoIndex;
bool hasOptimalTiling = false;
- for (uint32_t i = 0; i < pImageConstraintsInfo->createInfoCount; i++) {
+ for (uint32_t i = 0; i < pImageConstraintsInfo->formatConstraintsCount;
+ i++) {
const VkImageCreateInfo* createInfo =
- &pImageConstraintsInfo->pCreateInfos[i];
- const VkImageFormatConstraintsInfoFUCHSIAX* formatConstraints =
- pImageConstraintsInfo->pFormatConstraints
- ? &pImageConstraintsInfo->pFormatConstraints[i]
- : nullptr;
+ &pImageConstraintsInfo->pFormatConstraints[i].imageCreateInfo;
+ const VkImageFormatConstraintsInfoFUCHSIA* formatConstraints =
+ &pImageConstraintsInfo->pFormatConstraints[i];
// add ImageFormatConstraints for *optimal* tiling
VkResult optimalResult = VK_ERROR_FORMAT_NOT_SUPPORTED;
if (createInfo->tiling == VK_IMAGE_TILING_OPTIMAL) {
- optimalResult = addImageBufferCollectionConstraints(
- enc, device, physicalDevice, createInfo, formatConstraints,
+ optimalResult = addImageBufferCollectionConstraintsFUCHSIA(
+ enc, device, physicalDevice, formatConstraints,
VK_IMAGE_TILING_OPTIMAL, &constraints);
if (optimalResult == VK_SUCCESS) {
createInfoIndex.push_back(i);
@@ -2517,8 +2705,8 @@
}
// Add ImageFormatConstraints for *linear* tiling
- VkResult linearResult = addImageBufferCollectionConstraints(
- enc, device, physicalDevice, createInfo, formatConstraints,
+ VkResult linearResult = addImageBufferCollectionConstraintsFUCHSIA(
+ enc, device, physicalDevice, formatConstraints,
VK_IMAGE_TILING_LINEAR, &constraints);
if (linearResult == VK_SUCCESS) {
createInfoIndex.push_back(i);
@@ -2541,15 +2729,14 @@
// Set buffer memory constraints based on optimal/linear tiling support
// and flags.
- VkImageConstraintsInfoFlagsFUCHSIAX flags =
- pImageConstraintsInfo->flags;
- if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIAX)
+ VkImageConstraintsInfoFlagsFUCHSIA flags = pImageConstraintsInfo->flags;
+ if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA)
constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageRead;
- if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIAX)
+ if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA)
constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageReadOften;
- if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIAX)
+ if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA)
constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWrite;
- if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIAX)
+ if (flags & VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA)
constraints.usage.cpu |= fuchsia_sysmem::wire::kCpuUsageWriteOften;
constraints.has_buffer_memory_constraints = true;
@@ -2558,10 +2745,10 @@
memory_constraints.ram_domain_supported = true;
memory_constraints.inaccessible_domain_supported =
hasOptimalTiling &&
- !(flags & (VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIAX |
- VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIAX |
- VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIAX |
- VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIAX));
+ !(flags & (VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA |
+ VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA |
+ VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA |
+ VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA));
if (memory_constraints.inaccessible_domain_supported) {
memory_constraints.heap_permitted_count = 2;
@@ -2578,7 +2765,7 @@
if (constraints.image_format_constraints_count == 0) {
ALOGE("%s: none of the specified formats is supported by device",
__func__);
- return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ return {VK_ERROR_FORMAT_NOT_SUPPORTED};
}
constexpr uint32_t kVulkanPriority = 5;
@@ -2589,7 +2776,121 @@
if (!result.ok()) {
ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
result.status());
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return {VK_ERROR_INITIALIZATION_FAILED};
+ }
+
+ return {VK_SUCCESS, constraints, std::move(createInfoIndex)};
+ }
+
+ VkResult setBufferCollectionImageConstraintsFUCHSIA(
+ VkEncoder* enc,
+ VkDevice device,
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
+ const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
+ const auto& collection = *pCollection;
+
+ auto setConstraintsResult = setBufferCollectionImageConstraintsImpl(
+ enc, device, pCollection, pImageConstraintsInfo);
+ if (setConstraintsResult.result != VK_SUCCESS) {
+ return setConstraintsResult.result;
+ }
+
+ // copy constraints to info_VkBufferCollectionFUCHSIA if
+ // |collection| is a valid VkBufferCollectionFUCHSIA handle.
+ AutoLock<RecursiveLock> lock(mLock);
+ VkBufferCollectionFUCHSIA buffer_collection =
+ reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
+ if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
+ info_VkBufferCollectionFUCHSIA.end()) {
+ info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
+ android::base::makeOptional(
+ std::move(setConstraintsResult.constraints));
+ info_VkBufferCollectionFUCHSIA[buffer_collection].createInfoIndex =
+ std::move(setConstraintsResult.createInfoIndex);
+ }
+
+ return VK_SUCCESS;
+ }
+
+ VkResult setBufferCollectionImageConstraintsFUCHSIAX(
+ VkEncoder* enc,
+ VkDevice device,
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
+ const VkImageConstraintsInfoFUCHSIAX* pImageConstraintsInfo) {
+ const auto& collection = *pCollection;
+
+ const VkSysmemColorSpaceFUCHSIA kDefaultColorSpace = {
+ .sType = VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA,
+ .pNext = nullptr,
+ .colorSpace = static_cast<uint32_t>(
+ fuchsia_sysmem::wire::ColorSpaceType::kSrgb),
+ };
+
+ std::vector<VkImageFormatConstraintsInfoFUCHSIA> formatConstraints;
+ for (size_t i = 0; i < pImageConstraintsInfo->createInfoCount; i++) {
+ VkImageFormatConstraintsInfoFUCHSIA constraints = {
+ .sType =
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .imageCreateInfo = pImageConstraintsInfo->pCreateInfos[i],
+ .requiredFormatFeatures = {},
+ .flags = {},
+ .sysmemPixelFormat = 0u,
+ .colorSpaceCount = 1u,
+ .pColorSpaces = &kDefaultColorSpace,
+ };
+
+ if (pImageConstraintsInfo->pFormatConstraints) {
+ const auto* formatConstraintsFUCHSIAX =
+ &pImageConstraintsInfo->pFormatConstraints[i];
+ constraints.pNext = formatConstraintsFUCHSIAX->pNext;
+ constraints.requiredFormatFeatures =
+ formatConstraintsFUCHSIAX->requiredFormatFeatures;
+ constraints.flags =
+ reinterpret_cast<VkImageFormatConstraintsFlagsFUCHSIA>(
+ formatConstraintsFUCHSIAX->flags);
+ constraints.sysmemPixelFormat =
+ formatConstraintsFUCHSIAX->sysmemFormat;
+ constraints.colorSpaceCount =
+ formatConstraintsFUCHSIAX->colorSpaceCount > 0
+ ? formatConstraintsFUCHSIAX->colorSpaceCount
+ : 1;
+ // VkSysmemColorSpaceFUCHSIA and VkSysmemColorSpaceFUCHSIAX have
+ // identical definitions so we can just do a reinterpret_cast.
+ constraints.pColorSpaces =
+ formatConstraintsFUCHSIAX->colorSpaceCount > 0
+ ? reinterpret_cast<const VkSysmemColorSpaceFUCHSIA*>(
+ formatConstraintsFUCHSIAX->pColorSpaces)
+ : &kDefaultColorSpace;
+ }
+ formatConstraints.push_back(constraints);
+ }
+
+ VkImageConstraintsInfoFUCHSIA imageConstraintsInfoFUCHSIA = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = pImageConstraintsInfo->pNext,
+ .formatConstraintsCount = pImageConstraintsInfo->createInfoCount,
+ .pFormatConstraints = formatConstraints.data(),
+ .bufferCollectionConstraints =
+ VkBufferCollectionConstraintsInfoFUCHSIA{
+ .sType = VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .minBufferCount = pImageConstraintsInfo->minBufferCount,
+ .maxBufferCount = pImageConstraintsInfo->maxBufferCount,
+ .minBufferCountForCamping =
+ pImageConstraintsInfo->minBufferCountForCamping,
+ .minBufferCountForDedicatedSlack =
+ pImageConstraintsInfo->minBufferCountForDedicatedSlack,
+ .minBufferCountForSharedSlack =
+ pImageConstraintsInfo->minBufferCountForSharedSlack,
+ },
+ .flags = pImageConstraintsInfo->flags,
+ };
+
+ auto setConstraintsResult = setBufferCollectionImageConstraintsImpl(
+ enc, device, pCollection, &imageConstraintsInfoFUCHSIA);
+ if (setConstraintsResult.result != VK_SUCCESS) {
+ return setConstraintsResult.result;
}
// copy constraints to info_VkBufferCollectionFUCHSIAX if
@@ -2600,29 +2901,37 @@
if (info_VkBufferCollectionFUCHSIAX.find(buffer_collection) !=
info_VkBufferCollectionFUCHSIAX.end()) {
info_VkBufferCollectionFUCHSIAX[buffer_collection].constraints =
- android::base::makeOptional(std::move(constraints));
+ android::base::makeOptional(
+ std::move(setConstraintsResult.constraints));
info_VkBufferCollectionFUCHSIAX[buffer_collection].createInfoIndex =
- std::move(createInfoIndex);
+ std::move(setConstraintsResult.createInfoIndex);
}
return VK_SUCCESS;
}
- VkResult setBufferCollectionBufferConstraints(
+ struct SetBufferCollectionBufferConstraintsResult {
+ VkResult result;
+ fuchsia_sysmem::wire::BufferCollectionConstraints constraints;
+ };
+
+ SetBufferCollectionBufferConstraintsResult
+ setBufferCollectionBufferConstraintsImpl(
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
- const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
const auto& collection = *pCollection;
if (pBufferConstraintsInfo == nullptr) {
ALOGE(
"setBufferCollectionBufferConstraints: "
"pBufferConstraintsInfo cannot be null.");
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return {VK_ERROR_OUT_OF_DEVICE_MEMORY};
}
fuchsia_sysmem::wire::BufferCollectionConstraints constraints =
defaultBufferCollectionConstraints(
- /* min_size_bytes */ pBufferConstraintsInfo->pBufferCreateInfo->size,
- /* buffer_count */ pBufferConstraintsInfo->minCount);
+ /* min_size_bytes */ pBufferConstraintsInfo->createInfo.size,
+ /* buffer_count */ pBufferConstraintsInfo
+ ->bufferCollectionConstraints.minBufferCount);
constraints.usage.vulkan =
getBufferCollectionConstraintsVulkanBufferUsage(
pBufferConstraintsInfo);
@@ -2635,7 +2944,60 @@
if (!result.ok()) {
ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
result.status());
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return {VK_ERROR_OUT_OF_DEVICE_MEMORY};
+ }
+
+ return {VK_SUCCESS, constraints};
+ }
+
+ VkResult setBufferCollectionBufferConstraintsFUCHSIA(
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ auto setConstraintsResult = setBufferCollectionBufferConstraintsImpl(
+ pCollection, pBufferConstraintsInfo);
+ if (setConstraintsResult.result != VK_SUCCESS) {
+ return setConstraintsResult.result;
+ }
+
+ // copy constraints to info_VkBufferCollectionFUCHSIA if
+ // |collection| is a valid VkBufferCollectionFUCHSIA handle.
+ AutoLock<RecursiveLock> lock(mLock);
+ VkBufferCollectionFUCHSIA buffer_collection =
+ reinterpret_cast<VkBufferCollectionFUCHSIA>(pCollection);
+ if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
+ info_VkBufferCollectionFUCHSIA.end()) {
+ info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
+ android::base::makeOptional(setConstraintsResult.constraints);
+ }
+
+ return VK_SUCCESS;
+ }
+
+ VkResult setBufferCollectionBufferConstraintsFUCHSIAX(
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>* pCollection,
+ const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
+ VkBufferConstraintsInfoFUCHSIA bufferConstraintsInfoFUCHSIA = {
+ .sType = VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = pBufferConstraintsInfo->pNext,
+ .createInfo = *pBufferConstraintsInfo->pBufferCreateInfo,
+ .requiredFormatFeatures =
+ pBufferConstraintsInfo->requiredFormatFeatures,
+ .bufferCollectionConstraints =
+ VkBufferCollectionConstraintsInfoFUCHSIA{
+ .sType = VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .minBufferCount = pBufferConstraintsInfo->minCount,
+ .maxBufferCount = 0,
+ .minBufferCountForCamping = 0,
+ .minBufferCountForDedicatedSlack = 0,
+ .minBufferCountForSharedSlack = 0,
+ },
+ };
+
+ auto setConstraintsResult = setBufferCollectionBufferConstraintsImpl(
+ pCollection, &bufferConstraintsInfoFUCHSIA);
+ if (setConstraintsResult.result != VK_SUCCESS) {
+ return setConstraintsResult.result;
}
// copy constraints to info_VkBufferCollectionFUCHSIAX if
@@ -2646,12 +3008,39 @@
if (info_VkBufferCollectionFUCHSIAX.find(buffer_collection) !=
info_VkBufferCollectionFUCHSIAX.end()) {
info_VkBufferCollectionFUCHSIAX[buffer_collection].constraints =
- android::base::makeOptional(constraints);
+ android::base::makeOptional(setConstraintsResult.constraints);
}
return VK_SUCCESS;
}
+ VkResult on_vkSetBufferCollectionImageConstraintsFUCHSIA(
+ void* context,
+ VkResult,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
+ VkEncoder* enc = (VkEncoder*)context;
+ auto sysmem_collection = reinterpret_cast<
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
+ collection);
+ return setBufferCollectionImageConstraintsFUCHSIA(
+ enc, device, sysmem_collection, pImageConstraintsInfo);
+ }
+
+ VkResult on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ void*,
+ VkResult,
+ VkDevice,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ auto sysmem_collection = reinterpret_cast<
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
+ collection);
+ return setBufferCollectionBufferConstraintsFUCHSIA(
+ sysmem_collection, pBufferConstraintsInfo);
+ }
+
VkResult on_vkSetBufferCollectionConstraintsFUCHSIAX(
void* context,
VkResult,
@@ -2661,7 +3050,8 @@
VkEncoder* enc = (VkEncoder*)context;
auto sysmem_collection = reinterpret_cast<
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
- return setBufferCollectionConstraints(enc, device, sysmem_collection, pImageInfo);
+ return setBufferCollectionConstraintsFUCHSIAX(
+ enc, device, sysmem_collection, pImageInfo);
}
VkResult on_vkSetBufferCollectionImageConstraintsFUCHSIAX(
@@ -2673,7 +3063,7 @@
VkEncoder* enc = (VkEncoder*)context;
auto sysmem_collection = reinterpret_cast<
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
- return setBufferCollectionImageConstraints(
+ return setBufferCollectionImageConstraintsFUCHSIAX(
enc, device, sysmem_collection, pImageConstraintsInfo);
}
@@ -2685,8 +3075,8 @@
const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo) {
auto sysmem_collection = reinterpret_cast<
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(collection);
- return setBufferCollectionBufferConstraints(sysmem_collection,
- pBufferConstraintsInfo);
+ return setBufferCollectionBufferConstraintsFUCHSIAX(
+ sysmem_collection, pBufferConstraintsInfo);
}
VkResult on_vkGetBufferCollectionPropertiesFUCHSIAX(
@@ -2710,6 +3100,239 @@
}
VkResult getBufferCollectionImageCreateInfoIndexLocked(
+ VkBufferCollectionFUCHSIA collection,
+ fuchsia_sysmem::wire::BufferCollectionInfo2& info,
+ uint32_t* outCreateInfoIndex) {
+ if (!info_VkBufferCollectionFUCHSIA[collection]
+ .constraints.hasValue()) {
+ ALOGE("%s: constraints not set", __func__);
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ if (!info.settings.has_image_format_constraints) {
+ // no image format constraints, skip getting createInfoIndex.
+ return VK_SUCCESS;
+ }
+
+ const auto& constraints =
+ *info_VkBufferCollectionFUCHSIA[collection].constraints;
+ const auto& createInfoIndices =
+ info_VkBufferCollectionFUCHSIA[collection].createInfoIndex;
+ const auto& out = info.settings.image_format_constraints;
+ bool foundCreateInfo = false;
+
+ for (size_t imageFormatIndex = 0;
+ imageFormatIndex < constraints.image_format_constraints_count;
+ imageFormatIndex++) {
+ const auto& in =
+ constraints.image_format_constraints[imageFormatIndex];
+ // These checks are sorted in order of how often they're expected to
+ // mismatch, from most likely to least likely. They aren't always
+ // equality comparisons, since sysmem may change some values in
+ // compatible ways on behalf of the other participants.
+ if ((out.pixel_format.type != in.pixel_format.type) ||
+ (out.pixel_format.has_format_modifier !=
+ in.pixel_format.has_format_modifier) ||
+ (out.pixel_format.format_modifier.value !=
+ in.pixel_format.format_modifier.value) ||
+ (out.min_bytes_per_row < in.min_bytes_per_row) ||
+ (out.required_max_coded_width < in.required_max_coded_width) ||
+ (out.required_max_coded_height <
+ in.required_max_coded_height) ||
+ (out.bytes_per_row_divisor % in.bytes_per_row_divisor != 0)) {
+ continue;
+ }
+ // Check if the out colorspaces are a subset of the in color spaces.
+ bool all_color_spaces_found = true;
+ for (uint32_t j = 0; j < out.color_spaces_count; j++) {
+ bool found_matching_color_space = false;
+ for (uint32_t k = 0; k < in.color_spaces_count; k++) {
+ if (out.color_space[j].type == in.color_space[k].type) {
+ found_matching_color_space = true;
+ break;
+ }
+ }
+ if (!found_matching_color_space) {
+ all_color_spaces_found = false;
+ break;
+ }
+ }
+ if (!all_color_spaces_found) {
+ continue;
+ }
+
+ // Choose the first valid format for now.
+ *outCreateInfoIndex = createInfoIndices[imageFormatIndex];
+ return VK_SUCCESS;
+ }
+
+ ALOGE("%s: cannot find a valid image format in constraints", __func__);
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
+ void* context,
+ VkResult,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ VkBufferCollectionPropertiesFUCHSIA* pProperties) {
+ VkEncoder* enc = (VkEncoder*)context;
+ const auto& sysmem_collection = *reinterpret_cast<
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
+ collection);
+
+ auto result = sysmem_collection->WaitForBuffersAllocated();
+ if (!result.ok() || result.Unwrap()->status != ZX_OK) {
+ ALOGE("Failed wait for allocation: %d %d", result.status(),
+ GET_STATUS_SAFE(result, status));
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ fuchsia_sysmem::wire::BufferCollectionInfo2 info =
+ std::move(result.Unwrap()->buffer_collection_info);
+
+ bool is_host_visible =
+ info.settings.buffer_settings.heap ==
+ fuchsia_sysmem::wire::HeapType::kGoldfishHostVisible;
+ bool is_device_local =
+ info.settings.buffer_settings.heap ==
+ fuchsia_sysmem::wire::HeapType::kGoldfishDeviceLocal;
+ if (!is_host_visible && !is_device_local) {
+ ALOGE("buffer collection uses a non-goldfish heap (type 0x%lu)",
+ static_cast<uint64_t>(info.settings.buffer_settings.heap));
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // memoryTypeBits
+ // ====================================================================
+ {
+ AutoLock<RecursiveLock> lock(mLock);
+ auto deviceIt = info_VkDevice.find(device);
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ auto& deviceInfo = deviceIt->second;
+
+ // Device local memory type supported.
+ pProperties->memoryTypeBits = 0;
+ for (uint32_t i = 0; i < deviceInfo.memProps.memoryTypeCount; ++i) {
+ if ((is_device_local &&
+ (deviceInfo.memProps.memoryTypes[i].propertyFlags &
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) ||
+ (is_host_visible &&
+ (deviceInfo.memProps.memoryTypes[i].propertyFlags &
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
+ pProperties->memoryTypeBits |= 1ull << i;
+ }
+ }
+ }
+
+ // bufferCount
+ // ====================================================================
+ pProperties->bufferCount = info.buffer_count;
+
+ auto storeProperties = [this, collection, pProperties]() -> VkResult {
+ // store properties to storage
+ AutoLock<RecursiveLock> lock(mLock);
+ if (info_VkBufferCollectionFUCHSIA.find(collection) ==
+ info_VkBufferCollectionFUCHSIA.end()) {
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ info_VkBufferCollectionFUCHSIA[collection].properties =
+ android::base::makeOptional(*pProperties);
+
+ // We only do a shallow copy so we should remove all pNext pointers.
+ info_VkBufferCollectionFUCHSIA[collection].properties->pNext =
+ nullptr;
+ info_VkBufferCollectionFUCHSIA[collection]
+ .properties->sysmemColorSpaceIndex.pNext = nullptr;
+ return VK_SUCCESS;
+ };
+
+ // The fields below only apply to buffer collections with image formats.
+ if (!info.settings.has_image_format_constraints) {
+ ALOGD("%s: buffer collection doesn't have image format constraints",
+ __func__);
+ return storeProperties();
+ }
+
+ // sysmemFormat
+ // ====================================================================
+
+ pProperties->sysmemPixelFormat = static_cast<uint64_t>(
+ info.settings.image_format_constraints.pixel_format.type);
+
+ // colorSpace
+ // ====================================================================
+ if (info.settings.image_format_constraints.color_spaces_count == 0) {
+ ALOGE(
+ "%s: color space missing from allocated buffer collection "
+ "constraints",
+ __func__);
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+ // Only report first colorspace for now.
+ pProperties->sysmemColorSpaceIndex.colorSpace = static_cast<uint32_t>(
+ info.settings.image_format_constraints.color_space[0].type);
+
+ // createInfoIndex
+ // ====================================================================
+ {
+ AutoLock<RecursiveLock> lock(mLock);
+ auto getIndexResult = getBufferCollectionImageCreateInfoIndexLocked(
+ collection, info, &pProperties->createInfoIndex);
+ if (getIndexResult != VK_SUCCESS) {
+ return getIndexResult;
+ }
+ }
+
+ // formatFeatures
+ // ====================================================================
+ VkPhysicalDevice physicalDevice;
+ {
+ AutoLock<RecursiveLock> lock(mLock);
+ auto deviceIt = info_VkDevice.find(device);
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ physicalDevice = deviceIt->second.physdev;
+ }
+
+ VkFormat vkFormat = sysmemPixelFormatTypeToVk(
+ info.settings.image_format_constraints.pixel_format.type);
+ VkFormatProperties formatProperties;
+ enc->vkGetPhysicalDeviceFormatProperties(
+ physicalDevice, vkFormat, &formatProperties, true /* do lock */);
+ if (is_device_local) {
+ pProperties->formatFeatures =
+ formatProperties.optimalTilingFeatures;
+ }
+ if (is_host_visible) {
+ pProperties->formatFeatures = formatProperties.linearTilingFeatures;
+ }
+
+ // YCbCr properties
+ // ====================================================================
+ // TODO(59804): Implement this correctly when we support YUV pixel
+ // formats in goldfish ICD.
+ 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->suggestedYcbcrModel =
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
+ pProperties->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+ pProperties->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+ pProperties->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+
+ return storeProperties();
+ }
+
+ VkResult getBufferCollectionImageCreateInfoIndexLocked(
VkBufferCollectionFUCHSIAX collection,
fuchsia_sysmem::wire::BufferCollectionInfo2& info,
uint32_t* outCreateInfoIndex) {
@@ -3274,8 +3897,13 @@
vk_find_struct<VkImportAndroidHardwareBufferInfoANDROID>(pAllocateInfo);
#ifdef VK_USE_PLATFORM_FUCHSIA
- const VkImportMemoryBufferCollectionFUCHSIAX*
+ const VkImportMemoryBufferCollectionFUCHSIA*
importBufferCollectionInfoPtr =
+ vk_find_struct<VkImportMemoryBufferCollectionFUCHSIA>(
+ pAllocateInfo);
+
+ const VkImportMemoryBufferCollectionFUCHSIAX*
+ importBufferCollectionInfoPtrX =
vk_find_struct<VkImportMemoryBufferCollectionFUCHSIAX>(
pAllocateInfo);
@@ -3284,6 +3912,7 @@
pAllocateInfo);
#else
const void* importBufferCollectionInfoPtr = nullptr;
+ const void* importBufferCollectionInfoPtrX = nullptr;
const void* importVmoInfoPtr = nullptr;
#endif // VK_USE_PLATFORM_FUCHSIA
@@ -3292,7 +3921,8 @@
bool shouldPassThroughDedicatedAllocInfo =
!exportAllocateInfoPtr && !importAhbInfoPtr &&
- !importBufferCollectionInfoPtr && !importVmoInfoPtr;
+ !importBufferCollectionInfoPtr && !importBufferCollectionInfoPtrX &&
+ !importVmoInfoPtr;
#ifndef VK_USE_PLATFORM_FUCHSIA
shouldPassThroughDedicatedAllocInfo &=
@@ -3301,7 +3931,7 @@
if (!exportAllocateInfoPtr &&
(importAhbInfoPtr || importBufferCollectionInfoPtr ||
- importVmoInfoPtr) &&
+ importBufferCollectionInfoPtrX || importVmoInfoPtr) &&
dedicatedAllocInfoPtr &&
isHostVisibleMemoryTypeIndexForGuest(
&mHostVisibleMemoryVirtInfo, pAllocateInfo->memoryTypeIndex)) {
@@ -3323,6 +3953,7 @@
bool exportVmo = false;
bool importAhb = false;
bool importBufferCollection = false;
+ bool importBufferCollectionX = false;
bool importVmo = false;
(void)exportVmo;
@@ -3349,10 +3980,13 @@
importAhb = true;
} else if (importBufferCollectionInfoPtr) {
importBufferCollection = true;
+ } else if (importBufferCollectionInfoPtrX) {
+ importBufferCollectionX = true;
} else if (importVmoInfoPtr) {
importVmo = true;
}
- bool isImport = importAhb || importBufferCollection || importVmo;
+ bool isImport = importAhb || importBufferCollection ||
+ importBufferCollectionX || importVmo;
if (exportAhb) {
bool hasDedicatedImage = dedicatedAllocInfoPtr &&
@@ -3453,6 +4087,28 @@
vmo_handle = info.buffers[index].vmo.release();
}
+ if (importBufferCollectionX) {
+ const auto& collection = *reinterpret_cast<
+ fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
+ importBufferCollectionInfoPtrX->collection);
+ auto result = collection->WaitForBuffersAllocated();
+ if (!result.ok() || result.Unwrap()->status != ZX_OK) {
+ ALOGE("WaitForBuffersAllocated failed: %d %d", result.status(),
+ GET_STATUS_SAFE(result, status));
+ _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(
+ VK_ERROR_INITIALIZATION_FAILED);
+ }
+ fuchsia_sysmem::wire::BufferCollectionInfo2& info =
+ result.Unwrap()->buffer_collection_info;
+ uint32_t index = importBufferCollectionInfoPtrX->index;
+ if (info.buffer_count < index) {
+ ALOGE("Invalid buffer index: %d %d", index);
+ _RETURN_FAILURE_WITH_DEVICE_MEMORY_REPORT(
+ VK_ERROR_INITIALIZATION_FAILED);
+ }
+ vmo_handle = info.buffers[index].vmo.release();
+ }
+
if (importVmo) {
vmo_handle = importVmoInfoPtr->handle;
}
@@ -3473,15 +4129,25 @@
const VkImageCreateInfo* pImageCreateInfo = nullptr;
- VkBufferConstraintsInfoFUCHSIAX bufferConstraintsInfo = {
+ VkBufferConstraintsInfoFUCHSIA bufferConstraintsInfo = {
.sType =
- VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIAX,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA,
.pNext = nullptr,
- .pBufferCreateInfo = nullptr,
+ .createInfo = {},
.requiredFormatFeatures = 0,
- .minCount = 1,
+ .bufferCollectionConstraints =
+ VkBufferCollectionConstraintsInfoFUCHSIA{
+ .sType =
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .minBufferCount = 1,
+ .maxBufferCount = 0,
+ .minBufferCountForCamping = 0,
+ .minBufferCountForDedicatedSlack = 0,
+ .minBufferCountForSharedSlack = 0,
+ },
};
- const VkBufferConstraintsInfoFUCHSIAX* pBufferConstraintsInfo =
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo =
nullptr;
if (hasDedicatedImage) {
@@ -3502,8 +4168,7 @@
return VK_ERROR_INITIALIZATION_FAILED;
const auto& bufferInfo = it->second;
- bufferConstraintsInfo.pBufferCreateInfo =
- &bufferInfo.createInfo;
+ bufferConstraintsInfo.createInfo = bufferInfo.createInfo;
pBufferConstraintsInfo = &bufferConstraintsInfo;
}
@@ -3553,7 +4218,8 @@
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection> collection(
std::move(collection_ends->client));
if (hasDedicatedImage) {
- VkResult res = setBufferCollectionConstraints(
+ // TODO(fxbug.dev/90856): Use setBufferCollectionImageConstraintsFUCHSIA.
+ VkResult res = setBufferCollectionConstraintsFUCHSIA(
enc, device, &collection, pImageCreateInfo);
if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
ALOGE("setBufferCollectionConstraints failed: format %u is not supported",
@@ -3567,7 +4233,7 @@
}
if (hasDedicatedBuffer) {
- VkResult res = setBufferCollectionBufferConstraints(
+ VkResult res = setBufferCollectionBufferConstraintsFUCHSIA(
&collection, pBufferConstraintsInfo);
if (res != VK_SUCCESS) {
ALOGE("setBufferCollectionBufferConstraints failed: %d",
@@ -3692,10 +4358,11 @@
if (pBufferConstraintsInfo) {
fidl::Arena arena;
fuchsia_hardware_goldfish::wire::CreateBuffer2Params createParams(arena);
- createParams.set_size(arena,
- pBufferConstraintsInfo->pBufferCreateInfo->size)
- .set_memory_property(
- fuchsia_hardware_goldfish::wire::kMemoryPropertyDeviceLocal);
+ createParams
+ .set_size(arena,
+ pBufferConstraintsInfo->createInfo.size)
+ .set_memory_property(fuchsia_hardware_goldfish::wire::
+ kMemoryPropertyDeviceLocal);
auto result =
mControlDevice->CreateBuffer2(std::move(vmo_copy), std::move(createParams));
@@ -4235,10 +4902,16 @@
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
- const VkBufferCollectionImageCreateInfoFUCHSIAX*
- extBufferCollectionPtr =
+ const VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
+ vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIA>(
+ pCreateInfo);
+
+ if (!extBufferCollectionPtr) {
+ extBufferCollectionPtr = reinterpret_cast<
+ const VkBufferCollectionImageCreateInfoFUCHSIA*>(
vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIAX>(
- pCreateInfo);
+ pCreateInfo));
+ }
bool isSysmemBackedMemory = false;
if (extImgCiPtr &&
@@ -5310,9 +5983,16 @@
}
const auto* extBufferCollectionPtr =
- vk_find_struct<VkBufferCollectionBufferCreateInfoFUCHSIAX>(
+ vk_find_struct<VkBufferCollectionBufferCreateInfoFUCHSIA>(
pCreateInfo);
+ if (extBufferCollectionPtr == nullptr) {
+ extBufferCollectionPtr = reinterpret_cast<
+ const VkBufferCollectionBufferCreateInfoFUCHSIA*>(
+ vk_find_struct<VkBufferCollectionBufferCreateInfoFUCHSIAX>(
+ pCreateInfo));
+ }
+
if (extBufferCollectionPtr) {
const auto& collection = *reinterpret_cast<
fidl::WireSyncClient<fuchsia_sysmem::BufferCollection>*>(
@@ -7754,6 +8434,57 @@
context, input_result, device, pInfo);
}
+VkResult ResourceTracker::on_vkCreateBufferCollectionFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkBufferCollectionCreateInfoFUCHSIA* pInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBufferCollectionFUCHSIA* pCollection) {
+ return mImpl->on_vkCreateBufferCollectionFUCHSIA(
+ context, input_result, device, pInfo, pAllocator, pCollection);
+}
+
+void ResourceTracker::on_vkDestroyBufferCollectionFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkAllocationCallbacks* pAllocator) {
+ return mImpl->on_vkDestroyBufferCollectionFUCHSIA(
+ context, input_result, device, collection, pAllocator);
+}
+
+VkResult ResourceTracker::on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferDConstraintsInfo) {
+ return mImpl->on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ context, input_result, device, collection, pBufferDConstraintsInfo);
+}
+
+VkResult ResourceTracker::on_vkSetBufferCollectionImageConstraintsFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo) {
+ return mImpl->on_vkSetBufferCollectionImageConstraintsFUCHSIA(
+ context, input_result, device, collection, pImageConstraintsInfo);
+}
+
+VkResult ResourceTracker::on_vkGetBufferCollectionPropertiesFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ VkBufferCollectionPropertiesFUCHSIA* pProperties) {
+ return mImpl->on_vkGetBufferCollectionPropertiesFUCHSIA(
+ context, input_result, device, collection, pProperties);
+}
+
VkResult ResourceTracker::on_vkCreateBufferCollectionFUCHSIAX(
void* context,
VkResult input_result,