[fuchsia] Add R8G8B8A8 external image support. am: 6a2544969b
Change-Id: I985ee2f5d483ef0d04d758dad9bfa563b1228e12
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index c5bf514..2d2e650 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1653,9 +1653,9 @@
delete sysmem_collection;
}
- void setBufferCollectionConstraints(fuchsia::sysmem::BufferCollectionSyncPtr* collection,
- const VkImageCreateInfo* pImageInfo,
- size_t min_size_bytes) {
+ VkResult setBufferCollectionConstraints(fuchsia::sysmem::BufferCollectionSyncPtr* collection,
+ const VkImageCreateInfo* pImageInfo,
+ size_t min_size_bytes) {
fuchsia::sysmem::BufferCollectionConstraints constraints = {};
constraints.usage.vulkan = fuchsia::sysmem::vulkanUsageColorAttachment |
fuchsia::sysmem::vulkanUsageTransferSrc |
@@ -1675,28 +1675,60 @@
buffer_constraints.heap_permitted_count = 1;
buffer_constraints.heap_permitted[0] =
fuchsia::sysmem::HeapType::GOLDFISH_DEVICE_LOCAL;
- constraints.image_format_constraints_count = 1;
- fuchsia::sysmem::ImageFormatConstraints& image_constraints =
- constraints.image_format_constraints[0];
- image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::BGRA32;
- image_constraints.color_spaces_count = 1;
- image_constraints.color_space[0].type = fuchsia::sysmem::ColorSpaceType::SRGB;
- image_constraints.min_coded_width = pImageInfo->extent.width;
- image_constraints.max_coded_width = 0xfffffff;
- image_constraints.min_coded_height = pImageInfo->extent.height;
- image_constraints.max_coded_height = 0xffffffff;
- image_constraints.min_bytes_per_row = pImageInfo->extent.width * 4;
- image_constraints.max_bytes_per_row = 0xffffffff;
- image_constraints.max_coded_width_times_coded_height = 0xffffffff;
- image_constraints.layers = 1;
- image_constraints.coded_width_divisor = 1;
- image_constraints.coded_height_divisor = 1;
- image_constraints.bytes_per_row_divisor = 1;
- image_constraints.start_offset_divisor = 1;
- image_constraints.display_width_divisor = 1;
- image_constraints.display_height_divisor = 1;
+ std::vector<VkFormat> formats{pImageInfo->format};
+ if (pImageInfo->format == VK_FORMAT_UNDEFINED) {
+ // This is a hack to allow the client to say it supports every vulkan format the driver
+ // does. TODO(fxb/13247): Modify this function to take a list of vulkan formats to use.
+ formats = std::vector<VkFormat>{
+ VK_FORMAT_B8G8R8A8_UNORM,
+ VK_FORMAT_R8G8B8A8_UNORM,
+ };
+ }
+ constraints.image_format_constraints_count = formats.size();
+ uint32_t format_index = 0;
+ for (VkFormat format : formats) {
+ fuchsia::sysmem::ImageFormatConstraints& image_constraints =
+ constraints.image_format_constraints[format_index++];
+ switch (format) {
+ case VK_FORMAT_B8G8R8A8_SINT:
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ case VK_FORMAT_B8G8R8A8_SRGB:
+ case VK_FORMAT_B8G8R8A8_SNORM:
+ case VK_FORMAT_B8G8R8A8_SSCALED:
+ case VK_FORMAT_B8G8R8A8_USCALED:
+ image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::BGRA32;
+ break;
+ case VK_FORMAT_R8G8B8A8_SINT:
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ case VK_FORMAT_R8G8B8A8_SNORM:
+ case VK_FORMAT_R8G8B8A8_SSCALED:
+ case VK_FORMAT_R8G8B8A8_USCALED:
+ image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::R8G8B8A8;
+ break;
+ default:
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ }
+ image_constraints.color_spaces_count = 1;
+ image_constraints.color_space[0].type = fuchsia::sysmem::ColorSpaceType::SRGB;
+ image_constraints.min_coded_width = pImageInfo->extent.width;
+ image_constraints.max_coded_width = 0xfffffff;
+ image_constraints.min_coded_height = pImageInfo->extent.height;
+ image_constraints.max_coded_height = 0xffffffff;
+ image_constraints.min_bytes_per_row = pImageInfo->extent.width * 4;
+ image_constraints.max_bytes_per_row = 0xffffffff;
+ image_constraints.max_coded_width_times_coded_height = 0xffffffff;
+ image_constraints.layers = 1;
+ image_constraints.coded_width_divisor = 1;
+ image_constraints.coded_height_divisor = 1;
+ image_constraints.bytes_per_row_divisor = 1;
+ image_constraints.start_offset_divisor = 1;
+ image_constraints.display_width_divisor = 1;
+ image_constraints.display_height_divisor = 1;
+ }
(*collection)->SetConstraints(true, constraints);
+ return VK_SUCCESS;
}
VkResult on_vkSetBufferCollectionConstraintsFUCHSIA(
@@ -1705,10 +1737,9 @@
const VkImageCreateInfo* pImageInfo) {
auto sysmem_collection =
reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
- setBufferCollectionConstraints(
+ return setBufferCollectionConstraints(
sysmem_collection, pImageInfo,
pImageInfo->extent.width * pImageInfo->extent.height * 4);
- return VK_SUCCESS;
}
VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
@@ -2159,9 +2190,13 @@
ALOGE("BindSharedCollection failed: %d", status);
abort();
}
- setBufferCollectionConstraints(&collection,
- &imageCreateInfo,
- finalAllocInfo.allocationSize);
+ VkResult res = setBufferCollectionConstraints(&collection,
+ &imageCreateInfo,
+ finalAllocInfo.allocationSize);
+ if (res != VK_SUCCESS) {
+ ALOGE("setBufferCollectionConstraints failed: %d", res);
+ abort();
+ }
fuchsia::sysmem::BufferCollectionInfo_2 info;
zx_status_t status2;
@@ -2187,13 +2222,35 @@
ALOGE("Failed to duplicate VMO: %d", status);
abort();
}
- // TODO(reveman): Use imageCreateInfo.format to determine color
- // buffer format.
+
+ 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();
+ }
+
status = mControlDevice->CreateColorBuffer(
std::move(vmo_copy),
imageCreateInfo.extent.width,
imageCreateInfo.extent.height,
- fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
+ format,
&status2);
if (status != ZX_OK || status2 != ZX_OK) {
ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
@@ -2601,7 +2658,7 @@
zx_status_t status2;
zx_status_t status = (*collection)->WaitForBuffersAllocated(&status2, &info);
if (status == ZX_OK && status2 == ZX_OK) {
- if (index < info.buffer_count) {
+ if (index < info.buffer_count && info.settings.has_image_format_constraints) {
vmo = std::move(info.buffers[index].vmo);
}
} else {
@@ -2612,9 +2669,11 @@
zx_status_t status2 = ZX_OK;
status = mControlDevice->CreateColorBuffer(
std::move(vmo),
- localCreateInfo.extent.width,
- localCreateInfo.extent.height,
- fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
+ info.settings.image_format_constraints.min_coded_width,
+ info.settings.image_format_constraints.min_coded_height,
+ info.settings.image_format_constraints.pixel_format.type == fuchsia::sysmem::PixelFormatType::R8G8B8A8
+ ? fuchsia::hardware::goldfish::ColorBufferFormatType::RGBA
+ : fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
&status2);
if (status != ZX_OK || (status2 != ZX_OK && status2 != ZX_ERR_ALREADY_EXISTS)) {
ALOGE("CreateColorBuffer failed: %d:%d", status, status2);