Extract GPDIFP2 getProducerUsage path to seperate function
Extracting the GPDIFP2 logic to its own function makes it easier to
exit early from the GPDIFP2 path when we need to fall back to the
GetSwapchainGrallocUsage*ANDROID path.
This change also fixes an issue where we would exit getProducerUsage
early instead of falling back to the gralloc paths if GPDIFP2 would
return an error when called with an unsupported format.
Bug: 379230826
Test: atest libvulkan_test
Flag: EXEMPT bugfix
Change-Id: I42f1fe31e5e4a01c472a12854a1f4e989d2786dc
diff --git a/vulkan/tests/Android.bp b/vulkan/tests/Android.bp
index 551d9b7..db218c1 100644
--- a/vulkan/tests/Android.bp
+++ b/vulkan/tests/Android.bp
@@ -27,6 +27,7 @@
header_libs: [
"hwvulkan_headers",
+ "libvulkanprivate_headers-testing",
"vulkan_headers",
],
diff --git a/vulkan/tests/libvulkan_test.cpp b/vulkan/tests/libvulkan_test.cpp
index 128d640..7c9ef7d 100644
--- a/vulkan/tests/libvulkan_test.cpp
+++ b/vulkan/tests/libvulkan_test.cpp
@@ -15,6 +15,7 @@
*/
#include <android/log.h>
+#include <driver.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <media/NdkImageReader.h>
@@ -29,6 +30,8 @@
namespace android {
+namespace libvulkantest {
+
class AImageReaderVulkanSwapchainTest : public ::testing::Test {
public:
AImageReaderVulkanSwapchainTest() {}
@@ -271,17 +274,20 @@
VkResult res =
vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
- VK_CHECK(res);
- LOGI("Swapchain created successfully");
+ if (res == VK_SUCCESS) {
+ LOGI("Swapchain created successfully");
- uint32_t swapchainImageCount = 0;
- vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
- nullptr);
- std::vector<VkImage> swapchainImages(swapchainImageCount);
- vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
- swapchainImages.data());
+ uint32_t swapchainImageCount = 0;
+ vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
+ nullptr);
+ std::vector<VkImage> swapchainImages(swapchainImageCount);
+ vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
+ swapchainImages.data());
- LOGI("Swapchain has %u images", swapchainImageCount);
+ LOGI("Swapchain has %u images", swapchainImageCount);
+ } else {
+ LOGI("Swapchain creation failed");
+ }
}
// Image available callback (AImageReader)
@@ -357,4 +363,79 @@
cleanUpSwapchainForTest();
}
+// Passing state in these tests requires global state. Wrap each test in an
+// anonymous namespace to prevent conflicting names.
+namespace {
+
+VKAPI_ATTR VkResult VKAPI_CALL hookedGetPhysicalDeviceImageFormatProperties2KHR(
+ VkPhysicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2*,
+ VkImageFormatProperties2*) {
+ return VK_ERROR_SURFACE_LOST_KHR;
+}
+
+static PFN_vkGetSwapchainGrallocUsage2ANDROID
+ pfnNextGetSwapchainGrallocUsage2ANDROID = nullptr;
+
+static bool g_grallocCalled = false;
+
+VKAPI_ATTR VkResult VKAPI_CALL hookGetSwapchainGrallocUsage2ANDROID(
+ VkDevice device,
+ VkFormat format,
+ VkImageUsageFlags imageUsage,
+ VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
+ uint64_t* grallocConsumerUsage,
+ uint64_t* grallocProducerUsage) {
+ g_grallocCalled = true;
+ if (pfnNextGetSwapchainGrallocUsage2ANDROID) {
+ return pfnNextGetSwapchainGrallocUsage2ANDROID(
+ device, format, imageUsage, swapchainImageUsage,
+ grallocConsumerUsage, grallocProducerUsage);
+ }
+
+ return VK_ERROR_INITIALIZATION_FAILED;
+}
+
+TEST_F(AImageReaderVulkanSwapchainTest, getProducerUsageFallbackTest1) {
+ // BUG: 379230826
+ // Verify that getProducerUsage falls back to
+ // GetSwapchainGrallocUsage*ANDROID if GPDIFP2 fails
+ std::vector<const char*> instanceLayers = {};
+ std::vector<const char*> deviceLayers = {};
+ createVulkanInstance(instanceLayers);
+
+ createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
+ getANativeWindowFromReader();
+ createVulkanSurface();
+ pickPhysicalDeviceAndQueueFamily();
+
+ createDeviceAndGetQueue(deviceLayers);
+ auto& pdev = vulkan::driver::GetData(mDevice).driver_physical_device;
+ auto& pdevDispatchTable = vulkan::driver::GetData(pdev).driver;
+ auto& deviceDispatchTable = vulkan::driver::GetData(mDevice).driver;
+
+ ASSERT_NE(deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID, nullptr);
+
+ pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 =
+ hookedGetPhysicalDeviceImageFormatProperties2KHR;
+ deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID =
+ hookGetSwapchainGrallocUsage2ANDROID;
+
+ ASSERT_FALSE(g_grallocCalled);
+
+ createSwapchain();
+
+ ASSERT_TRUE(g_grallocCalled);
+
+ ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE);
+ ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE);
+ ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE);
+ ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE);
+ cleanUpSwapchainForTest();
+}
+
+} // namespace
+
+} // namespace libvulkantest
+
} // namespace android