Merge changes If668ed31,I5f6df09b
* changes:
fuchsia: Allow exportable dedicated buffer allocation.
fuchsia: Support vkSetBufferCollectionBufferConstraintsFUCHSIA.
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 44071ec..b62ce7b 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -221,6 +221,14 @@
return VK_SUCCESS;
}
+VkResult SetBufferCollectionBufferConstraintsFUCHSIA(
+ VkDevice /*device*/,
+ VkBufferCollectionFUCHSIA /*collection*/,
+ const VkBufferConstraintsInfoFUCHSIA* /*pBufferConstraintsInfo*/) {
+ AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIA");
+ return VK_SUCCESS;
+}
+
VkResult
GetBufferCollectionPropertiesFUCHSIA(VkDevice /*device*/,
VkBufferCollectionFUCHSIA /*collection*/,
@@ -279,6 +287,8 @@
return reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferCollectionFUCHSIA);
if (strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA") == 0)
return reinterpret_cast<PFN_vkVoidFunction>(SetBufferCollectionConstraintsFUCHSIA);
+ if (strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA") == 0)
+ return reinterpret_cast<PFN_vkVoidFunction>(SetBufferCollectionBufferConstraintsFUCHSIA);
if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0)
return reinterpret_cast<PFN_vkVoidFunction>(GetBufferCollectionPropertiesFUCHSIA);
#endif
@@ -554,6 +564,27 @@
}
VKAPI_ATTR
+VkResult SetBufferCollectionBufferConstraintsFUCHSIA(
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ AEMU_SCOPED_TRACE("goldfish_vulkan::SetBufferCollectionBufferConstraintsFUCHSIA");
+
+ VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
+
+ if (!hostSupportsVulkan) {
+ return vkstubhal::SetBufferCollectionBufferConstraintsFUCHSIA(device, collection,
+ pBufferConstraintsInfo);
+ }
+
+ VkResult res =
+ goldfish_vk::ResourceTracker::get()->on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ vkEnc, VK_SUCCESS, device, collection, pBufferConstraintsInfo);
+
+ return res;
+}
+
+VKAPI_ATTR
VkResult GetBufferCollectionPropertiesFUCHSIA(
VkDevice device,
VkBufferCollectionFUCHSIA collection,
@@ -605,6 +636,9 @@
if (!strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA")) {
return (PFN_vkVoidFunction)SetBufferCollectionConstraintsFUCHSIA;
}
+ if (!strcmp(name, "vkSetBufferCollectionBufferConstraintsFUCHSIA")) {
+ return (PFN_vkVoidFunction)SetBufferCollectionBufferConstraintsFUCHSIA;
+ }
if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) {
return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA;
}
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 44da142..e7ff088 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1680,18 +1680,15 @@
delete sysmem_collection;
}
- VkResult setBufferCollectionConstraints(fuchsia::sysmem::BufferCollectionSyncPtr* collection,
- const VkImageCreateInfo* pImageInfo,
- size_t min_size_bytes) {
+ inline fuchsia::sysmem::BufferCollectionConstraints
+ defaultBufferCollectionConstraints(size_t min_size_bytes,
+ size_t buffer_count) {
fuchsia::sysmem::BufferCollectionConstraints constraints = {};
- constraints.usage.vulkan = fuchsia::sysmem::vulkanUsageColorAttachment |
- fuchsia::sysmem::vulkanUsageTransferSrc |
- fuchsia::sysmem::vulkanUsageTransferDst |
- fuchsia::sysmem::vulkanUsageSampled;
- constraints.min_buffer_count = 1;
+ constraints.min_buffer_count = buffer_count;
constraints.has_buffer_memory_constraints = true;
fuchsia::sysmem::BufferMemoryConstraints& buffer_constraints =
constraints.buffer_memory_constraints;
+
buffer_constraints.min_size_bytes = min_size_bytes;
buffer_constraints.max_size_bytes = 0xffffffff;
buffer_constraints.physically_contiguous_required = false;
@@ -1703,6 +1700,72 @@
buffer_constraints.heap_permitted[0] =
fuchsia::sysmem::HeapType::GOLDFISH_DEVICE_LOCAL;
+ return constraints;
+ }
+
+ uint32_t getBufferCollectionConstraintsVulkanImageUsage(
+ const VkImageCreateInfo* pImageInfo) {
+ uint32_t usage = 0u;
+ VkImageUsageFlags imageUsage = pImageInfo->usage;
+
+#define SetUsageBit(USAGE) \
+ if (imageUsage & VK_IMAGE_USAGE_##USAGE##_BIT) { \
+ usage |= fuchsia::sysmem::VULKAN_IMAGE_USAGE_##USAGE; \
+ }
+
+ SetUsageBit(COLOR_ATTACHMENT);
+ SetUsageBit(TRANSFER_SRC);
+ SetUsageBit(TRANSFER_DST);
+ SetUsageBit(SAMPLED);
+
+#undef SetUsageBit
+ return usage;
+ }
+
+ uint32_t getBufferCollectionConstraintsVulkanBufferUsage(
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ uint32_t usage = 0u;
+ VkBufferUsageFlags bufferUsage =
+ pBufferConstraintsInfo->pBufferCreateInfo->usage;
+
+#define SetUsageBit(USAGE) \
+ if (bufferUsage & VK_BUFFER_USAGE_##USAGE##_BIT) { \
+ usage |= fuchsia::sysmem::VULKAN_BUFFER_USAGE_##USAGE; \
+ }
+
+ SetUsageBit(TRANSFER_SRC);
+ SetUsageBit(TRANSFER_DST);
+ SetUsageBit(UNIFORM_TEXEL_BUFFER);
+ SetUsageBit(STORAGE_TEXEL_BUFFER);
+ SetUsageBit(UNIFORM_BUFFER);
+ SetUsageBit(STORAGE_BUFFER);
+ SetUsageBit(INDEX_BUFFER);
+ SetUsageBit(VERTEX_BUFFER);
+ SetUsageBit(INDIRECT_BUFFER);
+
+#undef SetUsageBit
+ return usage;
+ }
+
+ VkResult setBufferCollectionConstraints(
+ fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+ const VkImageCreateInfo* pImageInfo) {
+ if (pImageInfo == nullptr) {
+ ALOGE("setBufferCollectionConstraints: pImageInfo cannot be null.");
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ // TODO(liyl): Currently the size only works for RGBA8 and BGRA8 images.
+ // We should set the size based on its actual format.
+ fuchsia::sysmem::BufferCollectionConstraints constraints =
+ defaultBufferCollectionConstraints(
+ /* min_size_bytes */ pImageInfo->extent.width *
+ pImageInfo->extent.height * 4,
+ /* buffer_count */ 1u);
+
+ constraints.usage.vulkan =
+ getBufferCollectionConstraintsVulkanImageUsage(pImageInfo);
+
// Set image format constraints for VkImage allocation.
if (pImageInfo) {
std::vector<VkFormat> formats{pImageInfo->format};
@@ -1768,17 +1831,49 @@
return VK_SUCCESS;
}
+ VkResult setBufferCollectionBufferConstraints(
+ fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ if (pBufferConstraintsInfo == nullptr) {
+ ALOGE(
+ "setBufferCollectionBufferConstraints: "
+ "pBufferConstraintsInfo cannot be null.");
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ fuchsia::sysmem::BufferCollectionConstraints constraints =
+ defaultBufferCollectionConstraints(
+ /* min_size_bytes */ pBufferConstraintsInfo->pBufferCreateInfo
+ ->size,
+ /* buffer_count */ pBufferConstraintsInfo->minCount);
+ constraints.usage.vulkan =
+ getBufferCollectionConstraintsVulkanBufferUsage(
+ pBufferConstraintsInfo);
+
+ (*collection)->SetConstraints(true, constraints);
+ return VK_SUCCESS;
+ }
+
VkResult on_vkSetBufferCollectionConstraintsFUCHSIA(
void*, VkResult, VkDevice,
VkBufferCollectionFUCHSIA collection,
const VkImageCreateInfo* pImageInfo) {
auto sysmem_collection =
reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
- size_t minSizeBytes = pImageInfo ? pImageInfo->extent.width *
- pImageInfo->extent.height * 4
- : 0u;
- return setBufferCollectionConstraints(sysmem_collection, pImageInfo,
- minSizeBytes);
+ return setBufferCollectionConstraints(sysmem_collection, pImageInfo);
+ }
+
+ VkResult on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ void*,
+ VkResult,
+ VkDevice,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo) {
+ auto sysmem_collection =
+ reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
+ collection);
+ return setBufferCollectionBufferConstraints(sysmem_collection,
+ pBufferConstraintsInfo);
}
VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
@@ -2202,9 +2297,30 @@
if (exportVmo) {
bool hasDedicatedImage = dedicatedAllocInfoPtr &&
(dedicatedAllocInfoPtr->image != VK_NULL_HANDLE);
- VkImageCreateInfo imageCreateInfo = {};
+ bool hasDedicatedBuffer =
+ dedicatedAllocInfoPtr &&
+ (dedicatedAllocInfoPtr->buffer != VK_NULL_HANDLE);
- // TODO(liyl): Handle dedicated buffer allocation as well.
+ if (hasDedicatedImage && hasDedicatedBuffer) {
+ ALOGE(
+ "Invalid VkMemoryDedicatedAllocationInfo: At least one "
+ "of image and buffer must be VK_NULL_HANDLE.");
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ }
+
+ const VkImageCreateInfo* pImageCreateInfo = nullptr;
+
+ VkBufferConstraintsInfoFUCHSIA bufferConstraintsInfo = {
+ .sType =
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA,
+ .pNext = nullptr,
+ .pBufferCreateInfo = nullptr,
+ .requiredFormatFeatures = 0,
+ .minCount = 1,
+ };
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo =
+ nullptr;
+
if (hasDedicatedImage) {
AutoLock lock(mLock);
@@ -2212,13 +2328,31 @@
if (it == info_VkImage.end()) return VK_ERROR_INITIALIZATION_FAILED;
const auto& imageInfo = it->second;
- imageCreateInfo = imageInfo.createInfo;
+ pImageCreateInfo = &imageInfo.createInfo;
}
- if (imageCreateInfo.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
- VK_IMAGE_USAGE_TRANSFER_DST_BIT |
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
- VK_IMAGE_USAGE_SAMPLED_BIT)) {
+ if (hasDedicatedBuffer) {
+ AutoLock lock(mLock);
+
+ auto it = info_VkBuffer.find(dedicatedAllocInfoPtr->buffer);
+ if (it == info_VkBuffer.end())
+ return VK_ERROR_INITIALIZATION_FAILED;
+ const auto& bufferInfo = it->second;
+
+ bufferConstraintsInfo.pBufferCreateInfo =
+ &bufferInfo.createInfo;
+ pBufferConstraintsInfo = &bufferConstraintsInfo;
+ }
+
+ hasDedicatedImage = hasDedicatedImage &&
+ getBufferCollectionConstraintsVulkanImageUsage(
+ pImageCreateInfo);
+ hasDedicatedBuffer =
+ hasDedicatedBuffer &&
+ getBufferCollectionConstraintsVulkanBufferUsage(
+ pBufferConstraintsInfo);
+
+ if (hasDedicatedImage || hasDedicatedBuffer) {
fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
zx_status_t status = mSysmemAllocator->AllocateSharedCollection(
token.NewRequest());
@@ -2234,12 +2368,24 @@
ALOGE("BindSharedCollection failed: %d", status);
abort();
}
- VkResult res = setBufferCollectionConstraints(&collection,
- &imageCreateInfo,
- finalAllocInfo.allocationSize);
- if (res != VK_SUCCESS) {
- ALOGE("setBufferCollectionConstraints failed: %d", res);
- abort();
+
+ if (hasDedicatedImage) {
+ VkResult res = setBufferCollectionConstraints(
+ &collection, pImageCreateInfo);
+ if (res != VK_SUCCESS) {
+ ALOGE("setBufferCollectionConstraints failed: %d", res);
+ abort();
+ }
+ }
+
+ if (hasDedicatedBuffer) {
+ VkResult res = setBufferCollectionBufferConstraints(
+ &collection, pBufferConstraintsInfo);
+ if (res != VK_SUCCESS) {
+ ALOGE("setBufferCollectionBufferConstraints failed: %d",
+ res);
+ abort();
+ }
}
fuchsia::sysmem::BufferCollectionInfo_2 info;
@@ -2267,38 +2413,52 @@
abort();
}
- fuchsia::hardware::goldfish::ColorBufferFormatType format;
- switch (imageCreateInfo.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:
- format = fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA;
- 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:
- format = fuchsia::hardware::goldfish::ColorBufferFormatType::RGBA;
- break;
- default:
- ALOGE("Unsupported format: %d", imageCreateInfo.format);
- abort();
+ if (pImageCreateInfo) {
+ fuchsia::hardware::goldfish::ColorBufferFormatType format;
+ switch (pImageCreateInfo->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:
+ format = fuchsia::hardware::goldfish::
+ ColorBufferFormatType::BGRA;
+ 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:
+ format = fuchsia::hardware::goldfish::
+ ColorBufferFormatType::RGBA;
+ break;
+ default:
+ ALOGE("Unsupported format: %d",
+ pImageCreateInfo->format);
+ abort();
+ }
+
+ status = mControlDevice->CreateColorBuffer(
+ std::move(vmo_copy), pImageCreateInfo->extent.width,
+ pImageCreateInfo->extent.height, format, &status2);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("CreateColorBuffer failed: %d:%d", status,
+ status2);
+ abort();
+ }
}
- status = mControlDevice->CreateColorBuffer(
- std::move(vmo_copy),
- imageCreateInfo.extent.width,
- imageCreateInfo.extent.height,
- format,
- &status2);
- if (status != ZX_OK || status2 != ZX_OK) {
- ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
- abort();
+ if (pBufferConstraintsInfo) {
+ status = mControlDevice->CreateBuffer(
+ std::move(vmo_copy),
+ pBufferConstraintsInfo->pBufferCreateInfo->size,
+ &status2);
+ if (status != ZX_OK || status2 != ZX_OK) {
+ ALOGE("CreateBuffer failed: %d:%d", status, status2);
+ abort();
+ }
}
}
}
@@ -5088,6 +5248,15 @@
context, input_result, device, collection, pImageInfo);
}
+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_vkGetBufferCollectionPropertiesFUCHSIA(
void* context, VkResult input_result,
VkDevice device,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 63cfc41..db33285 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -274,6 +274,12 @@
VkDevice device,
VkBufferCollectionFUCHSIA collection,
const VkImageCreateInfo* pImageInfo);
+ VkResult on_vkSetBufferCollectionBufferConstraintsFUCHSIA(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo);
VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
void* context, VkResult input_result,
VkDevice device,
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index b95517d..e7b0622 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -504,6 +504,14 @@
#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1
#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory"
+typedef struct VkBufferConstraintsInfoFUCHSIA {
+ VkStructureType sType;
+ const void* pNext;
+ const VkBufferCreateInfo* pBufferCreateInfo;
+ VkFormatFeatureFlags requiredFormatFeatures;
+ uint32_t minCount;
+} VkBufferConstraintsInfoFUCHSIA;
+
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
@@ -524,6 +532,8 @@
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetZirconHandleInfoFUCHSIA;
+#define VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA \
+ ((VkStructureType)1001004008)
#define VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA \
((VkStructureType)1001005000)
#define VK_STRUCTURE_TYPE_TEMP_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA \