Make sure we aren't allocating more ycbcr desc sets in Vk than available.

Ycbcr images in vulkan can use anywhere from 1 to 3 descriptor set slots.
This comes from some gpus needing to internally treat the different
planes as different textures/samplers. So when you allocated a desc set
that includes a ycbcr image it may actually use up 3 desc set slots from
the pool. Nothing else changes in how we use the VkImage or descriptor
set. Just a matter of accounting for it in the pool.

Bug: b/192358244
Change-Id: I10dead981e59f0ebee54b76bdeabf968114d83b0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/422520
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
(cherry picked from commit bee1b55f30f445cf473531ab1894fba4098a6447)
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/423021
Reviewed-by: Derek Sollenberger <djsollen@google.com>
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 44c26c2..df9c0fb 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -147,6 +147,18 @@
     // Returns true if it supports ycbcr conversion for samplers
     bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
 
+    // Returns the number of descriptor slots used by immutable ycbcr VkImages.
+    //
+    // TODO: We should update this to return a count for a specific format or external format. We
+    // can use vkGetPhysicalDeviceImageFormatProperties2 with a
+    // VkSamplerYcbcrConversionImageFormatProperties to query this. However, right now that call
+    // does not support external android formats which is where the majority of ycbcr images are
+    // coming from. So for now we stay safe and always return 3 here which is the max value that the
+    // count could be for any format.
+    uint32_t ycbcrCombinedImageSamplerDescriptorCount() const {
+        return 3;
+    }
+
     // Returns true if the device supports protected memory.
     bool supportsProtectedMemory() const { return fSupportsProtectedMemory; }
 
diff --git a/src/gpu/vk/GrVkDescriptorSetManager.cpp b/src/gpu/vk/GrVkDescriptorSetManager.cpp
index ae99342..14cb1b0 100644
--- a/src/gpu/vk/GrVkDescriptorSetManager.cpp
+++ b/src/gpu/vk/GrVkDescriptorSetManager.cpp
@@ -78,6 +78,7 @@
         uint32_t numBindings = visibilities.count();
         std::unique_ptr<VkDescriptorSetLayoutBinding[]> dsSamplerBindings(
                 new VkDescriptorSetLayoutBinding[numBindings]);
+        *descCountPerSet = 0;
         for (uint32_t i = 0; i < numBindings; ++i) {
             uint32_t visibility = visibilities[i];
             dsSamplerBindings[i].binding = i;
@@ -86,8 +87,10 @@
             dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(visibility);
             if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type) {
                 if (immutableSamplers[i]) {
+                    (*descCountPerSet) += gpu->vkCaps().ycbcrCombinedImageSamplerDescriptorCount();
                     dsSamplerBindings[i].pImmutableSamplers = immutableSamplers[i]->samplerPtr();
                 } else {
+                    (*descCountPerSet)++;
                     dsSamplerBindings[i].pImmutableSamplers = nullptr;
                 }
             }
@@ -117,8 +120,6 @@
         if (result != VK_SUCCESS) {
             return false;
         }
-
-        *descCountPerSet = visibilities.count();
     } else if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
         static constexpr int kUniformDescPerSet = 1;
         SkASSERT(kUniformDescPerSet == visibilities.count());