Skip to content

Commit 4a90260

Browse files
tomnomgoogleukAndroid (Google) Code Review
authored andcommitted
Merge "Extract GPDIFP2 getProducerUsage path to seperate function" into main
2 parents ae7eda1 + 244dbe4 commit 4a90260

5 files changed

Lines changed: 224 additions & 105 deletions

File tree

vulkan/libvulkan/Android.bp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ package {
2222
default_applicable_licenses: ["frameworks_native_license"],
2323
}
2424

25+
// Expose internal header files to test testing binary
26+
cc_library_headers {
27+
name: "libvulkanprivate_headers-testing",
28+
export_include_dirs: ["."],
29+
visibility: ["//frameworks/native/vulkan/tests"],
30+
}
31+
2532
ndk_library {
2633
name: "libvulkan",
2734
symbol_file: "libvulkan.map.txt",

vulkan/libvulkan/TEST_MAPPING

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"presubmit": [
3+
{
4+
"name": "libvulkan_test"
5+
}
6+
]
7+
}

vulkan/libvulkan/swapchain.cpp

Lines changed: 119 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,115 +1413,138 @@ static void DestroySwapchainInternal(VkDevice device,
14131413
allocator->pfnFree(allocator->pUserData, swapchain);
14141414
}
14151415

1416-
static VkResult getProducerUsage(const VkDevice& device,
1417-
const VkSwapchainCreateInfoKHR* create_info,
1418-
const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage,
1419-
bool create_protected_swapchain,
1420-
uint64_t* producer_usage) {
1421-
// Get the physical device to query the appropriate producer usage
1422-
const VkPhysicalDevice& pdev = GetData(device).driver_physical_device;
1423-
const InstanceData& instance_data = GetData(pdev);
1424-
const InstanceDriverTable& instance_dispatch = instance_data.driver;
1425-
if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2 ||
1426-
instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) {
1427-
// Look through the create_info pNext chain passed to createSwapchainKHR
1428-
// for an image compression control struct.
1429-
// if one is found AND the appropriate extensions are enabled, create a
1430-
// VkImageCompressionControlEXT structure to pass on to
1431-
// GetPhysicalDeviceImageFormatProperties2
1432-
void* compression_control_pNext = nullptr;
1433-
VkImageCompressionControlEXT image_compression = {};
1434-
const VkSwapchainCreateInfoKHR* create_infos = create_info;
1435-
while (create_infos->pNext) {
1436-
create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(create_infos->pNext);
1437-
switch (create_infos->sType) {
1438-
case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
1439-
const VkImageCompressionControlEXT* compression_infos =
1440-
reinterpret_cast<const VkImageCompressionControlEXT*>(create_infos);
1441-
image_compression = *compression_infos;
1442-
image_compression.pNext = nullptr;
1443-
compression_control_pNext = &image_compression;
1444-
} break;
1445-
default:
1446-
// Ignore all other info structs
1447-
break;
1448-
}
1416+
static VkResult getProducerUsageGPDIFP2(
1417+
const VkPhysicalDevice& pdev,
1418+
const VkSwapchainCreateInfoKHR* create_info,
1419+
const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage,
1420+
bool create_protected_swapchain,
1421+
uint64_t* producer_usage) {
1422+
// Look through the create_info pNext chain passed to createSwapchainKHR
1423+
// for an image compression control struct.
1424+
// if one is found AND the appropriate extensions are enabled, create a
1425+
// VkImageCompressionControlEXT structure to pass on to
1426+
// GetPhysicalDeviceImageFormatProperties2
1427+
void* compression_control_pNext = nullptr;
1428+
VkImageCompressionControlEXT image_compression = {};
1429+
const VkSwapchainCreateInfoKHR* create_infos = create_info;
1430+
while (create_infos->pNext) {
1431+
create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(
1432+
create_infos->pNext);
1433+
switch (create_infos->sType) {
1434+
case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
1435+
const VkImageCompressionControlEXT* compression_infos =
1436+
reinterpret_cast<const VkImageCompressionControlEXT*>(
1437+
create_infos);
1438+
image_compression = *compression_infos;
1439+
image_compression.pNext = nullptr;
1440+
compression_control_pNext = &image_compression;
1441+
} break;
1442+
default:
1443+
// Ignore all other info structs
1444+
break;
14491445
}
1446+
}
14501447

1451-
// call GetPhysicalDeviceImageFormatProperties2KHR
1452-
VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = {
1453-
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
1454-
.pNext = compression_control_pNext,
1455-
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
1456-
};
1448+
// call GetPhysicalDeviceImageFormatProperties2KHR
1449+
VkPhysicalDeviceExternalImageFormatInfo external_image_format_info = {
1450+
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
1451+
.pNext = compression_control_pNext,
1452+
.handleType =
1453+
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
1454+
};
14571455

1458-
// AHB does not have an sRGB format so we can't pass it to GPDIFP
1459-
// We need to convert the format to unorm if it is srgb
1460-
VkFormat format = create_info->imageFormat;
1461-
if (format == VK_FORMAT_R8G8B8A8_SRGB) {
1462-
format = VK_FORMAT_R8G8B8A8_UNORM;
1463-
}
1456+
// AHB does not have an sRGB format so we can't pass it to GPDIFP
1457+
// We need to convert the format to unorm if it is srgb
1458+
VkFormat format = create_info->imageFormat;
1459+
if (format == VK_FORMAT_R8G8B8A8_SRGB) {
1460+
format = VK_FORMAT_R8G8B8A8_UNORM;
1461+
}
14641462

1465-
VkPhysicalDeviceImageFormatInfo2 image_format_info = {
1466-
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
1467-
.pNext = &external_image_format_info,
1468-
.format = format,
1469-
.type = VK_IMAGE_TYPE_2D,
1470-
.tiling = VK_IMAGE_TILING_OPTIMAL,
1471-
.usage = create_info->imageUsage,
1472-
.flags = create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
1473-
};
1463+
VkPhysicalDeviceImageFormatInfo2 image_format_info = {
1464+
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
1465+
.pNext = &external_image_format_info,
1466+
.format = format,
1467+
.type = VK_IMAGE_TYPE_2D,
1468+
.tiling = VK_IMAGE_TILING_OPTIMAL,
1469+
.usage = create_info->imageUsage,
1470+
.flags =
1471+
create_protected_swapchain ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u,
1472+
};
14741473

1475-
// If supporting mutable format swapchain add the mutable format flag
1476-
if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
1477-
image_format_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1478-
image_format_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
1479-
}
1474+
// If supporting mutable format swapchain add the mutable format flag
1475+
if (create_info->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
1476+
image_format_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1477+
image_format_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
1478+
}
14801479

1481-
VkAndroidHardwareBufferUsageANDROID ahb_usage;
1482-
ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
1483-
ahb_usage.pNext = nullptr;
1480+
VkAndroidHardwareBufferUsageANDROID ahb_usage;
1481+
ahb_usage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
1482+
ahb_usage.pNext = nullptr;
14841483

1485-
VkImageFormatProperties2 image_format_properties;
1486-
image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
1487-
image_format_properties.pNext = &ahb_usage;
1484+
VkImageFormatProperties2 image_format_properties;
1485+
image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
1486+
image_format_properties.pNext = &ahb_usage;
14881487

1489-
VkResult result = GetPhysicalDeviceImageFormatProperties2(
1490-
pdev, &image_format_info, &image_format_properties);
1491-
if (result != VK_SUCCESS) {
1492-
ALOGE(
1493-
"VkGetPhysicalDeviceImageFormatProperties2 for AHB usage "
1494-
"failed: %d",
1495-
result);
1496-
return VK_ERROR_SURFACE_LOST_KHR;
1497-
}
1488+
VkResult result = GetPhysicalDeviceImageFormatProperties2(
1489+
pdev, &image_format_info, &image_format_properties);
1490+
if (result != VK_SUCCESS) {
1491+
ALOGE(
1492+
"VkGetPhysicalDeviceImageFormatProperties2 for AHB usage "
1493+
"failed: %d",
1494+
result);
1495+
return VK_ERROR_SURFACE_LOST_KHR;
1496+
}
1497+
// Determine if USAGE_FRONT_BUFFER is needed.
1498+
// GPDIFP2 has no means of using VkSwapchainImageUsageFlagsANDROID when
1499+
// querying for producer_usage. So androidHardwareBufferUsage will not
1500+
// contain USAGE_FRONT_BUFFER. We need to manually check for usage here.
1501+
if (!(swapchain_image_usage &
1502+
VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)) {
1503+
*producer_usage = ahb_usage.androidHardwareBufferUsage;
1504+
return VK_SUCCESS;
1505+
}
14981506

1499-
// Determine if USAGE_FRONT_BUFFER is needed.
1500-
// GPDIFP2 has no means of using VkSwapchainImageUsageFlagsANDROID when
1501-
// querying for producer_usage. So androidHardwareBufferUsage will not
1502-
// contain USAGE_FRONT_BUFFER. We need to manually check for usage here.
1503-
if (!(swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)) {
1504-
*producer_usage = ahb_usage.androidHardwareBufferUsage;
1505-
return VK_SUCCESS;
1506-
}
1507+
// Check if USAGE_FRONT_BUFFER is supported for this swapchain
1508+
AHardwareBuffer_Desc ahb_desc = {
1509+
.width = create_info->imageExtent.width,
1510+
.height = create_info->imageExtent.height,
1511+
.layers = create_info->imageArrayLayers,
1512+
.format = create_info->imageFormat,
1513+
.usage = ahb_usage.androidHardwareBufferUsage |
1514+
AHARDWAREBUFFER_USAGE_FRONT_BUFFER,
1515+
.stride = 0, // stride is always ignored when calling isSupported()
1516+
};
15071517

1508-
// Check if USAGE_FRONT_BUFFER is supported for this swapchain
1509-
AHardwareBuffer_Desc ahb_desc = {
1510-
.width = create_info->imageExtent.width,
1511-
.height = create_info->imageExtent.height,
1512-
.layers = create_info->imageArrayLayers,
1513-
.format = create_info->imageFormat,
1514-
.usage = ahb_usage.androidHardwareBufferUsage | AHARDWAREBUFFER_USAGE_FRONT_BUFFER,
1515-
.stride = 0, // stride is always ignored when calling isSupported()
1516-
};
1518+
// If FRONT_BUFFER is not supported in the GPDIFP2 path
1519+
// then we need to fallback to GetSwapchainGrallocUsageXAndroid
1520+
if (AHardwareBuffer_isSupported(&ahb_desc)) {
1521+
*producer_usage = ahb_usage.androidHardwareBufferUsage;
1522+
*producer_usage |= AHARDWAREBUFFER_USAGE_FRONT_BUFFER;
1523+
return VK_SUCCESS;
1524+
}
1525+
1526+
return VK_ERROR_FORMAT_NOT_SUPPORTED;
1527+
}
1528+
1529+
static VkResult getProducerUsage(const VkDevice& device,
1530+
const VkSwapchainCreateInfoKHR* create_info,
1531+
const VkSwapchainImageUsageFlagsANDROID swapchain_image_usage,
1532+
bool create_protected_swapchain,
1533+
uint64_t* producer_usage) {
1534+
// Get the physical device to query the appropriate producer usage
1535+
const VkPhysicalDevice& pdev = GetData(device).driver_physical_device;
1536+
const InstanceData& instance_data = GetData(pdev);
1537+
const InstanceDriverTable& instance_dispatch = instance_data.driver;
15171538

1518-
// If FRONT_BUFFER is not supported,
1519-
// then we need to call GetSwapchainGrallocUsageXAndroid below
1520-
if (AHardwareBuffer_isSupported(&ahb_desc)) {
1521-
*producer_usage = ahb_usage.androidHardwareBufferUsage;
1522-
*producer_usage |= AHARDWAREBUFFER_USAGE_FRONT_BUFFER;
1539+
if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2 ||
1540+
instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR) {
1541+
VkResult result =
1542+
getProducerUsageGPDIFP2(pdev, create_info, swapchain_image_usage,
1543+
create_protected_swapchain, producer_usage);
1544+
if (result == VK_SUCCESS) {
15231545
return VK_SUCCESS;
15241546
}
1547+
// Fall through to gralloc path on error
15251548
}
15261549

15271550
uint64_t native_usage = 0;

vulkan/tests/Android.bp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ cc_test {
2727

2828
header_libs: [
2929
"hwvulkan_headers",
30+
"libvulkanprivate_headers-testing",
3031
"vulkan_headers",
3132
],
3233

vulkan/tests/libvulkan_test.cpp

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include <android/log.h>
18+
#include <driver.h>
1819
#include <gmock/gmock.h>
1920
#include <gtest/gtest.h>
2021
#include <media/NdkImageReader.h>
@@ -29,6 +30,8 @@
2930

3031
namespace android {
3132

33+
namespace libvulkantest {
34+
3235
class AImageReaderVulkanSwapchainTest : public ::testing::Test {
3336
public:
3437
AImageReaderVulkanSwapchainTest() {}
@@ -271,17 +274,20 @@ class AImageReaderVulkanSwapchainTest : public ::testing::Test {
271274

272275
VkResult res =
273276
vkCreateSwapchainKHR(mDevice, &swapchainInfo, nullptr, &mSwapchain);
274-
VK_CHECK(res);
275-
LOGI("Swapchain created successfully");
277+
if (res == VK_SUCCESS) {
278+
LOGI("Swapchain created successfully");
276279

277-
uint32_t swapchainImageCount = 0;
278-
vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
279-
nullptr);
280-
std::vector<VkImage> swapchainImages(swapchainImageCount);
281-
vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
282-
swapchainImages.data());
280+
uint32_t swapchainImageCount = 0;
281+
vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
282+
nullptr);
283+
std::vector<VkImage> swapchainImages(swapchainImageCount);
284+
vkGetSwapchainImagesKHR(mDevice, mSwapchain, &swapchainImageCount,
285+
swapchainImages.data());
283286

284-
LOGI("Swapchain has %u images", swapchainImageCount);
287+
LOGI("Swapchain has %u images", swapchainImageCount);
288+
} else {
289+
LOGI("Swapchain creation failed");
290+
}
285291
}
286292

287293
// Image available callback (AImageReader)
@@ -357,4 +363,79 @@ TEST_F(AImageReaderVulkanSwapchainTest, TestHelperMethods) {
357363
cleanUpSwapchainForTest();
358364
}
359365

366+
// Passing state in these tests requires global state. Wrap each test in an
367+
// anonymous namespace to prevent conflicting names.
368+
namespace {
369+
370+
VKAPI_ATTR VkResult VKAPI_CALL hookedGetPhysicalDeviceImageFormatProperties2KHR(
371+
VkPhysicalDevice,
372+
const VkPhysicalDeviceImageFormatInfo2*,
373+
VkImageFormatProperties2*) {
374+
return VK_ERROR_SURFACE_LOST_KHR;
375+
}
376+
377+
static PFN_vkGetSwapchainGrallocUsage2ANDROID
378+
pfnNextGetSwapchainGrallocUsage2ANDROID = nullptr;
379+
380+
static bool g_grallocCalled = false;
381+
382+
VKAPI_ATTR VkResult VKAPI_CALL hookGetSwapchainGrallocUsage2ANDROID(
383+
VkDevice device,
384+
VkFormat format,
385+
VkImageUsageFlags imageUsage,
386+
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
387+
uint64_t* grallocConsumerUsage,
388+
uint64_t* grallocProducerUsage) {
389+
g_grallocCalled = true;
390+
if (pfnNextGetSwapchainGrallocUsage2ANDROID) {
391+
return pfnNextGetSwapchainGrallocUsage2ANDROID(
392+
device, format, imageUsage, swapchainImageUsage,
393+
grallocConsumerUsage, grallocProducerUsage);
394+
}
395+
396+
return VK_ERROR_INITIALIZATION_FAILED;
397+
}
398+
399+
TEST_F(AImageReaderVulkanSwapchainTest, getProducerUsageFallbackTest1) {
400+
// BUG: 379230826
401+
// Verify that getProducerUsage falls back to
402+
// GetSwapchainGrallocUsage*ANDROID if GPDIFP2 fails
403+
std::vector<const char*> instanceLayers = {};
404+
std::vector<const char*> deviceLayers = {};
405+
createVulkanInstance(instanceLayers);
406+
407+
createAImageReader(640, 480, AIMAGE_FORMAT_PRIVATE, 3);
408+
getANativeWindowFromReader();
409+
createVulkanSurface();
410+
pickPhysicalDeviceAndQueueFamily();
411+
412+
createDeviceAndGetQueue(deviceLayers);
413+
auto& pdev = vulkan::driver::GetData(mDevice).driver_physical_device;
414+
auto& pdevDispatchTable = vulkan::driver::GetData(pdev).driver;
415+
auto& deviceDispatchTable = vulkan::driver::GetData(mDevice).driver;
416+
417+
ASSERT_NE(deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID, nullptr);
418+
419+
pdevDispatchTable.GetPhysicalDeviceImageFormatProperties2 =
420+
hookedGetPhysicalDeviceImageFormatProperties2KHR;
421+
deviceDispatchTable.GetSwapchainGrallocUsage2ANDROID =
422+
hookGetSwapchainGrallocUsage2ANDROID;
423+
424+
ASSERT_FALSE(g_grallocCalled);
425+
426+
createSwapchain();
427+
428+
ASSERT_TRUE(g_grallocCalled);
429+
430+
ASSERT_NE(mVkInstance, (VkInstance)VK_NULL_HANDLE);
431+
ASSERT_NE(mPhysicalDev, (VkPhysicalDevice)VK_NULL_HANDLE);
432+
ASSERT_NE(mDevice, (VkDevice)VK_NULL_HANDLE);
433+
ASSERT_NE(mSurface, (VkSurfaceKHR)VK_NULL_HANDLE);
434+
cleanUpSwapchainForTest();
435+
}
436+
437+
} // namespace
438+
439+
} // namespace libvulkantest
440+
360441
} // namespace android

0 commit comments

Comments
 (0)