Implement the VK_KHR_swapchain_mutable_format device extension in the vulkan loader
Add an implementation for the VK_KHR_swapchain_mutable_format extension.
Test: Stepped through changes in debugger
Test: Ran sample app with VVL which used the extension
Test: Ran dEQP-VK.image.swapchain_mutable.android.* dEQP tests
Flag: com.android.graphics.libvulkan.flags.swapchain_mutable_format_ext
Bug: 341978292
Change-Id: Ib0e5b9f750cd5a94ab65419542898db207716fcc
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 436e6c6..4c4e341 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -32,6 +32,18 @@
],
}
+aconfig_declarations {
+ name: "libvulkan_flags",
+ package: "com.android.graphics.libvulkan.flags",
+ container: "system",
+ srcs: ["libvulkan_flags.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "libvulkanflags",
+ aconfig_declarations: "libvulkan_flags",
+}
+
cc_library_shared {
name: "libvulkan",
llndk: {
@@ -113,5 +125,8 @@
"android.hardware.graphics.common@1.0",
"libSurfaceFlingerProp",
],
- static_libs: ["libgrallocusage"],
+ static_libs: [
+ "libgrallocusage",
+ "libvulkanflags",
+ ],
}
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index a3fe33e..9ff0b46 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -25,6 +25,9 @@
#undef VK_NO_PROTOTYPES
#include "api.h"
+/*
+ * This file is autogenerated by api_generator.py. Do not edit directly.
+ */
namespace vulkan {
namespace api {
diff --git a/vulkan/libvulkan/api_gen.h b/vulkan/libvulkan/api_gen.h
index 4998018..b468a89 100644
--- a/vulkan/libvulkan/api_gen.h
+++ b/vulkan/libvulkan/api_gen.h
@@ -25,6 +25,9 @@
#include "driver_gen.h"
+/*
+ * This file is autogenerated by api_generator.py. Do not edit directly.
+ */
namespace vulkan {
namespace api {
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index ef213f0..01436db 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -41,10 +41,12 @@
#include <new>
#include <vector>
+#include <com_android_graphics_libvulkan_flags.h>
#include "stubhal.h"
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
+using namespace com::android::graphics::libvulkan;
extern "C" android_namespace_t* android_get_exported_namespace(const char*);
@@ -688,6 +690,7 @@
case ProcHook::KHR_incremental_present:
case ProcHook::KHR_shared_presentable_image:
case ProcHook::KHR_swapchain:
+ case ProcHook::KHR_swapchain_mutable_format:
case ProcHook::EXT_hdr_metadata:
case ProcHook::EXT_swapchain_maintenance1:
case ProcHook::ANDROID_external_memory_android_hardware_buffer:
@@ -740,6 +743,7 @@
break;
case ProcHook::ANDROID_external_memory_android_hardware_buffer:
case ProcHook::KHR_external_fence_fd:
+ case ProcHook::KHR_swapchain_mutable_format:
case ProcHook::EXTENSION_UNKNOWN:
// Extensions we don't need to do anything about at this level
break;
@@ -1251,6 +1255,15 @@
VK_EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION});
}
+ VkPhysicalDeviceProperties pDeviceProperties;
+ data.driver.GetPhysicalDeviceProperties(physicalDevice, &pDeviceProperties);
+ if (flags::swapchain_mutable_format_ext() &&
+ pDeviceProperties.apiVersion >= VK_API_VERSION_1_2) {
+ loader_extensions.push_back(
+ {VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME,
+ VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION});
+ }
+
// enumerate our extensions first
if (!pLayerName && pProperties) {
uint32_t count = std::min(
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index 8f09008..f741977 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -26,6 +26,9 @@
namespace vulkan {
namespace driver {
+/*
+ * This file is autogenerated by driver_generator.py. Do not edit directly.
+ */
namespace {
// clang-format off
@@ -613,6 +616,7 @@
if (strcmp(name, "VK_KHR_external_semaphore_capabilities") == 0) return ProcHook::KHR_external_semaphore_capabilities;
if (strcmp(name, "VK_KHR_external_fence_capabilities") == 0) return ProcHook::KHR_external_fence_capabilities;
if (strcmp(name, "VK_KHR_external_fence_fd") == 0) return ProcHook::KHR_external_fence_fd;
+ if (strcmp(name, "VK_KHR_swapchain_mutable_format") == 0) return ProcHook::KHR_swapchain_mutable_format;
// clang-format on
return ProcHook::EXTENSION_UNKNOWN;
}
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 4527214..649c0f1 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -26,6 +26,9 @@
#include <optional>
#include <vector>
+/*
+ * This file is autogenerated by driver_generator.py. Do not edit directly.
+ */
namespace vulkan {
namespace driver {
@@ -59,6 +62,7 @@
KHR_external_semaphore_capabilities,
KHR_external_fence_capabilities,
KHR_external_fence_fd,
+ KHR_swapchain_mutable_format,
EXTENSION_CORE_1_0,
EXTENSION_CORE_1_1,
diff --git a/vulkan/libvulkan/libvulkan_flags.aconfig b/vulkan/libvulkan/libvulkan_flags.aconfig
new file mode 100644
index 0000000..891bc02
--- /dev/null
+++ b/vulkan/libvulkan/libvulkan_flags.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.graphics.libvulkan.flags"
+container: "system"
+
+flag {
+ name: "swapchain_mutable_format_ext"
+ namespace: "core_graphics"
+ description: "Enable the VK_KHR_swapchain_mutable_format vulkan extension"
+ bug: "341978292"
+ is_fixed_read_only: true
+}
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 00e987f..0c23cf1 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1465,6 +1465,12 @@
.flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
};
+ // If supporting mutable format swapchain add the mutable format flag
+ if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
+ image_format_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ image_format_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
+ }
+
VkAndroidHardwareBufferUsageANDROID ahb_usage;
ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
ahb_usage.pNext = nullptr;
@@ -1883,6 +1889,11 @@
num_images = 1;
}
+ VkImageFormatListCreateInfo extra_mutable_formats = {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
+ };
+ VkImageFormatListCreateInfo* extra_mutable_formats_ptr;
+
// Look through the create_info pNext chain passed to createSwapchainKHR
// for an image compression control struct.
// if one is found AND the appropriate extensions are enabled, create a
@@ -1901,7 +1912,29 @@
image_compression.pNext = nullptr;
usage_info_pNext = &image_compression;
} break;
-
+ case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: {
+ const VkImageFormatListCreateInfo* format_list =
+ reinterpret_cast<const VkImageFormatListCreateInfo*>(
+ create_infos);
+ if (create_info->flags &
+ VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
+ if (format_list && format_list->viewFormatCount > 0 &&
+ format_list->pViewFormats) {
+ extra_mutable_formats.viewFormatCount =
+ format_list->viewFormatCount;
+ extra_mutable_formats.pViewFormats =
+ format_list->pViewFormats;
+ extra_mutable_formats_ptr = &extra_mutable_formats;
+ } else {
+ ALOGE(
+ "vk_swapchain_create_mutable_format_bit_khr was "
+ "set during swapchain creation but no valid "
+ "vkimageformatlistcreateinfo was found in the "
+ "pnext chain");
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ }
+ } break;
default:
// Ignore all other info structs
break;
@@ -1997,6 +2030,11 @@
.pQueueFamilyIndices = create_info->pQueueFamilyIndices,
};
+ if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
+ image_create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ image_create.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
+ }
+
// Note: don't do deferred allocation for shared present modes. There's only one buffer
// involved so very little benefit.
if ((create_info->flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT) &&
@@ -2006,7 +2044,7 @@
// AcquireNextImage.
VkImageSwapchainCreateInfoKHR image_swapchain_create = {
.sType = VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
- .pNext = nullptr,
+ .pNext = extra_mutable_formats_ptr,
.swapchain = HandleFromSwapchain(swapchain),
};
image_create.pNext = &image_swapchain_create;
@@ -2058,6 +2096,11 @@
ANativeWindowBuffer_getHardwareBuffer(img.buffer.get());
image_create.pNext = &image_native_buffer;
+ if (extra_mutable_formats_ptr) {
+ extra_mutable_formats_ptr->pNext = image_create.pNext;
+ image_create.pNext = extra_mutable_formats_ptr;
+ }
+
ATRACE_BEGIN("CreateImage");
result =
dispatch.CreateImage(device, &image_create, nullptr, &img.image);