Vulkan: Fix clear of specific mip level was clearing all mip levels

Bug: angleproject:2502
Change-Id: Iffa012dce14584318c4dfd3d9b3a304291c9cebf
Reviewed-on: https://chromium-review.googlesource.com/1070666
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 00cfb26..9a4de3f 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -210,7 +210,8 @@
         RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
         ASSERT(colorRenderTarget);
         vk::ImageHelper *image = colorRenderTarget->getImageForWrite(currentSerial, this);
-        image->clearColor(clearColorValue, commandBuffer);
+        GLint mipLevelToClear  = (attachment->type() == GL_TEXTURE) ? attachment->mipLevel() : 0;
+        image->clearColor(clearColorValue, mipLevelToClear, 1, commandBuffer);
     }
 
     return gl::NoError();
diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
index 098e8fd..6919c6b 100644
--- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
@@ -102,7 +102,7 @@
         }
         else
         {
-            mImage.clearColor(kBlackClearColorValue, commandBuffer);
+            mImage.clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
         }
     }
 
diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
index a865731..73b3415 100644
--- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
@@ -401,7 +401,7 @@
                                    gl::SwizzleState(), &member.imageView, 1);
 
         // Set transfer dest layout, and clear the image to black.
-        member.image.clearColor(transparentBlack, commandBuffer);
+        member.image.clearColor(transparentBlack, 0, 1, commandBuffer);
 
         ANGLE_TRY(member.imageAcquiredSemaphore.init(device));
         ANGLE_TRY(member.commandsCompleteSemaphore.init(device));
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 29ae179..742a399 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -855,7 +855,7 @@
 
     // TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
     VkClearColorValue black = {{0, 0, 0, 1.0f}};
-    mImage.clearColor(black, commandBuffer);
+    mImage.clearColor(black, 0, levelCount, commandBuffer);
     return vk::NoError();
 }
 
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 1b139db..6ce9256 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -770,7 +770,10 @@
     mCurrentLayout = newLayout;
 }
 
-void ImageHelper::clearColor(const VkClearColorValue &color, CommandBuffer *commandBuffer)
+void ImageHelper::clearColor(const VkClearColorValue &color,
+                             uint32_t mipLevel,
+                             uint32_t levelCount,
+                             CommandBuffer *commandBuffer)
 {
     ASSERT(valid());
 
@@ -780,8 +783,8 @@
 
     VkImageSubresourceRange range;
     range.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
-    range.baseMipLevel   = 0;
-    range.levelCount     = VK_REMAINING_MIP_LEVELS;
+    range.baseMipLevel   = mipLevel;
+    range.levelCount     = levelCount;
     range.baseArrayLayer = 0;
     range.layerCount     = mLayerCount;
 
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index dea2da0..ebee57f 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -219,7 +219,10 @@
                                 VkPipelineStageFlags dstStageMask,
                                 CommandBuffer *commandBuffer);
 
-    void clearColor(const VkClearColorValue &color, CommandBuffer *commandBuffer);
+    void clearColor(const VkClearColorValue &color,
+                    uint32_t mipLevel,
+                    uint32_t levelCount,
+                    CommandBuffer *commandBuffer);
 
     void clearDepthStencil(VkImageAspectFlags aspectFlags,
                            const VkClearDepthStencilValue &depthStencil,
diff --git a/src/tests/gl_tests/MipmapTest.cpp b/src/tests/gl_tests/MipmapTest.cpp
index d2fc2dd..052d2e1 100644
--- a/src/tests/gl_tests/MipmapTest.cpp
+++ b/src/tests/gl_tests/MipmapTest.cpp
@@ -520,9 +520,9 @@
 // In particular, on D3D11 Feature Level 9_3 it ensures that both the zero LOD workaround texture AND the 'normal' texture are copied during conversion.
 TEST_P(MipmapTest, GenerateMipmapFromInitDataThenRender)
 {
-    // TODO(lucferron): Figure out why we clear all levels when trying to clear level 0.
+    // TODO(lucferron): Figure out why this test is failing only on Intel Linux.
     // http://anglebug.com/2502
-    ANGLE_SKIP_TEST_IF(IsVulkan());
+    ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel());
 
     // Pass in initial data so the texture is blue.
     glBindTexture(GL_TEXTURE_2D, mTexture2D);
@@ -610,9 +610,9 @@
 // TODO: This test hits a texture rebind bug in the D3D11 renderer. Fix this.
 TEST_P(MipmapTest, RenderOntoLevelZeroAfterGenerateMipmap)
 {
-    // TODO(lucferron): Figure out why we clear all levels when trying to clear level 0.
+    // TODO(lucferron): Figure out why this test is failing only on Intel Linux.
     // http://anglebug.com/2502
-    ANGLE_SKIP_TEST_IF(IsVulkan());
+    ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel());
 
     // TODO(geofflang): Figure out why this is broken on AMD OpenGL
     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
@@ -701,8 +701,7 @@
 // works as expected. It tests enabling/disabling mipmaps, generating mipmaps, and rendering to level zero.
 TEST_P(MipmapTest, TextureCubeGeneralLevelZero)
 {
-    // TODO(lucferron): Implement mipmaps generation for cube textures
-    // http://anglebug.com/2502
+    // TODO(jmadill): Cube map attachments http://anglebug.com/2470
     ANGLE_SKIP_TEST_IF(IsVulkan());
 
     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);
@@ -743,8 +742,7 @@
 // This test ensures that rendering to level-zero of a TextureCube works as expected.
 TEST_P(MipmapTest, TextureCubeRenderToLevelZero)
 {
-    // TODO(lucferron): Implement mipmaps generation for cube textures
-    // http://anglebug.com/2502
+    // TODO(jmadill): Cube map attachments http://anglebug.com/2470
     ANGLE_SKIP_TEST_IF(IsVulkan());
 
     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube);