diff options
Diffstat (limited to 'chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp')
-rw-r--r-- | chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp | 81 |
1 files changed, 64 insertions, 17 deletions
diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp index d0a604d5317..01cc8673ace 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.cpp @@ -70,7 +70,18 @@ egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererV return egl::EglBadParameter() << "Failed to query AHardwareBuffer properties"; } - if (!HasFullTextureFormatSupport(renderer, bufferFormatProperties.format)) + if (bufferFormatProperties.format == VK_FORMAT_UNDEFINED) + { + ASSERT(bufferFormatProperties.externalFormat != 0); + // We must have an external format, check that it supports texture sampling + if (!(bufferFormatProperties.formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) + { + return egl::EglBadParameter() + << "Sampling from AHardwareBuffer externalFormat 0x" << std::hex + << bufferFormatProperties.externalFormat << " is unsupported "; + } + } + else if (!HasFullTextureFormatSupport(renderer, bufferFormatProperties.format)) { return egl::EglBadParameter() << "AHardwareBuffer format does not support enough features to use as a texture."; @@ -151,18 +162,35 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ANGLE_VK_TRY(displayVk, vkGetAndroidHardwareBufferPropertiesANDROID(device, hardwareBuffer, &bufferProperties)); - const vk::Format &vkFormat = renderer->getFormat(internalFormat); - const angle::Format &imageFormat = vkFormat.actualImageFormat(); VkExternalFormatANDROID externalFormat = {}; externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID; externalFormat.externalFormat = 0; + const vk::Format &vkFormat = renderer->getFormat(internalFormat); + const vk::Format &externalVkFormat = renderer->getFormat(angle::FormatID::NONE); + const angle::Format &imageFormat = vkFormat.actualImageFormat(); + bool isDepthOrStencilFormat = imageFormat.hasDepthOrStencilBits(); + + // Query AHB description and do the following - + // 1. Derive VkImageTiling mode based on AHB usage flags + // 2. Map AHB usage flags to VkImageUsageFlags + AHardwareBuffer_Desc ahbDescription; + AHardwareBuffer_describe(hardwareBuffer, &ahbDescription); + VkImageTiling imageTilingMode = AhbDescUsageToVkImageTiling(ahbDescription); + VkImageUsageFlags usage = AhbDescUsageToVkImageUsage(ahbDescription, isDepthOrStencilFormat); + if (bufferFormatProperties.format == VK_FORMAT_UNDEFINED) { externalFormat.externalFormat = bufferFormatProperties.externalFormat; + + // VkImageCreateInfo struct: If the pNext chain includes a VkExternalFormatANDROID structure + // whose externalFormat member is not 0, usage must not include any usages except + // VK_IMAGE_USAGE_SAMPLED_BIT + usage = VK_IMAGE_USAGE_SAMPLED_BIT; } VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {}; + externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; externalMemoryImageCreateInfo.pNext = &externalFormat; externalMemoryImageCreateInfo.handleTypes = @@ -173,19 +201,12 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk mImage = new vk::ImageHelper(); - // Query AHB description and do the following - - // 1. Derive VkImageTiling mode based on AHB usage flags - // 2. Map AHB usage flags to VkImageUsageFlags - AHardwareBuffer_Desc ahbDescription; - AHardwareBuffer_describe(hardwareBuffer, &ahbDescription); - VkImageTiling imageTilingMode = AhbDescUsageToVkImageTiling(ahbDescription); - VkImageUsageFlags usage = AhbDescUsageToVkImageUsage( - ahbDescription, (imageFormat.depthBits > 0 || imageFormat.stencilBits > 0)); - mImage->setTilingMode(imageTilingMode); ANGLE_TRY(mImage->initExternal( - displayVk, gl::TextureType::_2D, vkExtents, vkFormat, 1, usage, vk::kVkImageCreateFlagsNone, - vk::ImageLayout::ExternalPreInitialized, &externalMemoryImageCreateInfo, 0, 0, 1, 1)); + displayVk, gl::TextureType::_2D, vkExtents, + bufferFormatProperties.format == VK_FORMAT_UNDEFINED ? externalVkFormat : vkFormat, 1, + usage, vk::kVkImageCreateFlagsNone, vk::ImageLayout::ExternalPreInitialized, + &externalMemoryImageCreateInfo, 0, 0, 1, 1)); VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {}; importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID; @@ -203,9 +224,35 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk externalMemoryRequirements.memoryTypeBits = bufferProperties.memoryTypeBits; VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - ANGLE_TRY(mImage->initExternalMemory(displayVk, renderer->getMemoryProperties(), - externalMemoryRequirements, &dedicatedAllocInfo, - VK_QUEUE_FAMILY_FOREIGN_EXT, flags)); + if (bufferFormatProperties.format == VK_FORMAT_UNDEFINED) + { + // Note from Vulkan spec: Since GL_OES_EGL_image_external does not require the same sampling + // and conversion calculations as Vulkan does, achieving identical results between APIs may + // not be possible on some implementations. + ANGLE_VK_CHECK(displayVk, renderer->getFeatures().supportsYUVSamplerConversion.enabled, + VK_ERROR_FEATURE_NOT_PRESENT); + ASSERT(externalFormat.pNext == nullptr); + VkSamplerYcbcrConversionCreateInfo yuvConversionInfo = {}; + yuvConversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO; + yuvConversionInfo.pNext = &externalFormat; + yuvConversionInfo.format = VK_FORMAT_UNDEFINED; + yuvConversionInfo.xChromaOffset = bufferFormatProperties.suggestedXChromaOffset; + yuvConversionInfo.yChromaOffset = bufferFormatProperties.suggestedYChromaOffset; + yuvConversionInfo.ycbcrModel = bufferFormatProperties.suggestedYcbcrModel; + yuvConversionInfo.ycbcrRange = bufferFormatProperties.suggestedYcbcrRange; + yuvConversionInfo.chromaFilter = VK_FILTER_LINEAR; + yuvConversionInfo.components = bufferFormatProperties.samplerYcbcrConversionComponents; + + ANGLE_TRY(mImage->initExternalMemory( + displayVk, renderer->getMemoryProperties(), externalMemoryRequirements, + &yuvConversionInfo, &dedicatedAllocInfo, VK_QUEUE_FAMILY_FOREIGN_EXT, flags)); + } + else + { + ANGLE_TRY(mImage->initExternalMemory( + displayVk, renderer->getMemoryProperties(), externalMemoryRequirements, nullptr, + &dedicatedAllocInfo, VK_QUEUE_FAMILY_FOREIGN_EXT, flags)); + } constexpr uint32_t kColorRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; constexpr uint32_t kDepthStencilRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; |