Vulkan: Fix render target's tracking of content defined

Imagine the following scenario:

1. Clear draw framebuffer
2. Invalidate draw framebuffer
3. Update texture attached to draw framebuffer
4. Draw again into draw framebuffer

Step 3 could be a number of things, such as glCopyTex[Sub]Image,
glBlitFramebuffer, glTex[Sub]Image2D, glGenerateMipmap etc.

In the above scenario, at step 2, the framebuffer's render target
remembers it being invalidated (mContentDefined = false).  This is used
to set the loadOp of the next render pass to DONT_CARE.

However, mContentDefined was implemented for a very specific
optimization regarding the swapchain's depth buffer.  The reuse of this
variable for glInvalidateFramebuffer was erroneous as this variable
didn't track whether the contents are defined for the general case.

With this change, mContentDefined is set to true during
FramebufferVk::syncState for each render target whose contents are
marked dirty.

This change additionally makes glBlitFramebuffer signal the contents of
the blit targets as dirty, as well as textures that are used as storage
images.

Bug: angleproject:4859
Change-Id: I68c829f75ff4a3d03bb293ec72c609384983026d
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2309110
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
diff --git a/src/libANGLE/Context.inl.h b/src/libANGLE/Context.inl.h
index 96e9b02..486e3eb 100644
--- a/src/libANGLE/Context.inl.h
+++ b/src/libANGLE/Context.inl.h
@@ -46,16 +46,26 @@
     }
 }
 
-ANGLE_INLINE void MarkShaderStorageBufferUsage(const Context *context)
+ANGLE_INLINE void MarkShaderStorageUsage(const Context *context)
 {
     for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
     {
-        gl::Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
+        Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
         if (buffer)
         {
             buffer->onDataChanged();
         }
     }
+
+    for (size_t index : context->getStateCache().getActiveImageUnitIndices())
+    {
+        const ImageUnit &imageUnit = context->getState().getImageUnit(index);
+        const Texture *texture     = imageUnit.texture.get();
+        if (texture)
+        {
+            texture->onStateChange(angle::SubjectMessage::ContentsChanged);
+        }
+    }
 }
 
 // Return true if the draw is a no-op, else return false.