Vulkan: Fix UtilsVk invalidating Context descriptors.

Fixes a validation error and rendering artifact in the WebGL test:
textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view

Only applies to masked clears when combined with draw calls using
uniforms or textures.

Also make it easier to inspect layer messages in the debugger.

Bug: angleproject:2912
Change-Id: I4561895439221581b9dbc341d6de5d5a6c2096aa
Reviewed-on: https://chromium-review.googlesource.com/c/1462056
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index cda4488..79e1f37 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -226,11 +226,11 @@
     // TODO(jmadill): Use dirty bit. http://anglebug.com/3014
     if (!mCommandBuffer)
     {
+        mDirtyBits |= mNewCommandBufferDirtyBits;
         if (!mDrawFramebuffer->appendToStartedRenderPass(mRenderer->getCurrentQueueSerial(),
                                                          &mCommandBuffer))
         {
             ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, &mCommandBuffer));
-            mDirtyBits |= mNewCommandBufferDirtyBits;
         }
     }
 
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 79a241a..9ce020a 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -288,15 +288,16 @@
         }
     }
 
-    bool isError = (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0;
+    bool isError    = (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0;
+    std::string msg = log.str();
 
     if (isError)
     {
-        ERR() << log.str();
+        ERR() << msg;
     }
     else
     {
-        WARN() << log.str();
+        WARN() << msg;
     }
 
     return VK_FALSE;
diff --git a/src/tests/gl_tests/ClearTest.cpp b/src/tests/gl_tests/ClearTest.cpp
index 1c62f66..9378eae 100644
--- a/src/tests/gl_tests/ClearTest.cpp
+++ b/src/tests/gl_tests/ClearTest.cpp
@@ -152,8 +152,6 @@
         ASSERT_GL_NO_ERROR();
     }
 
-    void TearDown() override { ANGLETest::TearDown(); }
-
     void bindColorStencilFBO()
     {
         glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
@@ -424,6 +422,57 @@
     }
 }
 
+// Covers a bug in the Vulkan back-end where starting a new command buffer in
+// the masked clear would not trigger descriptor sets to be re-bound.
+TEST_P(ClearTest, MaskedClearThenDrawWithUniform)
+{
+    // Initialize a program with a uniform.
+    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
+    glUseProgram(program);
+
+    GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());
+    ASSERT_NE(-1, uniLoc);
+    glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);
+
+    // Initialize position attribute.
+    GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
+    ASSERT_NE(-1, posLoc);
+    setupQuadVertexBuffer(0.5f, 1.0f);
+    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+    glEnableVertexAttribArray(posLoc);
+
+    // Initialize a simple FBO.
+    constexpr GLsizei kSize = 2;
+    GLTexture clearTexture;
+    glBindTexture(GL_TEXTURE_2D, clearTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    GLFramebuffer fbo;
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);
+
+    glViewport(0, 0, kSize, kSize);
+
+    // Clear and draw to flush out dirty bits.
+    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+
+    // Flush to trigger a new serial.
+    glFlush();
+
+    // Enable color mask and draw again to trigger the bug.
+    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+
+    ASSERT_GL_NO_ERROR();
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
 // Requires ES3
 // This tests a bug where in a masked clear when calling "ClearBuffer", we would
 // mistakenly clear every channel (including the masked-out ones)