fuchsia: Allow exporting host-visible dedicated VkDeviceMemory.
Since now we have host-visible memory support, we can allocate
dedicated VkDeviceMemory and export them into VMO now. This change
adds supports to allocate and export dedicated VkDeviceMemory
with host-visible memoryTypeBits.
TEST=vkext_unprotected (VulkanExtension.ExternalMemoryFuchsia)
Change-Id: I23872e5c046e2de60aee61a516effad4b1dd6ff8
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index e18e522..0376bb7 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1732,10 +1732,21 @@
VkExternalMemoryHandleTypeFlagBits handleType,
uint32_t handle,
VkMemoryZirconHandlePropertiesFUCHSIA* pProperties) {
+ using llcpp::fuchsia::hardware::goldfish::MEMORY_PROPERTY_DEVICE_LOCAL;
+ using llcpp::fuchsia::hardware::goldfish::MEMORY_PROPERTY_HOST_VISIBLE;
+
if (handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA) {
return VK_ERROR_INITIALIZATION_FAILED;
}
+ zx_info_handle_basic_t handleInfo;
+ zx_status_t status = zx::unowned_vmo(handle)->get_info(
+ ZX_INFO_HANDLE_BASIC, &handleInfo, sizeof(handleInfo), nullptr,
+ nullptr);
+ if (status != ZX_OK || handleInfo.type != ZX_OBJ_TYPE_VMO) {
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
AutoLock lock(mLock);
auto deviceIt = info_VkDevice.find(device);
@@ -1746,11 +1757,44 @@
auto& info = deviceIt->second;
- // Device local memory type supported.
+ zx::vmo vmo_dup;
+ status =
+ zx::unowned_vmo(handle)->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_dup);
+ if (status != ZX_OK) {
+ ALOGE("zx_handle_duplicate() error: %d", status);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ uint32_t memoryProperty = 0u;
+
+ auto result = mControlDevice->GetBufferHandleInfo(std::move(vmo_dup));
+ if (!result.ok()) {
+ ALOGE(
+ "mControlDevice->GetBufferHandleInfo fatal error: epitaph: %d",
+ result.status());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ if (result->result.is_response()) {
+ memoryProperty = result->result.response().info.memory_property();
+ } else if (result->result.err() == ZX_ERR_NOT_FOUND) {
+ // If an VMO is allocated while ColorBuffer/Buffer is not created,
+ // it must be a device-local buffer, since for host-visible buffers,
+ // ColorBuffer/Buffer is created at sysmem allocation time.
+ memoryProperty = MEMORY_PROPERTY_DEVICE_LOCAL;
+ } else {
+ ALOGE("mControlDevice->GetBufferHandleInfo error: %d",
+ result->result.err());
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
pProperties->memoryTypeBits = 0;
for (uint32_t i = 0; i < info.memProps.memoryTypeCount; ++i) {
- if (info.memProps.memoryTypes[i].propertyFlags &
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+ if (((memoryProperty & MEMORY_PROPERTY_DEVICE_LOCAL) &&
+ (info.memProps.memoryTypes[i].propertyFlags &
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) ||
+ ((memoryProperty & MEMORY_PROPERTY_HOST_VISIBLE) &&
+ (info.memProps.memoryTypes[i].propertyFlags &
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
pProperties->memoryTypeBits |= 1ull << i;
}
}
@@ -2972,24 +3016,26 @@
vk_find_struct<VkMemoryDedicatedAllocateInfo>(pAllocateInfo);
bool shouldPassThroughDedicatedAllocInfo =
- !exportAllocateInfoPtr &&
- !importAhbInfoPtr &&
- !importBufferCollectionInfoPtr &&
- !importVmoInfoPtr &&
+ !exportAllocateInfoPtr && !importAhbInfoPtr &&
+ !importBufferCollectionInfoPtr && !importVmoInfoPtr;
+
+#ifndef VK_USE_PLATFORM_FUCHSIA
+ shouldPassThroughDedicatedAllocInfo &=
!isHostVisibleMemoryTypeIndexForGuest(
- &mHostVisibleMemoryVirtInfo,
- pAllocateInfo->memoryTypeIndex);
+ &mHostVisibleMemoryVirtInfo, pAllocateInfo->memoryTypeIndex);
if (!exportAllocateInfoPtr &&
- (importAhbInfoPtr || importBufferCollectionInfoPtr || importVmoInfoPtr) &&
+ (importAhbInfoPtr || importBufferCollectionInfoPtr ||
+ importVmoInfoPtr) &&
dedicatedAllocInfoPtr &&
isHostVisibleMemoryTypeIndexForGuest(
- &mHostVisibleMemoryVirtInfo,
- pAllocateInfo->memoryTypeIndex)) {
- ALOGE("FATAL: It is not yet supported to import-allocate "
- "external memory that is both host visible and dedicated.");
+ &mHostVisibleMemoryVirtInfo, pAllocateInfo->memoryTypeIndex)) {
+ ALOGE(
+ "FATAL: It is not yet supported to import-allocate "
+ "external memory that is both host visible and dedicated.");
abort();
}
+#endif // VK_USE_PLATFORM_FUCHSIA
if (shouldPassThroughDedicatedAllocInfo &&
dedicatedAllocInfoPtr) {
@@ -3287,78 +3333,96 @@
abort();
}
- if (pImageCreateInfo) {
- llcpp::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 = llcpp::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 = llcpp::fuchsia::hardware::goldfish::
- ColorBufferFormatType::RGBA;
- break;
- case VK_FORMAT_R8_UNORM:
- case VK_FORMAT_R8_UINT:
- case VK_FORMAT_R8_USCALED:
- case VK_FORMAT_R8_SNORM:
- case VK_FORMAT_R8_SINT:
- case VK_FORMAT_R8_SSCALED:
- case VK_FORMAT_R8_SRGB:
- format = llcpp::fuchsia::hardware::goldfish::ColorBufferFormatType::
- LUMINANCE;
- break;
- case VK_FORMAT_R8G8_UNORM:
- case VK_FORMAT_R8G8_UINT:
- case VK_FORMAT_R8G8_USCALED:
- case VK_FORMAT_R8G8_SNORM:
- case VK_FORMAT_R8G8_SINT:
- case VK_FORMAT_R8G8_SSCALED:
- case VK_FORMAT_R8G8_SRGB:
- format = llcpp::fuchsia::hardware::goldfish::ColorBufferFormatType::RG;
- break;
- default:
- ALOGE("Unsupported format: %d",
- pImageCreateInfo->format);
- abort();
- }
+ bool isHostVisible = isHostVisibleMemoryTypeIndexForGuest(
+ &mHostVisibleMemoryVirtInfo,
+ pAllocateInfo->memoryTypeIndex);
- auto createParams =
- llcpp::fuchsia::hardware::goldfish::CreateColorBuffer2Params::Builder(
- std::make_unique<llcpp::fuchsia::hardware::goldfish::
- CreateColorBuffer2Params::Frame>())
- .set_width(std::make_unique<uint32_t>(pImageCreateInfo->extent.width))
- .set_height(std::make_unique<uint32_t>(pImageCreateInfo->extent.height))
- .set_format(std::make_unique<
- llcpp::fuchsia::hardware::goldfish::ColorBufferFormatType>(
- format))
- .set_memory_property(std::make_unique<uint32_t>(
- llcpp::fuchsia::hardware::goldfish::MEMORY_PROPERTY_DEVICE_LOCAL))
- .build();
+ // Only device-local images need to create color buffer; for
+ // host-visible images, the color buffer is already created when
+ // sysmem allocates memory.
+ if (!isHostVisible) {
+ if (pImageCreateInfo) {
+ llcpp::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 = llcpp::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 = llcpp::fuchsia::hardware::goldfish::
+ ColorBufferFormatType::RGBA;
+ break;
+ case VK_FORMAT_R8_UNORM:
+ case VK_FORMAT_R8_UINT:
+ case VK_FORMAT_R8_USCALED:
+ case VK_FORMAT_R8_SNORM:
+ case VK_FORMAT_R8_SINT:
+ case VK_FORMAT_R8_SSCALED:
+ case VK_FORMAT_R8_SRGB:
+ format = llcpp::fuchsia::hardware::goldfish::
+ ColorBufferFormatType::LUMINANCE;
+ break;
+ case VK_FORMAT_R8G8_UNORM:
+ case VK_FORMAT_R8G8_UINT:
+ case VK_FORMAT_R8G8_USCALED:
+ case VK_FORMAT_R8G8_SNORM:
+ case VK_FORMAT_R8G8_SINT:
+ case VK_FORMAT_R8G8_SSCALED:
+ case VK_FORMAT_R8G8_SRGB:
+ format = llcpp::fuchsia::hardware::goldfish::
+ ColorBufferFormatType::RG;
+ break;
+ default:
+ ALOGE("Unsupported format: %d",
+ pImageCreateInfo->format);
+ abort();
+ }
- auto result = mControlDevice->CreateColorBuffer2(std::move(vmo_copy),
- std::move(createParams));
- if (!result.ok() || result.Unwrap()->res != ZX_OK) {
- if (result.ok() &&
- result.Unwrap()->res == ZX_ERR_ALREADY_EXISTS) {
- ALOGD("CreateColorBuffer: color buffer already "
- "exists\n");
- } else {
- ALOGE("CreateColorBuffer failed: %d:%d",
- result.status(),
- GET_STATUS_SAFE(result, res));
- abort();
+ auto createParams =
+ llcpp::fuchsia::hardware::goldfish::
+ CreateColorBuffer2Params::Builder(
+ std::make_unique<
+ llcpp::fuchsia::hardware::goldfish::
+ CreateColorBuffer2Params::Frame>())
+ .set_width(std::make_unique<uint32_t>(
+ pImageCreateInfo->extent.width))
+ .set_height(std::make_unique<uint32_t>(
+ pImageCreateInfo->extent.height))
+ .set_format(
+ std::make_unique<
+ llcpp::fuchsia::hardware::goldfish::
+ ColorBufferFormatType>(format))
+ .set_memory_property(
+ std::make_unique<uint32_t>(
+ llcpp::fuchsia::hardware::goldfish::
+ MEMORY_PROPERTY_DEVICE_LOCAL))
+ .build();
+
+ auto result = mControlDevice->CreateColorBuffer2(
+ std::move(vmo_copy), std::move(createParams));
+ if (!result.ok() || result.Unwrap()->res != ZX_OK) {
+ if (result.ok() &&
+ result.Unwrap()->res == ZX_ERR_ALREADY_EXISTS) {
+ ALOGD(
+ "CreateColorBuffer: color buffer already "
+ "exists\n");
+ } else {
+ ALOGE("CreateColorBuffer failed: %d:%d",
+ result.status(),
+ GET_STATUS_SAFE(result, res));
+ abort();
+ }
}
}
}
@@ -3655,9 +3719,13 @@
uint32_t normalBits) {
uint32_t res = 0;
for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
- if (normalBits & (1 << i) &&
- !isHostVisibleMemoryTypeIndexForGuest(
- &mHostVisibleMemoryVirtInfo, i)) {
+ bool shouldAcceptMemoryIndex = normalBits & (1 << i);
+#ifndef VK_USE_PLATFORM_FUCHSIA
+ shouldAcceptMemoryIndex &= !isHostVisibleMemoryTypeIndexForGuest(
+ &mHostVisibleMemoryVirtInfo, i);
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ if (shouldAcceptMemoryIndex) {
res |= (1 << i);
}
}