summaryrefslogtreecommitdiff
path: root/vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'vulkan')
-rw-r--r--vulkan/api/vulkan.api2
-rw-r--r--vulkan/include/vulkan/vk_android_native_buffer.h12
-rw-r--r--vulkan/libvulkan/api.cpp21
-rw-r--r--vulkan/libvulkan/code-generator.tmpl8
-rw-r--r--vulkan/libvulkan/driver.cpp76
-rw-r--r--vulkan/libvulkan/driver_gen.cpp26
-rw-r--r--vulkan/libvulkan/driver_gen.h3
-rw-r--r--vulkan/libvulkan/layers_extensions.cpp7
-rw-r--r--vulkan/libvulkan/swapchain.cpp257
-rw-r--r--vulkan/libvulkan/swapchain.h2
-rw-r--r--vulkan/vkjson/Android.bp2
11 files changed, 383 insertions, 33 deletions
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 7604c955c6..76503c8c17 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -96,7 +96,7 @@ define NULL_HANDLE 0
@extension("VK_KHR_win32_surface") define VK_KHR_WIN32_SURFACE_NAME "VK_KHR_win32_surface"
// 11
-@extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 7
+@extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 8
@extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_NAME "VK_ANDROID_native_buffer"
// 12
diff --git a/vulkan/include/vulkan/vk_android_native_buffer.h b/vulkan/include/vulkan/vk_android_native_buffer.h
index d3e5f0f6b1..23006fa6be 100644
--- a/vulkan/include/vulkan/vk_android_native_buffer.h
+++ b/vulkan/include/vulkan/vk_android_native_buffer.h
@@ -37,7 +37,17 @@ extern "C" {
* backwards-compatibility support is temporary, and will likely be removed in
* (along with all gralloc0 support) in a future release.
*/
-#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 7
+/* NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 8
+ *
+ * This version of the extension doesn't introduce new types or structs, but is
+ * to accommodate the new struct VkBindImageMemorySwapchainInfoKHR added in
+ * VK_KHR_swapchain spec version 69. When VkBindImageMemorySwapchainInfoKHR is
+ * chained in the pNext chain of VkBindImageMemoryInfo, a VkNativeBufferANDROID
+ * that holds the correct gralloc handle according to the imageIndex specified
+ * in VkBindImageMemorySwapchainInfoKHR will be additionally chained to the
+ * pNext chain of VkBindImageMemoryInfo and passed down to the driver.
+ */
+#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 8
#define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME "VK_ANDROID_native_buffer"
#define VK_ANDROID_NATIVE_BUFFER_ENUM(type,id) ((type)(1000000000 + (1000 * (VK_ANDROID_NATIVE_BUFFER_EXTENSION_NUMBER - 1)) + (id)))
diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp
index 673a066182..71048db920 100644
--- a/vulkan/libvulkan/api.cpp
+++ b/vulkan/libvulkan/api.cpp
@@ -21,6 +21,8 @@
// There are a few of them requiring manual code for things such as layer
// discovery or chaining. They call into functions defined in this file.
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <stdlib.h>
#include <string.h>
@@ -32,6 +34,7 @@
#include <android-base/strings.h>
#include <cutils/properties.h>
#include <log/log.h>
+#include <utils/Trace.h>
#include <vulkan/vk_layer_interface.h>
#include <graphicsenv/GraphicsEnv.h>
@@ -1176,6 +1179,8 @@ bool EnsureInitialized() {
VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance) {
+ ATRACE_CALL();
+
if (!EnsureInitialized())
return VK_ERROR_INITIALIZATION_FAILED;
@@ -1184,6 +1189,8 @@ VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
void DestroyInstance(VkInstance instance,
const VkAllocationCallbacks* pAllocator) {
+ ATRACE_CALL();
+
if (instance != VK_NULL_HANDLE)
LayerChain::DestroyInstance(instance, pAllocator);
}
@@ -1192,17 +1199,23 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkDevice* pDevice) {
+ ATRACE_CALL();
+
return LayerChain::CreateDevice(physicalDevice, pCreateInfo, pAllocator,
pDevice);
}
void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
+ ATRACE_CALL();
+
if (device != VK_NULL_HANDLE)
LayerChain::DestroyDevice(device, pAllocator);
}
VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
VkLayerProperties* pProperties) {
+ ATRACE_CALL();
+
if (!EnsureInitialized())
return VK_ERROR_INITIALIZATION_FAILED;
@@ -1225,6 +1238,8 @@ VkResult EnumerateInstanceExtensionProperties(
const char* pLayerName,
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties) {
+ ATRACE_CALL();
+
if (!EnsureInitialized())
return VK_ERROR_INITIALIZATION_FAILED;
@@ -1253,6 +1268,8 @@ VkResult EnumerateInstanceExtensionProperties(
VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkLayerProperties* pProperties) {
+ ATRACE_CALL();
+
uint32_t count;
const LayerChain::ActiveLayer* layers =
LayerChain::GetActiveLayers(physicalDevice, count);
@@ -1275,6 +1292,8 @@ VkResult EnumerateDeviceExtensionProperties(
const char* pLayerName,
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties) {
+ ATRACE_CALL();
+
if (pLayerName) {
// EnumerateDeviceLayerProperties enumerates active layers for
// backward compatibility. The extension query here should work for
@@ -1302,6 +1321,8 @@ VkResult EnumerateDeviceExtensionProperties(
}
VkResult EnumerateInstanceVersion(uint32_t* pApiVersion) {
+ ATRACE_CALL();
+
*pApiVersion = VK_API_VERSION_1_1;
return VK_SUCCESS;
}
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index f04eb03eac..bdd3573b11 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -703,6 +703,7 @@ VK_KHR_get_surface_capabilities2
{{Macro "driver.InterceptedExtensions"}}
VK_KHR_get_physical_device_properties2
VK_ANDROID_external_memory_android_hardware_buffer
+VK_KHR_bind_memory2
{{end}}
@@ -750,6 +751,9 @@ VK_ANDROID_external_memory_android_hardware_buffer
{{else if eq $.Name "vkGetInstanceProcAddr"}}true
{{else if eq $.Name "vkGetDeviceProcAddr"}}true
+ {{/* VK_KHR_swapchain v69 requirement */}}
+ {{else if eq $.Name "vkBindImageMemory2"}}true
+ {{else if eq $.Name "vkBindImageMemory2KHR"}}true
{{end}}
{{$ext := GetAnnotation $ "extension"}}
@@ -985,6 +989,10 @@ VK_ANDROID_external_memory_android_hardware_buffer
{{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
{{else if eq $.Name "vkGetPhysicalDeviceProperties2"}}true
{{else if eq $.Name "vkGetPhysicalDeviceProperties2KHR"}}true
+
+ {{/* VK_KHR_swapchain v69 requirement */}}
+ {{else if eq $.Name "vkBindImageMemory2"}}true
+ {{else if eq $.Name "vkBindImageMemory2KHR"}}true
{{end}}
{{$ext := GetAnnotation $ "extension"}}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index fdbd969d66..23506bad54 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
@@ -31,6 +33,8 @@
#include <configstore/Utils.h>
#include <cutils/properties.h>
#include <graphicsenv/GraphicsEnv.h>
+#include <utils/Timers.h>
+#include <utils/Trace.h>
#include <utils/Vector.h>
#include "android-base/properties.h"
@@ -150,6 +154,8 @@ Hal Hal::hal_;
void* LoadLibrary(const android_dlextinfo& dlextinfo,
const char* subname,
int subname_len) {
+ ATRACE_CALL();
+
const char kLibFormat[] = "vulkan.%*s.so";
char* name = static_cast<char*>(
alloca(sizeof(kLibFormat) + static_cast<size_t>(subname_len)));
@@ -164,6 +170,8 @@ const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
int LoadDriver(android_namespace_t* library_namespace,
const hwvulkan_module_t** module) {
+ ATRACE_CALL();
+
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
.library_namespace = library_namespace,
@@ -198,20 +206,32 @@ int LoadDriver(android_namespace_t* library_namespace,
}
int LoadBuiltinDriver(const hwvulkan_module_t** module) {
+ ATRACE_CALL();
+
auto ns = android_get_exported_namespace("sphal");
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN);
return LoadDriver(ns, module);
}
int LoadUpdatedDriver(const hwvulkan_module_t** module) {
+ ATRACE_CALL();
+
auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN_UPDATED);
return LoadDriver(ns, module);
}
bool Hal::Open() {
+ ATRACE_CALL();
+
+ const nsecs_t openTime = systemTime();
+
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
// Use a stub device unless we successfully open a real HAL device.
@@ -237,15 +257,22 @@ bool Hal::Open() {
}
}
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
return true;
}
+
hwvulkan_device_t* device;
+ ATRACE_BEGIN("hwvulkan module open");
result =
module->common.methods->open(&module->common, HWVULKAN_DEVICE_0,
reinterpret_cast<hw_device_t**>(&device));
+ ATRACE_END();
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
// Any device with a Vulkan HAL should be able to open the device.
ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
result);
@@ -256,10 +283,15 @@ bool Hal::Open() {
hal_.InitDebugReportIndex();
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, true, systemTime() - openTime);
+
return true;
}
bool Hal::InitDebugReportIndex() {
+ ATRACE_CALL();
+
uint32_t count;
if (dev_->EnumerateInstanceExtensionProperties(nullptr, &count, nullptr) !=
VK_SUCCESS) {
@@ -505,6 +537,7 @@ void CreateInfoWrapper::FilterExtension(const char* name) {
// Extensions we don't need to do anything about at this level
break;
+ case ProcHook::KHR_bind_memory2:
case ProcHook::KHR_incremental_present:
case ProcHook::KHR_shared_presentable_image:
case ProcHook::KHR_swapchain:
@@ -545,6 +578,7 @@ void CreateInfoWrapper::FilterExtension(const char* name) {
// return now as these extensions do not require HAL support
return;
case ProcHook::EXT_hdr_metadata:
+ case ProcHook::KHR_bind_memory2:
hook_extensions_.set(ext_bit);
break;
case ProcHook::ANDROID_external_memory_android_hardware_buffer:
@@ -821,8 +855,10 @@ VkResult EnumerateInstanceExtensionProperties(
}
}
+ ATRACE_BEGIN("driver.EnumerateInstanceExtensionProperties");
VkResult result = Hal::Device().EnumerateInstanceExtensionProperties(
pLayerName, pPropertyCount, pProperties);
+ ATRACE_END();
if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) {
int idx = Hal::Get().GetDebugReportIndex();
@@ -931,8 +967,10 @@ VkResult EnumerateDeviceExtensionProperties(
*pPropertyCount -= count;
}
+ ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
VkResult result = data.driver.EnumerateDeviceExtensionProperties(
physicalDevice, pLayerName, pPropertyCount, pProperties);
+ ATRACE_END();
if (pProperties) {
// map VK_ANDROID_native_buffer to VK_KHR_swapchain
@@ -945,7 +983,12 @@ VkResult EnumerateDeviceExtensionProperties(
memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
- prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
+
+ if (prop.specVersion >= 8) {
+ prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION;
+ } else {
+ prop.specVersion = 68;
+ }
}
}
@@ -968,12 +1011,15 @@ VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
if (result != VK_SUCCESS)
return result;
+ ATRACE_BEGIN("AllocateInstanceData");
InstanceData* data = AllocateInstanceData(data_allocator);
+ ATRACE_END();
if (!data)
return VK_ERROR_OUT_OF_HOST_MEMORY;
data->hook_extensions |= wrapper.GetHookExtensions();
+ ATRACE_BEGIN("autoDowngradeApiVersion");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
uint32_t api_version = ((pCreateInfo->pApplicationInfo)
@@ -984,12 +1030,14 @@ VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
uint32_t icd_api_version;
PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
- Hal::Device().GetInstanceProcAddr(NULL,
+ Hal::Device().GetInstanceProcAddr(nullptr,
"vkEnumerateInstanceVersion"));
if (!pfn_enumerate_instance_version) {
icd_api_version = VK_API_VERSION_1_0;
} else {
+ ATRACE_BEGIN("pfn_enumerate_instance_version");
result = (*pfn_enumerate_instance_version)(&icd_api_version);
+ ATRACE_END();
}
uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
@@ -1000,12 +1048,15 @@ VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
wrapper.DowngradeApiVersion();
}
#pragma clang diagnostic pop
+ ATRACE_END();
// call into the driver
VkInstance instance;
+ ATRACE_BEGIN("driver.CreateInstance");
result = Hal::Device().CreateInstance(
static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator,
&instance);
+ ATRACE_END();
if (result != VK_SUCCESS) {
FreeInstanceData(data, data_allocator);
return result;
@@ -1066,8 +1117,10 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
if (result != VK_SUCCESS)
return result;
+ ATRACE_BEGIN("AllocateDeviceData");
DeviceData* data = AllocateDeviceData(data_allocator,
instance_data.debug_report_callbacks);
+ ATRACE_END();
if (!data)
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -1075,9 +1128,11 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
// call into the driver
VkDevice dev;
+ ATRACE_BEGIN("driver.CreateDevice");
result = instance_data.driver.CreateDevice(
physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper),
pAllocator, &dev);
+ ATRACE_END();
if (result != VK_SUCCESS) {
FreeDeviceData(data, data_allocator);
return result;
@@ -1114,8 +1169,15 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
}
VkPhysicalDeviceProperties properties;
+ ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
&properties);
+ ATRACE_END();
+
+ if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+ // Log that the app is hitting software Vulkan implementation
+ android::GraphicsEnv::getInstance().setCpuVulkanInUse();
+ }
data->driver_device = dev;
data->driver_version = properties.driverVersion;
@@ -1141,6 +1203,8 @@ void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
VkResult EnumeratePhysicalDevices(VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices) {
+ ATRACE_CALL();
+
const auto& data = GetData(instance);
VkResult result = data.driver.EnumeratePhysicalDevices(
@@ -1157,6 +1221,8 @@ VkResult EnumeratePhysicalDeviceGroups(
VkInstance instance,
uint32_t* pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
+ ATRACE_CALL();
+
VkResult result = VK_SUCCESS;
const auto& data = GetData(instance);
@@ -1217,6 +1283,8 @@ void GetDeviceQueue(VkDevice device,
uint32_t queueFamilyIndex,
uint32_t queueIndex,
VkQueue* pQueue) {
+ ATRACE_CALL();
+
const auto& data = GetData(device);
data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
@@ -1226,6 +1294,8 @@ void GetDeviceQueue(VkDevice device,
void GetDeviceQueue2(VkDevice device,
const VkDeviceQueueInfo2* pQueueInfo,
VkQueue* pQueue) {
+ ATRACE_CALL();
+
const auto& data = GetData(device);
data.driver.GetDeviceQueue2(device, pQueueInfo, pQueue);
@@ -1236,6 +1306,8 @@ VKAPI_ATTR VkResult
AllocateCommandBuffers(VkDevice device,
const VkCommandBufferAllocateInfo* pAllocateInfo,
VkCommandBuffer* pCommandBuffers) {
+ ATRACE_CALL();
+
const auto& data = GetData(device);
VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo,
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index ec98b9fe04..574c3273d0 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -137,6 +137,15 @@ VKAPI_ATTR VkResult checkedGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR
}
}
+VKAPI_ATTR VkResult checkedBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfoKHR* pBindInfos) {
+ if (GetData(device).hook_extensions[ProcHook::KHR_bind_memory2]) {
+ return BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
+ } else {
+ Logger(device).Err(device, "VK_KHR_bind_memory2 not enabled. vkBindImageMemory2KHR not executed.");
+ return VK_SUCCESS;
+ }
+}
+
// clang-format on
const ProcHook g_proc_hooks[] = {
@@ -170,6 +179,20 @@ const ProcHook g_proc_hooks[] = {
nullptr,
},
{
+ "vkBindImageMemory2",
+ ProcHook::DEVICE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory2),
+ nullptr,
+ },
+ {
+ "vkBindImageMemory2KHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_bind_memory2,
+ reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory2KHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedBindImageMemory2KHR),
+ },
+ {
"vkCreateAndroidSurfaceKHR",
ProcHook::INSTANCE,
ProcHook::KHR_android_surface,
@@ -458,6 +481,7 @@ ProcHook::Extension GetProcHookExtension(const char* name) {
if (strcmp(name, "VK_KHR_get_surface_capabilities2") == 0) return ProcHook::KHR_get_surface_capabilities2;
if (strcmp(name, "VK_KHR_get_physical_device_properties2") == 0) return ProcHook::KHR_get_physical_device_properties2;
if (strcmp(name, "VK_ANDROID_external_memory_android_hardware_buffer") == 0) return ProcHook::ANDROID_external_memory_android_hardware_buffer;
+ if (strcmp(name, "VK_KHR_bind_memory2") == 0) return ProcHook::KHR_bind_memory2;
// clang-format on
return ProcHook::EXTENSION_UNKNOWN;
}
@@ -517,11 +541,13 @@ bool InitDriverTable(VkDevice dev,
INIT_PROC(true, dev, CreateImage);
INIT_PROC(true, dev, DestroyImage);
INIT_PROC(true, dev, AllocateCommandBuffers);
+ INIT_PROC(false, dev, BindImageMemory2);
INIT_PROC(false, dev, GetDeviceQueue2);
INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
+ INIT_PROC_EXT(KHR_bind_memory2, true, dev, BindImageMemory2KHR);
// clang-format on
return success;
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 14c3aba75a..3faf6c0e32 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -46,6 +46,7 @@ struct ProcHook {
KHR_get_surface_capabilities2,
KHR_get_physical_device_properties2,
ANDROID_external_memory_android_hardware_buffer,
+ KHR_bind_memory2,
EXTENSION_CORE, // valid bit
EXTENSION_COUNT,
@@ -85,11 +86,13 @@ struct DeviceDriverTable {
PFN_vkCreateImage CreateImage;
PFN_vkDestroyImage DestroyImage;
PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
+ PFN_vkBindImageMemory2 BindImageMemory2;
PFN_vkGetDeviceQueue2 GetDeviceQueue2;
PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID;
PFN_vkGetSwapchainGrallocUsage2ANDROID GetSwapchainGrallocUsage2ANDROID;
PFN_vkAcquireImageANDROID AcquireImageANDROID;
PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID;
+ PFN_vkBindImageMemory2KHR BindImageMemory2KHR;
// clang-format on
};
diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp
index a7b7a6f71a..5679412732 100644
--- a/vulkan/libvulkan/layers_extensions.cpp
+++ b/vulkan/libvulkan/layers_extensions.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include "layers_extensions.h"
#include <alloca.h>
@@ -33,6 +35,7 @@
#include <log/log.h>
#include <nativebridge/native_bridge.h>
#include <nativeloader/native_loader.h>
+#include <utils/Trace.h>
#include <ziparchive/zip_archive.h>
// TODO(jessehall): The whole way we deal with extensions is pretty hokey, and
@@ -425,6 +428,8 @@ void ForEachFileInPath(const std::string& path, Functor functor) {
}
void DiscoverLayersInPathList(const std::string& pathstr) {
+ ATRACE_CALL();
+
std::vector<std::string> paths = android::base::Split(pathstr, ":");
for (const auto& path : paths) {
ForEachFileInPath(path, [&](const std::string& filename) {
@@ -474,6 +479,8 @@ void* GetLayerGetProcAddr(const Layer& layer,
} // anonymous namespace
void DiscoverLayers() {
+ ATRACE_CALL();
+
if (property_get_bool("ro.debuggable", false) &&
prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
DiscoverLayersInPathList(kSystemLayerLibraryDir);
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 3db8a3962e..a8949d36f4 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -14,16 +14,21 @@
* limitations under the License.
*/
-#include <algorithm>
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <android/hardware/graphics/common/1.0/types.h>
#include <grallocusage/GrallocUsageConversion.h>
#include <log/log.h>
-#include <ui/BufferQueueDefs.h>
#include <sync/sync.h>
+#include <system/window.h>
+#include <ui/BufferQueueDefs.h>
#include <utils/StrongPointer.h>
+#include <utils/Trace.h>
#include <utils/Vector.h>
-#include <system/window.h>
-#include <android/hardware/graphics/common/1.0/types.h>
+
+#include <algorithm>
+#include <unordered_set>
+#include <vector>
#include "driver.h"
@@ -50,6 +55,22 @@ const VkSurfaceTransformFlagsKHR kSupportedTransforms =
// VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR |
VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
+int TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform) {
+ switch (transform) {
+ // TODO: See TODO in TranslateNativeToVulkanTransform
+ case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
+ return NATIVE_WINDOW_TRANSFORM_ROT_90;
+ case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
+ return NATIVE_WINDOW_TRANSFORM_ROT_180;
+ case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
+ return NATIVE_WINDOW_TRANSFORM_ROT_270;
+ case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
+ case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
+ default:
+ return 0;
+ }
+}
+
VkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransform(int native) {
// Native and Vulkan transforms are isomorphic, but are represented
// differently. Vulkan transforms are built up of an optional horizontal
@@ -205,10 +226,12 @@ enum { MIN_NUM_FRAMES_AGO = 5 };
struct Swapchain {
Swapchain(Surface& surface_,
uint32_t num_images_,
- VkPresentModeKHR present_mode)
+ VkPresentModeKHR present_mode,
+ int pre_transform_)
: surface(surface_),
num_images(num_images_),
mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR),
+ pre_transform(pre_transform_),
frame_timestamps_enabled(false),
shared(present_mode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
present_mode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
@@ -217,10 +240,20 @@ struct Swapchain {
window,
&refresh_duration);
}
+ uint64_t get_refresh_duration()
+ {
+ ANativeWindow* window = surface.window.get();
+ native_window_get_refresh_cycle_duration(
+ window,
+ &refresh_duration);
+ return static_cast<uint64_t>(refresh_duration);
+
+ }
Surface& surface;
uint32_t num_images;
bool mailbox_mode;
+ int pre_transform;
bool frame_timestamps_enabled;
int64_t refresh_duration;
bool shared;
@@ -335,15 +368,15 @@ uint32_t get_num_ready_timings(Swapchain& swapchain) {
swapchain.surface.window.get(), ti.native_frame_id_,
&desired_present_time, &render_complete_time,
&composition_latch_time,
- NULL, //&first_composition_start_time,
- NULL, //&last_composition_start_time,
- NULL, //&composition_finish_time,
+ nullptr, //&first_composition_start_time,
+ nullptr, //&last_composition_start_time,
+ nullptr, //&composition_finish_time,
// TODO(ianelliott): Maybe ask if this one is
// supported, at startup time (since it may not be
// supported):
&actual_present_time,
- NULL, //&dequeue_ready_time,
- NULL /*&reads_done_time*/);
+ nullptr, //&dequeue_ready_time,
+ nullptr /*&reads_done_time*/);
if (ret != android::NO_ERROR) {
continue;
@@ -416,7 +449,7 @@ android_pixel_format GetNativePixelFormat(VkFormat format) {
case VK_FORMAT_R16G16B16A16_SFLOAT:
native_format = HAL_PIXEL_FORMAT_RGBA_FP16;
break;
- case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
native_format = HAL_PIXEL_FORMAT_RGBA_1010102;
break;
default:
@@ -486,6 +519,8 @@ VkResult CreateAndroidSurfaceKHR(
const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* out_surface) {
+ ATRACE_CALL();
+
if (!allocator)
allocator = &GetData(instance).allocator;
void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface),
@@ -528,6 +563,8 @@ VKAPI_ATTR
void DestroySurfaceKHR(VkInstance instance,
VkSurfaceKHR surface_handle,
const VkAllocationCallbacks* allocator) {
+ ATRACE_CALL();
+
Surface* surface = SurfaceFromHandle(surface_handle);
if (!surface)
return;
@@ -548,6 +585,8 @@ VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
uint32_t /*queue_family*/,
VkSurfaceKHR surface_handle,
VkBool32* supported) {
+ ATRACE_CALL();
+
const Surface* surface = SurfaceFromHandle(surface_handle);
if (!surface) {
return VK_ERROR_SURFACE_LOST_KHR;
@@ -569,21 +608,18 @@ VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
switch (native_format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_FP16:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
format_supported = true;
break;
default:
break;
}
- // USAGE_CPU_READ_MASK 0xFUL
- // USAGE_CPU_WRITE_MASK (0xFUL << 4)
- // The currently used bits are as below:
- // USAGE_CPU_READ_RARELY = 2UL
- // USAGE_CPU_READ_OFTEN = 3UL
- // USAGE_CPU_WRITE_RARELY = (2UL << 4)
- // USAGE_CPU_WRITE_OFTEN = (3UL << 4)
- *supported = static_cast<VkBool32>(format_supported ||
- (surface->consumer_usage & 0xFFUL) == 0);
+ *supported = static_cast<VkBool32>(
+ format_supported || (surface->consumer_usage &
+ (AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) == 0);
return VK_SUCCESS;
}
@@ -593,6 +629,8 @@ VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(
VkPhysicalDevice /*pdev*/,
VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR* capabilities) {
+ ATRACE_CALL();
+
int err;
ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
@@ -666,6 +704,8 @@ VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,
VkSurfaceKHR surface_handle,
uint32_t* count,
VkSurfaceFormatKHR* formats) {
+ ATRACE_CALL();
+
const InstanceData& instance_data = GetData(pdev);
// TODO(jessehall): Fill out the set of supported formats. Longer term, add
@@ -678,6 +718,8 @@ VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,
{VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
{VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
{VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
+ {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
+ {VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
};
const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
uint32_t total_num_formats = kNumFormats;
@@ -700,6 +742,12 @@ VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
{VK_FORMAT_R8G8B8A8_SRGB,
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
+ {VK_FORMAT_R16G16B16A16_SFLOAT,
+ VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT},
+ {VK_FORMAT_R16G16B16A16_SFLOAT,
+ VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT},
+ {VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+ VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
};
const uint32_t kNumWideColorFormats =
sizeof(kWideColorFormats) / sizeof(kWideColorFormats[0]);
@@ -734,6 +782,8 @@ VkResult GetPhysicalDeviceSurfaceCapabilities2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
+ ATRACE_CALL();
+
VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR(
physicalDevice, pSurfaceInfo->surface,
&pSurfaceCapabilities->surfaceCapabilities);
@@ -769,6 +819,8 @@ VkResult GetPhysicalDeviceSurfaceFormats2KHR(
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pSurfaceFormatCount,
VkSurfaceFormat2KHR* pSurfaceFormats) {
+ ATRACE_CALL();
+
if (!pSurfaceFormats) {
return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
pSurfaceInfo->surface,
@@ -800,6 +852,8 @@ VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev,
VkSurfaceKHR surface,
uint32_t* count,
VkPresentModeKHR* modes) {
+ ATRACE_CALL();
+
int err;
int query_value;
ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
@@ -851,6 +905,8 @@ VKAPI_ATTR
VkResult GetDeviceGroupPresentCapabilitiesKHR(
VkDevice,
VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) {
+ ATRACE_CALL();
+
ALOGV_IF(pDeviceGroupPresentCapabilities->sType !=
VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR,
"vkGetDeviceGroupPresentCapabilitiesKHR: invalid "
@@ -873,6 +929,8 @@ VkResult GetDeviceGroupSurfacePresentModesKHR(
VkDevice,
VkSurfaceKHR,
VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ ATRACE_CALL();
+
*pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
return VK_SUCCESS;
}
@@ -882,6 +940,8 @@ VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice,
VkSurfaceKHR surface,
uint32_t* pRectCount,
VkRect2D* pRects) {
+ ATRACE_CALL();
+
if (!pRects) {
*pRectCount = 1;
} else {
@@ -923,6 +983,8 @@ VkResult CreateSwapchainKHR(VkDevice device,
const VkSwapchainCreateInfoKHR* create_info,
const VkAllocationCallbacks* allocator,
VkSwapchainKHR* swapchain_handle) {
+ ATRACE_CALL();
+
int err;
VkResult result = VK_SUCCESS;
@@ -1128,7 +1190,9 @@ VkResult CreateSwapchainKHR(VkDevice device,
}
uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
uint32_t num_images =
- (create_info->minImageCount - 1) + min_undequeued_buffers;
+ (swap_interval ? create_info->minImageCount
+ : std::max(3u, create_info->minImageCount)) -
+ 1 + min_undequeued_buffers;
// Lower layer insists that we have at least two buffers. This is wasteful
// and we'd like to relax it in the shared case, but not all the pieces are
@@ -1147,9 +1211,11 @@ VkResult CreateSwapchainKHR(VkDevice device,
int32_t legacy_usage = 0;
if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
uint64_t consumer_usage, producer_usage;
+ ATRACE_BEGIN("dispatch.GetSwapchainGrallocUsage2ANDROID");
result = dispatch.GetSwapchainGrallocUsage2ANDROID(
device, create_info->imageFormat, create_info->imageUsage,
swapchain_image_usage, &consumer_usage, &producer_usage);
+ ATRACE_END();
if (result != VK_SUCCESS) {
ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
return VK_ERROR_SURFACE_LOST_KHR;
@@ -1157,9 +1223,11 @@ VkResult CreateSwapchainKHR(VkDevice device,
legacy_usage =
android_convertGralloc1To0Usage(producer_usage, consumer_usage);
} else if (dispatch.GetSwapchainGrallocUsageANDROID) {
+ ATRACE_BEGIN("dispatch.GetSwapchainGrallocUsageANDROID");
result = dispatch.GetSwapchainGrallocUsageANDROID(
device, create_info->imageFormat, create_info->imageUsage,
&legacy_usage);
+ ATRACE_END();
if (result != VK_SUCCESS) {
ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
return VK_ERROR_SURFACE_LOST_KHR;
@@ -1188,9 +1256,9 @@ VkResult CreateSwapchainKHR(VkDevice device,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!mem)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- Swapchain* swapchain =
- new (mem) Swapchain(surface, num_images, create_info->presentMode);
-
+ Swapchain* swapchain = new (mem)
+ Swapchain(surface, num_images, create_info->presentMode,
+ TranslateVulkanToNativeTransform(create_info->preTransform));
// -- Dequeue all buffers and create a VkImage for each --
// Any failures during or after this must cancel the dequeued buffers.
@@ -1254,8 +1322,10 @@ VkResult CreateSwapchainKHR(VkDevice device,
&image_native_buffer.usage2.producer,
&image_native_buffer.usage2.consumer);
+ ATRACE_BEGIN("dispatch.CreateImage");
result =
dispatch.CreateImage(device, &image_create, nullptr, &img.image);
+ ATRACE_END();
if (result != VK_SUCCESS) {
ALOGD("vkCreateImage w/ native buffer failed: %u", result);
break;
@@ -1279,8 +1349,11 @@ VkResult CreateSwapchainKHR(VkDevice device,
}
}
if (result != VK_SUCCESS) {
- if (img.image)
+ if (img.image) {
+ ATRACE_BEGIN("dispatch.DestroyImage");
dispatch.DestroyImage(device, img.image, nullptr);
+ ATRACE_END();
+ }
}
}
@@ -1299,6 +1372,8 @@ VKAPI_ATTR
void DestroySwapchainKHR(VkDevice device,
VkSwapchainKHR swapchain_handle,
const VkAllocationCallbacks* allocator) {
+ ATRACE_CALL();
+
const auto& dispatch = GetData(device).driver;
Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
if (!swapchain)
@@ -1324,6 +1399,8 @@ VkResult GetSwapchainImagesKHR(VkDevice,
VkSwapchainKHR swapchain_handle,
uint32_t* count,
VkImage* images) {
+ ATRACE_CALL();
+
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
ALOGW_IF(swapchain.surface.swapchain_handle != swapchain_handle,
"getting images for non-active swapchain 0x%" PRIx64
@@ -1352,6 +1429,8 @@ VkResult AcquireNextImageKHR(VkDevice device,
VkSemaphore semaphore,
VkFence vk_fence,
uint32_t* image_index) {
+ ATRACE_CALL();
+
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
ANativeWindow* window = swapchain.surface.window.get();
VkResult result;
@@ -1432,6 +1511,8 @@ VKAPI_ATTR
VkResult AcquireNextImage2KHR(VkDevice device,
const VkAcquireNextImageInfoKHR* pAcquireInfo,
uint32_t* pImageIndex) {
+ ATRACE_CALL();
+
// TODO: this should actually be the other way around and this function
// should handle any additional structures that get passed in
return AcquireNextImageKHR(device, pAcquireInfo->swapchain,
@@ -1461,6 +1542,8 @@ static VkResult WorstPresentResult(VkResult a, VkResult b) {
VKAPI_ATTR
VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
+ ATRACE_CALL();
+
ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
"vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d",
present_info->sType);
@@ -1649,6 +1732,19 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
ReleaseSwapchainImage(device, window, fence, img);
OrphanSwapchain(device, &swapchain);
}
+ int window_transform_hint;
+ err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT,
+ &window_transform_hint);
+ if (err != 0) {
+ ALOGE("NATIVE_WINDOW_TRANSFORM_HINT query failed: %s (%d)",
+ strerror(-err), err);
+ swapchain_result = WorstPresentResult(
+ swapchain_result, VK_ERROR_SURFACE_LOST_KHR);
+ }
+ if (swapchain.pre_transform != window_transform_hint) {
+ swapchain_result =
+ WorstPresentResult(swapchain_result, VK_SUBOPTIMAL_KHR);
+ }
} else {
ReleaseSwapchainImage(device, nullptr, fence, img);
swapchain_result = VK_ERROR_OUT_OF_DATE_KHR;
@@ -1672,11 +1768,12 @@ VkResult GetRefreshCycleDurationGOOGLE(
VkDevice,
VkSwapchainKHR swapchain_handle,
VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
+ ATRACE_CALL();
+
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
VkResult result = VK_SUCCESS;
- pDisplayTimingProperties->refreshDuration =
- static_cast<uint64_t>(swapchain.refresh_duration);
+ pDisplayTimingProperties->refreshDuration = swapchain.get_refresh_duration();
return result;
}
@@ -1687,6 +1784,8 @@ VkResult GetPastPresentationTimingGOOGLE(
VkSwapchainKHR swapchain_handle,
uint32_t* count,
VkPastPresentationTimingGOOGLE* timings) {
+ ATRACE_CALL();
+
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
ANativeWindow* window = swapchain.surface.window.get();
VkResult result = VK_SUCCESS;
@@ -1711,6 +1810,8 @@ VKAPI_ATTR
VkResult GetSwapchainStatusKHR(
VkDevice,
VkSwapchainKHR swapchain_handle) {
+ ATRACE_CALL();
+
Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
VkResult result = VK_SUCCESS;
@@ -1728,6 +1829,7 @@ VKAPI_ATTR void SetHdrMetadataEXT(
uint32_t swapchainCount,
const VkSwapchainKHR* pSwapchains,
const VkHdrMetadataEXT* pHdrMetadataEXTs) {
+ ATRACE_CALL();
for (uint32_t idx = 0; idx < swapchainCount; idx++) {
Swapchain* swapchain = SwapchainFromHandle(pSwapchains[idx]);
@@ -1760,5 +1862,106 @@ VKAPI_ATTR void SetHdrMetadataEXT(
return;
}
+static void InterceptBindImageMemory2(
+ uint32_t bind_info_count,
+ const VkBindImageMemoryInfo* bind_infos,
+ std::vector<VkNativeBufferANDROID>* out_native_buffers,
+ std::vector<VkBindImageMemoryInfo>* out_bind_infos) {
+ out_native_buffers->clear();
+ out_bind_infos->clear();
+
+ if (!bind_info_count)
+ return;
+
+ std::unordered_set<uint32_t> intercepted_indexes;
+
+ for (uint32_t idx = 0; idx < bind_info_count; idx++) {
+ auto info = reinterpret_cast<const VkBindImageMemorySwapchainInfoKHR*>(
+ bind_infos[idx].pNext);
+ while (info &&
+ info->sType !=
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR) {
+ info = reinterpret_cast<const VkBindImageMemorySwapchainInfoKHR*>(
+ info->pNext);
+ }
+
+ if (!info)
+ continue;
+
+ ALOG_ASSERT(info->swapchain != VK_NULL_HANDLE,
+ "swapchain handle must not be NULL");
+ const Swapchain* swapchain = SwapchainFromHandle(info->swapchain);
+ ALOG_ASSERT(
+ info->imageIndex < swapchain->num_images,
+ "imageIndex must be less than the number of images in swapchain");
+
+ ANativeWindowBuffer* buffer =
+ swapchain->images[info->imageIndex].buffer.get();
+ VkNativeBufferANDROID native_buffer = {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wold-style-cast"
+ .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID,
+#pragma clang diagnostic pop
+ .pNext = bind_infos[idx].pNext,
+ .handle = buffer->handle,
+ .stride = buffer->stride,
+ .format = buffer->format,
+ .usage = int(buffer->usage),
+ };
+ // Reserve enough space to avoid letting re-allocation invalidate the
+ // addresses of the elements inside.
+ out_native_buffers->reserve(bind_info_count);
+ out_native_buffers->emplace_back(native_buffer);
+
+ // Reserve the space now since we know how much is needed now.
+ out_bind_infos->reserve(bind_info_count);
+ out_bind_infos->emplace_back(bind_infos[idx]);
+ out_bind_infos->back().pNext = &out_native_buffers->back();
+
+ intercepted_indexes.insert(idx);
+ }
+
+ if (intercepted_indexes.empty())
+ return;
+
+ for (uint32_t idx = 0; idx < bind_info_count; idx++) {
+ if (intercepted_indexes.count(idx))
+ continue;
+ out_bind_infos->emplace_back(bind_infos[idx]);
+ }
+}
+
+VKAPI_ATTR
+VkResult BindImageMemory2(VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos) {
+ ATRACE_CALL();
+
+ // out_native_buffers is for maintaining the lifecycle of the constructed
+ // VkNativeBufferANDROID objects inside InterceptBindImageMemory2.
+ std::vector<VkNativeBufferANDROID> out_native_buffers;
+ std::vector<VkBindImageMemoryInfo> out_bind_infos;
+ InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers,
+ &out_bind_infos);
+ return GetData(device).driver.BindImageMemory2(
+ device, bindInfoCount,
+ out_bind_infos.empty() ? pBindInfos : out_bind_infos.data());
+}
+
+VKAPI_ATTR
+VkResult BindImageMemory2KHR(VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos) {
+ ATRACE_CALL();
+
+ std::vector<VkNativeBufferANDROID> out_native_buffers;
+ std::vector<VkBindImageMemoryInfo> out_bind_infos;
+ InterceptBindImageMemory2(bindInfoCount, pBindInfos, &out_native_buffers,
+ &out_bind_infos);
+ return GetData(device).driver.BindImageMemory2KHR(
+ device, bindInfoCount,
+ out_bind_infos.empty() ? pBindInfos : out_bind_infos.data());
+}
+
} // namespace driver
} // namespace vulkan
diff --git a/vulkan/libvulkan/swapchain.h b/vulkan/libvulkan/swapchain.h
index ed5718c75f..4912ef1a33 100644
--- a/vulkan/libvulkan/swapchain.h
+++ b/vulkan/libvulkan/swapchain.h
@@ -44,6 +44,8 @@ VKAPI_ATTR VkResult GetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapch
VKAPI_ATTR void SetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pHdrMetadataEXTs);
VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
+VKAPI_ATTR VkResult BindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos);
+VKAPI_ATTR VkResult BindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos);
// clang-format on
} // namespace driver
diff --git a/vulkan/vkjson/Android.bp b/vulkan/vkjson/Android.bp
index ca93e65a8d..a626e4839d 100644
--- a/vulkan/vkjson/Android.bp
+++ b/vulkan/vkjson/Android.bp
@@ -10,7 +10,6 @@ cc_library_static {
"-Wimplicit-fallthrough",
],
cppflags: [
- "-std=c++11",
"-Wno-sign-compare",
],
export_include_dirs: [
@@ -37,7 +36,6 @@ cc_library_static {
"-Wimplicit-fallthrough",
],
cppflags: [
- "-std=c++11",
"-Wno-sign-compare",
],
export_include_dirs: [