From: Chris Forbes Date: Thu, 19 Jul 2018 23:47:11 +0000 (-0700) Subject: Backport post-P AHardwareBuffer changes from Khronos CTS X-Git-Tag: upstream/1.3.5~1974^2~8^2~5^2~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0100d07a004050f3db89c2ea3673b150838b97f9;p=platform%2Fupstream%2FVK-GL-CTS.git Backport post-P AHardwareBuffer changes from Khronos CTS This includes all the changes approved by Khronos to these tests between the time we initially landed them for P CTS, and the upstream changes being accepted. Bug: b/75981905, b/109927547 Change-Id: I23550489a55af36089451384f75f62ae54f99c27 --- diff --git a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp index 9724e19..6186423 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp @@ -53,18 +53,6 @@ # include #endif -#if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__) -# define USE_ANDROID_O_HARDWARE_BUFFER -#endif - -#if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__) -# define USE_ANDROID_P_HARDWARE_BUFFER -#endif - -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) -# include -#endif - using tcu::TestLog; using namespace vkt::ExternalMemoryUtil; @@ -3806,75 +3794,19 @@ de::MovePtr createFenceTests (tcu::TestContext& testCtx, vk: return fenceGroup; } -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) -deUint32 vkUsageToAhbUsage(deUint64 vkFlag) { - switch(vkFlag) { - case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT: - case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT: - // No AHB equivalent. - return 0u; - case vk::VK_IMAGE_USAGE_SAMPLED_BIT: - return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; - case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT: - return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; - case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT: - return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; - } - return 0u; -} - -deUint32 vkCreateToAhbUsage(deUint64 vkFlag) { - switch(vkFlag) { - case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT: - case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT: - // No AHB equivalent. - return 0u; - case vk::VK_IMAGE_CREATE_PROTECTED_BIT: - return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT; -#if defined(USE_ANDROID_P_HARDWARE_BUFFER) - case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT: - return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP; -#endif - } - return 0u; -} - -deUint32 vkFormatToAhbFormat(deUint64 vkFormat) { - switch(vkFormat) { - case vk::VK_FORMAT_R8G8B8A8_UNORM: - return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; - case vk::VK_FORMAT_R8G8B8_UNORM: - return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; - case vk::VK_FORMAT_R5G6B5_UNORM_PACK16: - return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; - case vk::VK_FORMAT_R16G16B16A16_SFLOAT: - return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; - case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32: - return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; +bool ValidateAHardwareBuffer(vk::VkFormat format, deUint64 requiredAhbUsage, const vk::DeviceDriver& vkd, const vk::VkDevice& device) +{ + AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance(); + if (!ahbApi) + { + TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles"); } - return 0u; -} -bool ValidateAHardwareBuffer(vk::VkFormat format, deUint32 requiredAhbUsage, const vk::DeviceDriver& vkd, const vk::VkDevice& device) { - AHardwareBuffer_Desc hbufferdesc = - { - 64u, - 64u, - 1u, - vkFormatToAhbFormat(format), - requiredAhbUsage, - 0u, - 0u, - 0u - }; - AHardwareBuffer* hbuffer = DE_NULL; - AHardwareBuffer_allocate(&hbufferdesc, &hbuffer); - if (!hbuffer) + vk::pt::AndroidHardwareBufferPtr ahb = ahbApi->allocate(64u, 64u, 1u, ahbApi->vkFormatToAhbFormat(format), requiredAhbUsage); + if (ahb.internal == DE_NULL) return false; - NativeHandle nativeHandle; - nativeHandle = vk::pt::AndroidHardwareBufferPtr(hbuffer); - + NativeHandle nativeHandle(ahb); vk::VkAndroidHardwareBufferFormatPropertiesANDROID formatProperties = { vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID, @@ -3887,14 +3819,15 @@ bool ValidateAHardwareBuffer(vk::VkFormat format, deUint32 requiredAhbUsage, con vk::VK_CHROMA_LOCATION_COSITED_EVEN, vk::VK_CHROMA_LOCATION_COSITED_EVEN }; - vk::VkAndroidHardwareBufferPropertiesANDROID bufferProperties = { + vk::VkAndroidHardwareBufferPropertiesANDROID bufferProperties = + { vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID, &formatProperties, 0u, 0u }; - VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, vk::pt::AndroidHardwareBufferPtr(hbuffer), &bufferProperties)); + VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, ahb, &bufferProperties)); TCU_CHECK(formatProperties.format != vk::VK_FORMAT_UNDEFINED); TCU_CHECK(formatProperties.format == format); TCU_CHECK(formatProperties.externalFormat != 0u); @@ -3902,20 +3835,24 @@ bool ValidateAHardwareBuffer(vk::VkFormat format, deUint32 requiredAhbUsage, con TCU_CHECK((formatProperties.formatFeatures & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) != 0u); return true; } -#endif -tcu::TestStatus testAndroidHardwareBufferImageFormat(Context& context, vk::VkFormat format) +tcu::TestStatus testAndroidHardwareBufferImageFormat (Context& context, vk::VkFormat format) { -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) + AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance(); + if (!ahbApi) + { + TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles"); + } + const vk::VkExternalMemoryHandleTypeFlagBits externalMemoryType = vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; const vk::PlatformInterface& vkp (context.getPlatformInterface()); const vk::Unique instance (createInstance(vkp, context.getUsedApiVersion(), externalMemoryType, 0u, 0u)); const vk::InstanceDriver vki (vkp, *instance); const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine())); const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u)); - const vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL; const vk::Unique device (createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalMemoryType, 0u, queueFamilyIndex, true)); const vk::DeviceDriver vkd (vki, *device); + TestLog& log = context.getTestContext().getLog(); const vk::VkImageUsageFlagBits usageFlags[] = { @@ -3932,29 +3869,28 @@ tcu::TestStatus testAndroidHardwareBufferImageFormat(Context& context, vk::VkFor vk::VK_IMAGE_CREATE_PROTECTED_BIT, vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, }; - deUint32 mustSupportAhbUsageFlags = - AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | - AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; -#if defined(USE_ANDROID_P_HARDWARE_BUFFER) - mustSupportAhbUsageFlags |= - AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | - AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE; -#endif + const vk::VkImageTiling tilings[] = + { + vk::VK_IMAGE_TILING_OPTIMAL, + vk::VK_IMAGE_TILING_LINEAR, + }; + deUint64 mustSupportAhbUsageFlags = ahbApi->mustSupportAhbUsageFlags(); const size_t numOfUsageFlags = DE_LENGTH_OF_ARRAY(usageFlags); const size_t numOfCreateFlags = DE_LENGTH_OF_ARRAY(createFlags); const size_t numOfFlagCombos = 1u << (numOfUsageFlags + numOfCreateFlags); + const size_t numOfTilings = DE_LENGTH_OF_ARRAY(tilings); for (size_t combo = 0; combo < numOfFlagCombos; combo++) { vk::VkImageUsageFlags usage = 0; vk::VkImageCreateFlags createFlag = 0; - deUint32 requiredAhbUsage = 0; + deUint64 requiredAhbUsage = 0; for (size_t usageNdx = 0; usageNdx < numOfUsageFlags; usageNdx++) { if ((combo & (1u << usageNdx)) == 0) continue; usage |= usageFlags[usageNdx]; - requiredAhbUsage |= vkUsageToAhbUsage(usageFlags[usageNdx]); + requiredAhbUsage |= ahbApi->vkUsageToAhbUsage(usageFlags[usageNdx]); } for (size_t createFlagNdx = 0; createFlagNdx < numOfCreateFlags; createFlagNdx++) { @@ -3962,7 +3898,7 @@ tcu::TestStatus testAndroidHardwareBufferImageFormat(Context& context, vk::VkFor if ((combo & (1u << bit)) == 0) continue; createFlag |= createFlags[createFlagNdx]; - requiredAhbUsage |= vkCreateToAhbUsage(createFlags[createFlagNdx]); + requiredAhbUsage |= ahbApi->vkCreateToAhbUsage(createFlags[createFlagNdx]); } // Only test a combination if the usage flags include at least one of the AHARDWAREBUFFER_USAGE_GPU_* flag. @@ -3973,123 +3909,144 @@ tcu::TestStatus testAndroidHardwareBufferImageFormat(Context& context, vk::VkFor if (!ValidateAHardwareBuffer(format, requiredAhbUsage, vkd, *device)) continue; - const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo = + bool foundAnyUsableTiling = false; + for (size_t tilingIndex = 0; tilingIndex < numOfTilings; tilingIndex++) { - vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - DE_NULL, - vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID - }; - const vk::VkPhysicalDeviceImageFormatInfo2 info = - { - vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - &externalInfo, - format, - vk::VK_IMAGE_TYPE_2D, - vk::VK_IMAGE_TILING_OPTIMAL, - usage, - createFlag, - }; + const vk::VkImageTiling tiling = tilings[tilingIndex]; - vk::VkAndroidHardwareBufferUsageANDROID ahbUsageProperties = - { - vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID, - DE_NULL, - 0u - }; - vk::VkExternalImageFormatProperties externalProperties = - { - vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, - &ahbUsageProperties, - { 0u, 0u, 0u } - }; - vk::VkImageFormatProperties2 properties = - { - vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, - &externalProperties, + const vk::VkPhysicalDeviceExternalImageFormatInfo externalInfo = { - { 0u, 0u, 0u }, - 0u, - 0u, - 0u, + vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + DE_NULL, + vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID + }; + const vk::VkPhysicalDeviceImageFormatInfo2 info = + { + vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + &externalInfo, + format, + vk::VK_IMAGE_TYPE_2D, + tiling, + usage, + createFlag, + }; + + vk::VkAndroidHardwareBufferUsageANDROID ahbUsageProperties = + { + vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID, + DE_NULL, 0u - } - }; + }; + vk::VkExternalImageFormatProperties externalProperties = + { + vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, + &ahbUsageProperties, + { 0u, 0u, 0u } + }; + vk::VkImageFormatProperties2 properties = + { + vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + &externalProperties, + { + { 0u, 0u, 0u }, + 0u, + 0u, + 0u, + 0u + } + }; - vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties); - TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0); - TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0); - TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0); - deUint32 maxWidth = properties.imageFormatProperties.maxExtent.width; - deUint32 maxHeight = properties.imageFormatProperties.maxExtent.height; - TCU_CHECK(maxWidth >= 4096); - TCU_CHECK(maxHeight >= 4096); - // Even if not requested, at least one of GPU_* usage flags must be present. - TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & mustSupportAhbUsageFlags) != 0u); - // The AHB usage flags corresponding to the create and usage flags used in info must be present. - TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & requiredAhbUsage) == requiredAhbUsage); - - struct ImageSize { - deUint32 width; - deUint32 height; - }; - ImageSize sizes[] = { - {64u, 64u}, - {1024u, 2096u}, - }; - deUint32 exportedMemoryTypeIndex = ~0U; - for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(sizes); i++) { - const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, sizes[i].width, sizes[i].height, tiling, createFlag, usage)); - const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *image)); - const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); - NativeHandle handle; - - VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); - getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); - - AHardwareBuffer_Desc desc; - AHardwareBuffer_describe(static_cast(handle.getAndroidHardwareBuffer().internal), &desc); - TCU_CHECK(desc.format == vkFormatToAhbFormat(format)); - TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage); - } + if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED) + { + log << TestLog::Message << "Tiling " << tiling << " is not supported." << TestLog::EndMessage; + continue; + } - if (properties.imageFormatProperties.maxMipLevels > 1u) { - const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, - properties.imageFormatProperties.maxMipLevels)); - const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *image)); - const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); - NativeHandle handle; + foundAnyUsableTiling = true; - VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); - getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); + TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0); + TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0); + TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0); + deUint32 maxWidth = properties.imageFormatProperties.maxExtent.width; + deUint32 maxHeight = properties.imageFormatProperties.maxExtent.height; + TCU_CHECK(maxWidth >= 4096); + TCU_CHECK(maxHeight >= 4096); + // Even if not requested, at least one of GPU_* usage flags must be present. + TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & mustSupportAhbUsageFlags) != 0u); + // The AHB usage flags corresponding to the create and usage flags used in info must be present. + TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & requiredAhbUsage) == requiredAhbUsage); - AHardwareBuffer_Desc desc; - AHardwareBuffer_describe(static_cast(handle.getAndroidHardwareBuffer().internal), &desc); - TCU_CHECK(desc.format == vkFormatToAhbFormat(format)); - TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage); - } + log << TestLog::Message << "Required flags: " << std::hex << requiredAhbUsage << " Actual flags: " << std::hex << ahbUsageProperties.androidHardwareBufferUsage + << TestLog::EndMessage; - if (properties.imageFormatProperties.maxArrayLayers > 1u) { - const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, - 1u, properties.imageFormatProperties.maxArrayLayers)); - const vk::VkMemoryRequirements requirements(getImageMemoryRequirements(vkd, *device, *image)); - const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); - NativeHandle handle; + struct ImageSize + { + deUint32 width; + deUint32 height; + }; + ImageSize sizes[] = + { + {64u, 64u}, + {1024u, 2096u}, + }; + for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(sizes); i++) + { + deUint32 exportedMemoryTypeIndex = ~0U; + const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, sizes[i].width, sizes[i].height, tiling, createFlag, usage)); + const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *image)); + const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); + NativeHandle handle; + + VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); + getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); + + deUint32 ahbFormat = 0; + deUint64 anhUsage = 0; + ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL); + TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format)); + TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage); + } - VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); - getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); + if (properties.imageFormatProperties.maxMipLevels > 1u) + { + deUint32 exportedMemoryTypeIndex = ~0U; + const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, properties.imageFormatProperties.maxMipLevels)); + const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *image)); + const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); + NativeHandle handle; + + VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); + getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); + + deUint32 ahbFormat = 0; + deUint64 anhUsage = 0; + ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL); + TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format)); + TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage); + } - AHardwareBuffer_Desc desc; - AHardwareBuffer_describe(static_cast(handle.getAndroidHardwareBuffer().internal), &desc); - TCU_CHECK(desc.format == vkFormatToAhbFormat(format)); - TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage); + if (properties.imageFormatProperties.maxArrayLayers > 1u) + { + deUint32 exportedMemoryTypeIndex = ~0U; + const vk::Unique image (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, 1u, properties.imageFormatProperties.maxArrayLayers)); + const vk::VkMemoryRequirements requirements (getImageMemoryRequirements(vkd, *device, *image)); + const vk::Unique memory (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex)); + NativeHandle handle; + + VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u)); + getMemoryNative(vkd, *device, *memory, externalMemoryType, handle); + + deUint32 ahbFormat = 0; + deUint64 anhUsage = 0; + ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL); + TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format)); + TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage); + } } + + TCU_CHECK(foundAnyUsableTiling); } return tcu::TestStatus::pass("Pass"); -#else - DE_UNREF(context); - DE_UNREF(format); - TCU_THROW(NotSupportedError, "Platform doesn't support AHardwareBuffers"); -#endif } de::MovePtr createFenceTests (tcu::TestContext& testCtx) @@ -4259,6 +4216,7 @@ de::MovePtr createMemoryTests (tcu::TestContext& testCtx, vk { const vk::VkFormat format = ahbFormats[ahbFormatNdx]; const std::string testCaseName = getFormatCaseName(format); + addFunctionCase(formatGroup.get(), testCaseName, "", testAndroidHardwareBufferImageFormat, format); } diff --git a/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp b/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp index b7e2095..1e8f82f 100644 --- a/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp +++ b/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.cpp @@ -36,9 +36,14 @@ # include #endif +#if (DE_OS == DE_OS_ANDROID) +# include +#endif + #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__) # include -# define USE_ANDROID_O_HARDWARE_BUFFER 1 +# include "deDynamicLibrary.hpp" +# define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1 #endif namespace vkt @@ -119,15 +124,13 @@ NativeHandle::NativeHandle (const NativeHandle& other) DE_FATAL("Platform doesn't support win32 handles"); #endif } -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) else if (other.m_androidHardwareBuffer.internal) { DE_ASSERT(other.m_fd == -1); DE_ASSERT(!other.m_win32Handle.internal); m_androidHardwareBuffer = other.m_androidHardwareBuffer; - AHardwareBuffer_acquire((AHardwareBuffer*)m_androidHardwareBuffer.internal); + AndroidHardwareBufferExternalApi::getInstance()->acquire(m_androidHardwareBuffer); } -#endif else DE_FATAL("Native handle can't be duplicated"); } @@ -195,16 +198,12 @@ void NativeHandle::reset (void) DE_FATAL("Platform doesn't support win32 handles"); #endif } - -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) if (m_androidHardwareBuffer.internal) { DE_ASSERT(m_fd == -1); DE_ASSERT(!m_win32Handle.internal); - AHardwareBuffer_release((AHardwareBuffer*)m_androidHardwareBuffer.internal); + AndroidHardwareBufferExternalApi::getInstance()->release(m_androidHardwareBuffer); } -#endif - m_fd = -1; m_win32Handle = vk::pt::Win32Handle(DE_NULL); m_win32HandleType = WIN32HANDLETYPE_LAST; @@ -503,6 +502,10 @@ void getMemoryNative (const vk::DeviceInterface& vkd, } else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) { + if (!AndroidHardwareBufferExternalApi::getInstance()) + { + TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles"); + } const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID info = { vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, @@ -1014,13 +1017,17 @@ static vk::Move importMemory (const vk::DeviceInterface& return memory; } -#if defined(USE_ANDROID_O_HARDWARE_BUFFER) else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) { - AHardwareBuffer_Desc desc; - AHardwareBuffer_describe(static_cast(handle.getAndroidHardwareBuffer().internal), &desc); + AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance(); + if (!ahbApi) + { + TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles"); + } - DE_ASSERT(desc.format == AHARDWAREBUFFER_FORMAT_BLOB || image != 0); + deUint32 ahbFormat = 0; + ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, DE_NULL, DE_NULL); + DE_ASSERT(ahbApi->ahbFormatIsBlob(ahbFormat) || image != 0); vk::VkImportAndroidHardwareBufferInfoANDROID importInfo = { @@ -1046,7 +1053,6 @@ static vk::Move importMemory (const vk::DeviceInterface& return memory; } -#endif // (USE_ANDROID_O_HARDWARE_BUFFER) else { DE_FATAL("Unknown external memory type"); @@ -1125,8 +1131,8 @@ vk::Move createExternalImage (const vk::DeviceInterface& vkd, vk::VkImageTiling tiling, vk::VkImageCreateFlags createFlags, vk::VkImageUsageFlags usageFlags, - deUint32 mipLevels, - deUint32 arrayLayers) + deUint32 mipLevels, + deUint32 arrayLayers) { const vk::VkExternalMemoryImageCreateInfo externalCreateInfo = { @@ -1156,5 +1162,320 @@ vk::Move createExternalImage (const vk::DeviceInterface& vkd, return vk::createImage(vkd, device, &createInfo); } +#if (DE_OS == DE_OS_ANDROID) +# if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__) +# define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1 +# endif + +static deInt32 androidGetSdkVersion() +{ + static deInt32 sdkVersion = -1; + if (sdkVersion < 0) + { + char value[128] = {0}; + __system_property_get("ro.build.version.sdk", value); + sdkVersion = static_cast(strtol(value, DE_NULL, 10)); + printf("SDK Version is %d\n", sdkVersion); + } + return sdkVersion; +} + +static deInt32 checkAnbApiBuild() +{ + deInt32 sdkVersion = androidGetSdkVersion(); +#if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) + // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer. + DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */ +#endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) +#if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER) + // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer. + DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */ +#endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER) + return sdkVersion; +} + +bool AndroidHardwareBufferExternalApi::supportsAhb() +{ + return (checkAnbApiBuild() >= __ANDROID_API_O__); +} + +AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi() +{ + deInt32 sdkVersion = checkAnbApiBuild(); + if(sdkVersion >= __ANDROID_API_O__) + { +#if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) + if (!loadAhbDynamicApis(sdkVersion)) + { + // Couldn't load Android AHB system APIs. + DE_TEST_ASSERT(false); + } +#else + // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android. + DE_TEST_ASSERT(false); +#endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) + } +} + +AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi() +{ +} + +#if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) +typedef int (*pfn_system_property_get)(const char *, char *); +typedef int (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer); +typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc); +typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer); +typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer); + +struct AhbFunctions +{ + pfnAHardwareBuffer_allocate allocate; + pfnAHardwareBuffer_describe describe; + pfnAHardwareBuffer_acquire acquire; + pfnAHardwareBuffer_release release; +}; + +static AhbFunctions ahbFunctions; + +static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions) +{ + static bool ahbApiLoaded = false; + if (ahbApiLoaded || + ((pAhbFunctions->allocate != DE_NULL) && + (pAhbFunctions->describe != DE_NULL) && + (pAhbFunctions->acquire != DE_NULL) && + (pAhbFunctions->release != DE_NULL))) + { + ahbApiLoaded = true; + return true; + } + return false; +} + +bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion) +{ + if(sdkVersion >= __ANDROID_API_O__) + { + if (!ahbFunctionsLoaded(&ahbFunctions)) + { + de::DynamicLibrary libnativewindow("libnativewindow.so"); + ahbFunctions.allocate = reinterpret_cast(libnativewindow.getFunction("AHardwareBuffer_allocate")); + ahbFunctions.describe = reinterpret_cast(libnativewindow.getFunction("AHardwareBuffer_describe")); + ahbFunctions.acquire = reinterpret_cast(libnativewindow.getFunction("AHardwareBuffer_acquire")); + ahbFunctions.release = reinterpret_cast(libnativewindow.getFunction("AHardwareBuffer_release")); + + return ahbFunctionsLoaded(&ahbFunctions); + + } + else + { + return true; + } + } + + return false; +} + +class AndroidHardwareBufferExternalApi26 : public AndroidHardwareBufferExternalApi +{ +public: + + virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage); + virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer); + virtual void release(vk::pt::AndroidHardwareBufferPtr buffer); + virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer, + deUint32* width, + deUint32* height, + deUint32* layers, + deUint32* format, + deUint64* usage, + deUint32* stride); + virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag); + virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag); + virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat); + virtual deUint64 mustSupportAhbUsageFlags(); + virtual bool ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); }; + + AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {}; + virtual ~AndroidHardwareBufferExternalApi26() {}; + +private: + // Stop the compiler generating methods of copy the object + AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented + AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented +}; + +vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate( deUint32 width, + deUint32 height, + deUint32 layers, + deUint32 format, + deUint64 usage) +{ + AHardwareBuffer_Desc hbufferdesc = { + width, + height, + layers, // number of images + format, + usage, + 0u, // Stride in pixels, ignored for AHardwareBuffer_allocate() + 0u, // Initialize to zero, reserved for future use + 0u // Initialize to zero, reserved for future use + }; + + AHardwareBuffer* hbuffer = DE_NULL; + ahbFunctions.allocate(&hbufferdesc, &hbuffer); + + return vk::pt::AndroidHardwareBufferPtr(hbuffer); +} + +void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer) +{ + ahbFunctions.acquire(static_cast(buffer.internal)); +} + +void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer) +{ + ahbFunctions.release(static_cast(buffer.internal)); +} + +void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer, + deUint32* width, + deUint32* height, + deUint32* layers, + deUint32* format, + deUint64* usage, + deUint32* stride) +{ + AHardwareBuffer_Desc desc; + ahbFunctions.describe(static_cast(buffer.internal), &desc); + if (width) *width = desc.width; + if (height) *height = desc.height; + if (layers) *layers = desc.layers; + if (format) *format = desc.format; + if (usage) *usage = desc.usage; + if (stride) *stride = desc.stride; +} + +deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags) +{ + switch(vkFlags) + { + case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT: + case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT: + // No AHB equivalent. + return 0u; + case vk::VK_IMAGE_USAGE_SAMPLED_BIT: + return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; + case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT: + return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; + case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT: + return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; + default: + return 0u; + } +} + +deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags) +{ + switch(vkFlags) + { + case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT: + case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT: + // No AHB equivalent. + return 0u; + case vk::VK_IMAGE_CREATE_PROTECTED_BIT: + return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT; + default: + return 0u; + } +} + +deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat) +{ + switch(vkFormat) + { + case vk::VK_FORMAT_R8G8B8A8_UNORM: + return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; + case vk::VK_FORMAT_R8G8B8_UNORM: + return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; + case vk::VK_FORMAT_R5G6B5_UNORM_PACK16: + return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; + case vk::VK_FORMAT_R16G16B16A16_SFLOAT: + return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; + case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32: + return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; + default: + return 0u; + } +} + +deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() +{ + return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT); +} + +#if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER) +class AndroidHardwareBufferExternalApi28 : public AndroidHardwareBufferExternalApi26 +{ +public: + + virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag); + virtual deUint64 mustSupportAhbUsageFlags(); + + AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {}; + virtual ~AndroidHardwareBufferExternalApi28() {}; + +private: + // Stop the compiler generating methods of copy the object + AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented + AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented +}; + +deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags) +{ + switch(vkFlags) + { + case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT: + return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP; + default: + return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags); + } +} + +deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags() +{ + return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE; +} + +#endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER) +#endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) +#endif // (DE_OS == DE_OS_ANDROID) + +AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance() +{ +#if (DE_OS == DE_OS_ANDROID) + deInt32 sdkVersion = checkAnbApiBuild(); +#if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) +# if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__) + if (sdkVersion >= __ANDROID_API_P__ ) + { + static AndroidHardwareBufferExternalApi28 api28Instance; + return &api28Instance; + } + else +# elif defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__) + if (sdkVersion >= __ANDROID_API_O__ ) + { + static AndroidHardwareBufferExternalApi26 api26Instance; + return &api26Instance; + } +# endif +#endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER) + DE_UNREF(sdkVersion); +#endif // DE_OS == DE_OS_ANDROID + return DE_NULL; +} + } // ExternalMemoryUtil } // vkt diff --git a/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.hpp b/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.hpp index ae573a8..f448326 100644 --- a/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.hpp +++ b/external/vulkancts/modules/vulkan/vktExternalMemoryUtil.hpp @@ -70,6 +70,83 @@ private: NativeHandle& operator= (const NativeHandle&); }; +class AndroidHardwareBufferExternalApi +{ +public: + + /** + * getInstance obtains the object, that provides an interface to AHB system APIs . + * If the AHB system API is not supported or if it is not built as supported with the CTS, + * then this function would return a null object. + */ + static AndroidHardwareBufferExternalApi* getInstance(); + + /* Is AndroidHardwareBuffer supported? */ + static bool supportsAhb(); + + /** + * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows: + * width; - width in pixels + * height; - height in pixels + * layers; - number of images + * format; - One of AHARDWAREBUFFER_FORMAT_* + * usage; - Combination of AHARDWAREBUFFER_USAGE_* + * + * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if + * the allocation fails for any reason. + */ + virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32 height, deUint32 layers, deUint32 format, deUint64 usage) = 0; + + /** + * Acquire a reference on the given AHardwareBuffer object. This prevents the + * object from being deleted until the last reference is removed. + */ + virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0; + + /** + * Remove a reference that was previously acquired with + * AHardwareBuffer_acquire(). + */ + virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0; + + /** + * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL: + * width; - width in pixels + * height; - height in pixels + * layers; - number of images + * format; - One of AHARDWAREBUFFER_FORMAT_* + * usage; - Combination of AHARDWAREBUFFER_USAGE_* + * + */ + virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer, + deUint32* width, + deUint32* height, + deUint32* layers, + deUint32* format, + deUint64* usage, + deUint32* stride) = 0; + + + virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0; + virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0; + virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0; + virtual deUint64 mustSupportAhbUsageFlags() = 0; + virtual bool ahbFormatIsBlob(deUint32 format) = 0; + + virtual ~AndroidHardwareBufferExternalApi(); + +protected: + // Protected Constructor + AndroidHardwareBufferExternalApi(); + +private: + // Stop the compiler generating methods of copy the object + AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const& copy); // Not Implemented + AndroidHardwareBufferExternalApi& operator=(AndroidHardwareBufferExternalApi const& copy); // Not Implemented + + static bool loadAhbDynamicApis(deInt32 sdkVersion); +}; + const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type); const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type); const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type); @@ -236,8 +313,8 @@ vk::Move createExternalImage (const vk::DeviceInterface& vk::VkImageTiling tiling, vk::VkImageCreateFlags createFlags, vk::VkImageUsageFlags usageFlags, - deUint32 mipLevels = 1u, - deUint32 arrayLayers = 1u); + deUint32 mipLevels = 1u, + deUint32 arrayLayers = 1u); } // ExternalMemoryUtil } // vkt