Add support for OES_depth_texture

Note: Includes workaround for http://anglebug.com/3452 - some Android
devices do not indicate filtering support on VK_FORMAT_D16_UNORM.

Bug: angleproject:3103
Test: angle_end2end_tests --gtest_filter=DepthStencilFormatsTest.DepthTexture/*
angle_end2end_tests --gtest_filter=DepthStencilFormatsTest.PackedDepthStencil/*
angle_end2end_tests --gtest_filter=DepthStencilFormatsTest.DepthTextureRender/ES2_VULKAN

Change-Id: Ic325fb94ab0e619a17c2e149e0e0865fa4142f3a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1575426
Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index 0cdb05f..feb6d15 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -221,9 +221,7 @@
 
 ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
 
-ProgramVk::ProgramVk(const gl::ProgramState &state) : ProgramImpl(state), mUniformBlocksOffsets{}
-{
-}
+ProgramVk::ProgramVk(const gl::ProgramState &state) : ProgramImpl(state), mUniformBlocksOffsets{} {}
 
 ProgramVk::~ProgramVk() = default;
 
@@ -998,8 +996,10 @@
                 vk::CommandBuffer *srcLayoutChange;
                 ANGLE_TRY(image.recordCommands(contextVk, &srcLayoutChange));
 
-                image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT,
-                                   vk::ImageLayout::FragmentShaderReadOnly, srcLayoutChange);
+                VkImageAspectFlags aspectFlags = image.getAspectFlags();
+                ASSERT(aspectFlags != 0);
+                image.changeLayout(aspectFlags, vk::ImageLayout::FragmentShaderReadOnly,
+                                   srcLayoutChange);
             }
 
             image.addReadDependency(framebuffer);
@@ -1092,8 +1092,8 @@
             descSet = mEmptyDescriptorSets[descriptorSetIndex];
         }
 
-        constexpr uint32_t kShaderTypeMin = static_cast<uint32_t>(gl::kGLES2ShaderTypeMin);
-        constexpr uint32_t kShaderTypeMax = static_cast<uint32_t>(gl::kGLES2ShaderTypeMax);
+        constexpr uint32_t kShaderTypeMin   = static_cast<uint32_t>(gl::kGLES2ShaderTypeMin);
+        constexpr uint32_t kShaderTypeMax   = static_cast<uint32_t>(gl::kGLES2ShaderTypeMax);
         constexpr uint32_t kShaderTypeCount = kShaderTypeMax - kShaderTypeMin + 1;
 
         // Default uniforms are encompassed in a block per shader stage, and they are assigned
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index f46ff95..d8388a3 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -1320,6 +1320,11 @@
     {
         mFeatures.forceNonZeroScissor.enabled = true;
     }
+
+    if (IsAndroid() && IsQualcomm(mPhysicalDeviceProperties.vendorID))
+    {
+        mFeatures.forceD16TexFilter.enabled = true;
+    }
 }
 
 void RendererVk::initPipelineCacheVkKey()
@@ -2284,6 +2289,12 @@
 
         // Otherwise query the format features and cache it.
         vkGetPhysicalDeviceFormatProperties(mPhysicalDevice, format, &deviceProperties);
+        // Workaround for some Android devices that don't indicate filtering
+        // support on D16_UNORM and they should.
+        if (mFeatures.forceD16TexFilter.enabled && format == VK_FORMAT_D16_UNORM)
+        {
+            deviceProperties.*features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+        }
     }
 
     return deviceProperties.*features & featureBits;
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index d329907..27b4598 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -1340,7 +1340,7 @@
     // Lazily allocate the image view itself.
     // Note that these views are specifically made to be used as color attachments, and therefore
     // don't have swizzle.
-    return mImage->initLayerImageView(context, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
+    return mImage->initLayerImageView(context, mState.getType(), mImage->getAspectFlags(),
                                       gl::SwizzleState(), *imageViewOut, getNativeImageLevel(level),
                                       1, getNativeImageLayer(layer), 1);
 }
@@ -1357,14 +1357,18 @@
                                    const uint32_t levelCount,
                                    vk::CommandBuffer *commandBuffer)
 {
-    const RendererVk *renderer         = contextVk->getRenderer();
-    const angle::Format &textureFormat = format.imageFormat();
+    RendererVk *renderer = contextVk->getRenderer();
 
     VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                                         VK_IMAGE_USAGE_SAMPLED_BIT;
-
-    if (!textureFormat.isBlock)
+    if (renderer->hasImageFormatFeatureBits(format.vkImageFormat,
+                                            VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
+    {
+        imageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+    }
+    else if (renderer->hasImageFormatFeatureBits(format.vkImageFormat,
+                                                 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
     {
         imageUsageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
     }
@@ -1410,16 +1414,22 @@
     uint32_t baseLevel  = getNativeImageLevel(0);
     uint32_t baseLayer  = getNativeImageLayer(0);
     uint32_t layerCount = mState.getType() == gl::TextureType::CubeMap ? gl::kCubeFaceCount : 1;
+    VkImageAspectFlags aspectFlags = vk::GetFormatAspectFlags(format.angleFormat());
+    // If we are reading a depth buffer, select only the depth component/aspect
+    if (aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT)
+    {
+        aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
+    }
 
-    ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
-                                         mappedSwizzle, &mReadMipmapImageView, baseLevel,
-                                         levelCount, baseLayer, layerCount));
-    ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
-                                         mappedSwizzle, &mReadBaseLevelImageView, baseLevel, 1,
-                                         baseLayer, layerCount));
+    ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags, mappedSwizzle,
+                                         &mReadMipmapImageView, baseLevel, levelCount, baseLayer,
+                                         layerCount));
+    ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags, mappedSwizzle,
+                                         &mReadBaseLevelImageView, baseLevel, 1, baseLayer,
+                                         layerCount));
     if (!format.imageFormat().isBlock)
     {
-        ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), VK_IMAGE_ASPECT_COLOR_BIT,
+        ANGLE_TRY(mImage->initLayerImageView(contextVk, mState.getType(), aspectFlags,
                                              gl::SwizzleState(), &mDrawBaseLevelImageView,
                                              baseLevel, 1, baseLayer, layerCount));
     }
diff --git a/src/libANGLE/renderer/vulkan/vk_format_map.json b/src/libANGLE/renderer/vulkan/vk_format_map.json
index f6d0b26..f643025 100644
--- a/src/libANGLE/renderer/vulkan/vk_format_map.json
+++ b/src/libANGLE/renderer/vulkan/vk_format_map.json
@@ -224,6 +224,10 @@
             "buffer": "NONE",
             "image": "D24_UNORM_S8_UINT"
         },
+        "D32_UNORM": {
+            "buffer": "NONE",
+            "image": "D24_UNORM_S8_UINT"
+        },
         "ETC1_R8G8B8_UNORM_BLOCK": {
             "buffer": "NONE",
             "image": "ETC2_R8G8B8_UNORM_BLOCK"
diff --git a/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp b/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
index a49c852..4924520 100644
--- a/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp
@@ -695,7 +695,19 @@
             break;
 
         case angle::FormatID::D32_UNORM:
-            // This format is not implemented in Vulkan.
+            internalFormat = GL_DEPTH_COMPONENT32_OES;
+            {
+                static constexpr ImageFormatInitInfo kInfo[] = {
+                    {angle::FormatID::D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, nullptr},
+                    {angle::FormatID::D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, nullptr},
+                    {angle::FormatID::D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, nullptr}};
+                initImageFallback(renderer, kInfo, ArraySize(kInfo));
+            }
+            bufferFormatID               = angle::FormatID::NONE;
+            vkBufferFormat               = VK_FORMAT_UNDEFINED;
+            vkBufferFormatIsPacked       = false;
+            vertexLoadFunction           = nullptr;
+            vertexLoadRequiresConversion = true;
             break;
 
         case angle::FormatID::EAC_R11G11_SNORM_BLOCK:
diff --git a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
index 378f1db..b2bb0bf 100644
--- a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
@@ -321,15 +321,28 @@
             swizzleStateOut->swizzleAlpha = swizzleState.swizzleRed;
             break;
         default:
-            // Set any missing channel to default in case the emulated format has that channel.
-            swizzleStateOut->swizzleRed =
-                angleFormat.redBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
-            swizzleStateOut->swizzleGreen =
-                angleFormat.greenBits > 0 ? swizzleState.swizzleGreen : GL_ZERO;
-            swizzleStateOut->swizzleBlue =
-                angleFormat.blueBits > 0 ? swizzleState.swizzleBlue : GL_ZERO;
-            swizzleStateOut->swizzleAlpha =
-                angleFormat.alphaBits > 0 ? swizzleState.swizzleAlpha : GL_ONE;
+            if (angleFormat.hasDepthOrStencilBits())
+            {
+                swizzleStateOut->swizzleRed =
+                    angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
+                swizzleStateOut->swizzleGreen =
+                    angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
+                swizzleStateOut->swizzleBlue =
+                    angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
+                swizzleStateOut->swizzleAlpha = GL_ONE;
+            }
+            else
+            {
+                // Set any missing channel to default in case the emulated format has that channel.
+                swizzleStateOut->swizzleRed =
+                    angleFormat.redBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
+                swizzleStateOut->swizzleGreen =
+                    angleFormat.greenBits > 0 ? swizzleState.swizzleGreen : GL_ZERO;
+                swizzleStateOut->swizzleBlue =
+                    angleFormat.blueBits > 0 ? swizzleState.swizzleBlue : GL_ZERO;
+                swizzleStateOut->swizzleAlpha =
+                    angleFormat.alphaBits > 0 ? swizzleState.swizzleAlpha : GL_ONE;
+            }
             break;
     }
 }
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index bc6ad8a..7e094a9 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -1683,6 +1683,10 @@
 void ImageHelper::clearDepthStencil(VkImageAspectFlags imageAspectFlags,
                                     VkImageAspectFlags clearAspectFlags,
                                     const VkClearDepthStencilValue &depthStencil,
+                                    uint32_t baseMipLevel,
+                                    uint32_t levelCount,
+                                    uint32_t baseArrayLayer,
+                                    uint32_t layerCount,
                                     vk::CommandBuffer *commandBuffer)
 {
     ASSERT(valid());
@@ -1691,10 +1695,10 @@
 
     VkImageSubresourceRange clearRange = {
         /*aspectMask*/ clearAspectFlags,
-        /*baseMipLevel*/ 0,
-        /*levelCount*/ 1,
-        /*baseArrayLayer*/ 0,
-        /*layerCount*/ 1,
+        /*baseMipLevel*/ baseMipLevel,
+        /*levelCount*/ levelCount,
+        /*baseArrayLayer*/ baseArrayLayer,
+        /*layerCount*/ layerCount,
     };
 
     commandBuffer->clearDepthStencilImage(mImage, getCurrentLayout(), depthStencil, 1, &clearRange);
@@ -1711,9 +1715,9 @@
 
     if (isDepthStencil)
     {
-        ASSERT(mipLevel == 0 && baseArrayLayer == 0 && layerCount == 1);
         const VkImageAspectFlags aspect = vk::GetDepthStencilAspectFlags(mFormat->imageFormat());
-        clearDepthStencil(aspect, aspect, value.depthStencil, commandBuffer);
+        clearDepthStencil(aspect, aspect, value.depthStencil, mipLevel, 1, baseArrayLayer,
+                          layerCount, commandBuffer);
     }
     else
     {
@@ -1945,12 +1949,12 @@
     loadFunction.loadFunction(extents.width, extents.height, extents.depth, source, inputRowPitch,
                               inputDepthPitch, stagingPointer, outputRowPitch, outputDepthPitch);
 
-    VkBufferImageCopy copy = {};
+    VkBufferImageCopy copy         = {};
+    VkImageAspectFlags aspectFlags = GetFormatAspectFlags(vkFormat.imageFormat());
 
     copy.bufferOffset                    = stagingOffset;
     copy.bufferRowLength                 = bufferRowLength;
     copy.bufferImageHeight               = bufferImageHeight;
-    copy.imageSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
     copy.imageSubresource.mipLevel       = index.getLevelIndex();
     copy.imageSubresource.baseArrayLayer = index.hasLayer() ? index.getLayerIndex() : 0;
     copy.imageSubresource.layerCount     = index.getLayerCount();
@@ -1958,7 +1962,19 @@
     gl_vk::GetOffset(offset, &copy.imageOffset);
     gl_vk::GetExtent(extents, &copy.imageExtent);
 
-    mSubresourceUpdates.emplace_back(bufferHandle, copy);
+    // TODO: http://anglebug.com/3437 - need to split packed depth_stencil into
+    // staging buffers for upload.
+    // Ignore stencil for now.
+    if (aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT)
+    {
+        aspectFlags &= ~VK_IMAGE_ASPECT_STENCIL_BIT;
+    }
+
+    if (aspectFlags)
+    {
+        copy.imageSubresource.aspectMask = aspectFlags;
+        mSubresourceUpdates.emplace_back(bufferHandle, copy);
+    }
 
     return angle::Result::Continue;
 }
@@ -1984,6 +2000,9 @@
     copy.imageSubresource.baseArrayLayer = imageIndex.hasLayer() ? imageIndex.getLayerIndex() : 0;
     copy.imageSubresource.layerCount     = imageIndex.getLayerCount();
 
+    // Note: Only support color now
+    ASSERT(getAspectFlags() == VK_IMAGE_ASPECT_COLOR_BIT);
+
     gl_vk::GetOffset(offset, &copy.imageOffset);
     gl_vk::GetExtent(extents, &copy.imageExtent);
 
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index 9672faa..754bb98 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -754,6 +754,10 @@
     void clearDepthStencil(VkImageAspectFlags imageAspectFlags,
                            VkImageAspectFlags clearAspectFlags,
                            const VkClearDepthStencilValue &depthStencil,
+                           uint32_t baseMipLevel,
+                           uint32_t levelCount,
+                           uint32_t baseArrayLayer,
+                           uint32_t layerCount,
                            vk::CommandBuffer *commandBuffer);
 
     struct SubresourceUpdate