unified Vulkan uniform buffers

Bug: skia:
Change-Id: I0edb278546e00bf9aa0427578d1bcf41581cd12d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/234277
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/modules/particles/BUILD.gn b/modules/particles/BUILD.gn
index a4b8052..1573b72 100644
--- a/modules/particles/BUILD.gn
+++ b/modules/particles/BUILD.gn
@@ -25,5 +25,8 @@
     ]
     sources = skia_particle_sources
     configs += [ "../../:skia_private" ]
+    if (skia_enable_tools) {
+      configs += [ "../../:our_vulkan_headers" ]
+    }
   }
 }
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 8376542..345984f 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -16,6 +16,7 @@
 #include "src/gpu/vk/GrVkCaps.h"
 #include "src/gpu/vk/GrVkInterface.h"
 #include "src/gpu/vk/GrVkTexture.h"
+#include "src/gpu/vk/GrVkUniformHandler.h"
 #include "src/gpu/vk/GrVkUtil.h"
 
 #ifdef SK_BUILD_FOR_ANDROID
@@ -1557,6 +1558,14 @@
     return {GrColorType::kUnknown, 0};
 }
 
+int GrVkCaps::getFragmentUniformBinding() const {
+    return GrVkUniformHandler::kUniformBinding;
+}
+
+int GrVkCaps::getFragmentUniformSet() const {
+    return GrVkUniformHandler::kUniformBufferDescSet;
+}
+
 #if GR_TEST_UTILS
 std::vector<GrCaps::TestFormatColorTypeCombination> GrVkCaps::getTestingCombinations() const {
     std::vector<GrCaps::TestFormatColorTypeCombination> combos = {
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 21e5bfb..46a60f1 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -166,6 +166,9 @@
     GrSwizzle getTextureSwizzle(const GrBackendFormat&, GrColorType) const override;
     GrSwizzle getOutputSwizzle(const GrBackendFormat&, GrColorType) const override;
 
+    int getFragmentUniformBinding() const;
+    int getFragmentUniformSet() const;
+
 #if GR_TEST_UTILS
     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
 #endif
diff --git a/src/gpu/vk/GrVkDescriptorSetManager.cpp b/src/gpu/vk/GrVkDescriptorSetManager.cpp
index e926b10..5869ae6 100644
--- a/src/gpu/vk/GrVkDescriptorSetManager.cpp
+++ b/src/gpu/vk/GrVkDescriptorSetManager.cpp
@@ -17,16 +17,12 @@
 #endif
 
 GrVkDescriptorSetManager* GrVkDescriptorSetManager::CreateUniformManager(GrVkGpu* gpu) {
-    SkSTArray<2, uint32_t> visibilities;
-    // We set the visibility of the first binding to all supported geometry processing shader
-    // stages (vertex, tesselation, geometry, etc.) and the second binding to the fragment
-    // shader.
-    uint32_t geomStages = kVertex_GrShaderFlag;
+    SkSTArray<1, uint32_t> visibilities;
+    uint32_t stages = kVertex_GrShaderFlag | kFragment_GrShaderFlag;
     if (gpu->vkCaps().shaderCaps()->geometryShaderSupport()) {
-        geomStages |= kGeometry_GrShaderFlag;
+        stages |= kGeometry_GrShaderFlag;
     }
-    visibilities.push_back(geomStages);
-    visibilities.push_back(kFragment_GrShaderFlag);
+    visibilities.push_back(stages);
 
     SkTArray<const GrVkSampler*> samplers;
     return new GrVkDescriptorSetManager(gpu, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, visibilities,
@@ -243,28 +239,24 @@
         fDescCountPerSet = visibilities.count();
     } else {
         SkASSERT(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type);
-        GR_STATIC_ASSERT(2 == kUniformDescPerSet);
+        GR_STATIC_ASSERT(1 == kUniformDescPerSet);
         SkASSERT(kUniformDescPerSet == visibilities.count());
         // Create Uniform Buffer Descriptor
-        static const uint32_t bindings[kUniformDescPerSet] =
-                { GrVkUniformHandler::kGeometryBinding, GrVkUniformHandler::kFragBinding };
-        VkDescriptorSetLayoutBinding dsUniBindings[kUniformDescPerSet];
-        memset(&dsUniBindings, 0, kUniformDescPerSet * sizeof(VkDescriptorSetLayoutBinding));
-        for (int i = 0; i < kUniformDescPerSet; ++i) {
-            dsUniBindings[i].binding = bindings[i];
-            dsUniBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-            dsUniBindings[i].descriptorCount = 1;
-            dsUniBindings[i].stageFlags = visibility_to_vk_stage_flags(visibilities[i]);
-            dsUniBindings[i].pImmutableSamplers = nullptr;
-        }
+        VkDescriptorSetLayoutBinding dsUniBinding;
+        memset(&dsUniBinding, 0, sizeof(dsUniBinding));
+        dsUniBinding.binding = GrVkUniformHandler::kUniformBinding;
+        dsUniBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        dsUniBinding.descriptorCount = 1;
+        dsUniBinding.stageFlags = visibility_to_vk_stage_flags(visibilities[0]);
+        dsUniBinding.pImmutableSamplers = nullptr;
 
         VkDescriptorSetLayoutCreateInfo uniformLayoutCreateInfo;
         memset(&uniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
         uniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
         uniformLayoutCreateInfo.pNext = nullptr;
         uniformLayoutCreateInfo.flags = 0;
-        uniformLayoutCreateInfo.bindingCount = 2;
-        uniformLayoutCreateInfo.pBindings = dsUniBindings;
+        uniformLayoutCreateInfo.bindingCount = 1;
+        uniformLayoutCreateInfo.pBindings = &dsUniBinding;
 
 #if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
         // skia:8713
diff --git a/src/gpu/vk/GrVkDescriptorSetManager.h b/src/gpu/vk/GrVkDescriptorSetManager.h
index 0fff6da..767ca33 100644
--- a/src/gpu/vk/GrVkDescriptorSetManager.h
+++ b/src/gpu/vk/GrVkDescriptorSetManager.h
@@ -74,7 +74,7 @@
 
     private:
         enum {
-            kUniformDescPerSet = 2,
+            kUniformDescPerSet = 1,
             kMaxDescriptors = 1024,
             kStartNumDescriptors = 16, // must be less than kMaxUniformDescriptors
         };
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index e10780d..23e7eb5 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -33,8 +33,7 @@
         const GrVkDescriptorSetManager::Handle& samplerDSHandle,
         const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
         const UniformInfoArray& uniforms,
-        uint32_t geometryUniformSize,
-        uint32_t fragmentUniformSize,
+        uint32_t uniformSize,
         const UniformInfoArray& samplers,
         std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
         std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
@@ -49,13 +48,12 @@
         , fXferProcessor(std::move(xferProcessor))
         , fFragmentProcessors(std::move(fragmentProcessors))
         , fFragmentProcessorCnt(fragmentProcessorCnt)
-        , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
+        , fDataManager(uniforms, uniformSize) {
     fDescriptorSets[0] = VK_NULL_HANDLE;
     fDescriptorSets[1] = VK_NULL_HANDLE;
     fDescriptorSets[2] = VK_NULL_HANDLE;
 
-    fGeometryUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, geometryUniformSize));
-    fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize));
+    fUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, uniformSize));
 
     fNumSamplers = samplers.count();
 
@@ -77,14 +75,9 @@
         fPipeline = nullptr;
     }
 
-    if (fGeometryUniformBuffer) {
-        fGeometryUniformBuffer->release(gpu);
-        fGeometryUniformBuffer.reset();
-    }
-
-    if (fFragmentUniformBuffer) {
-        fFragmentUniformBuffer->release(gpu);
-        fFragmentUniformBuffer.reset();
+    if (fUniformBuffer) {
+        fUniformBuffer->release(gpu);
+        fUniformBuffer.reset();
     }
 
     if (fUniformDescriptorSet) {
@@ -104,14 +97,9 @@
         fPipeline = nullptr;
     }
 
-    if (fGeometryUniformBuffer) {
-        fGeometryUniformBuffer->abandon();
-        fGeometryUniformBuffer.reset();
-    }
-
-    if (fFragmentUniformBuffer) {
-        fFragmentUniformBuffer->abandon();
-        fFragmentUniformBuffer.reset();
+    if (fUniformBuffer) {
+        fUniformBuffer->abandon();
+        fUniformBuffer.reset();
     }
 
     if (fUniformDescriptorSet) {
@@ -154,10 +142,9 @@
     }
 
     // Get new descriptor set
-    if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
+    if (fUniformBuffer) {
         int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
-        if (fDataManager.uploadUniformBuffers(
-                    gpu, fGeometryUniformBuffer.get(), fFragmentUniformBuffer.get()) ||
+        if (fDataManager.uploadUniformBuffers(gpu, fUniformBuffer.get()) ||
             !fUniformDescriptorSet) {
             if (fUniformDescriptorSet) {
                 fUniformDescriptorSet->recycle(gpu);
@@ -171,11 +158,8 @@
         if (fUniformDescriptorSet) {
             commandBuffer->addRecycledResource(fUniformDescriptorSet);
         }
-        if (fGeometryUniformBuffer) {
-            commandBuffer->addRecycledResource(fGeometryUniformBuffer->resource());
-        }
-        if (fFragmentUniformBuffer) {
-            commandBuffer->addRecycledResource(fFragmentUniformBuffer->resource());
+        if (fUniformBuffer) {
+            commandBuffer->addRecycledResource(fUniformBuffer->resource());
         }
     }
 }
@@ -284,8 +268,7 @@
 void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
                                    VkDescriptorBufferInfo* bufferInfo,
                                    const GrVkUniformBuffer* buffer,
-                                   VkDescriptorSet descriptorSet,
-                                   uint32_t binding) {
+                                   VkDescriptorSet descriptorSet) {
 
     memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
     bufferInfo->buffer = buffer->buffer();
@@ -296,7 +279,7 @@
     descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
     descriptorWrite->pNext = nullptr;
     descriptorWrite->dstSet = descriptorSet;
-    descriptorWrite->dstBinding = binding;
+    descriptorWrite->dstBinding = GrVkUniformHandler::kUniformBinding;
     descriptorWrite->dstArrayElement = 0;
     descriptorWrite->descriptorCount = 1;
     descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -311,23 +294,11 @@
 
     uint32_t writeCount = 0;
 
-    // Geometry Uniform Buffer
-    if (fGeometryUniformBuffer.get()) {
+    if (fUniformBuffer.get()) {
         set_uniform_descriptor_writes(&descriptorWrites[writeCount],
                                       &bufferInfos[writeCount],
-                                      fGeometryUniformBuffer.get(),
-                                      fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
-                                      GrVkUniformHandler::kGeometryBinding);
-        ++writeCount;
-    }
-
-    // Fragment Uniform Buffer
-    if (fFragmentUniformBuffer.get()) {
-        set_uniform_descriptor_writes(&descriptorWrites[writeCount],
-                                      &bufferInfos[writeCount],
-                                      fFragmentUniformBuffer.get(),
-                                      fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
-                                      GrVkUniformHandler::kFragBinding);
+                                      fUniformBuffer.get(),
+                                      fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet]);
         ++writeCount;
     }
 
diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h
index 4da733f..9d6fe0f 100644
--- a/src/gpu/vk/GrVkPipelineState.h
+++ b/src/gpu/vk/GrVkPipelineState.h
@@ -44,8 +44,7 @@
             const GrVkDescriptorSetManager::Handle& samplerDSHandle,
             const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
             const UniformInfoArray& uniforms,
-            uint32_t geometryUniformSize,
-            uint32_t fragmentUniformSize,
+            uint32_t uniformSize,
             const UniformInfoArray& samplers,
             std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
             std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
@@ -131,8 +130,7 @@
 
     SkSTArray<4, const GrVkSampler*>   fImmutableSamplers;
 
-    std::unique_ptr<GrVkUniformBuffer> fGeometryUniformBuffer;
-    std::unique_ptr<GrVkUniformBuffer> fFragmentUniformBuffer;
+    std::unique_ptr<GrVkUniformBuffer> fUniformBuffer;
 
     // Tracks the current render target uniforms stored in the vertex buffer.
     RenderTargetState fRenderTargetState;
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index 43a9b3e..3fcb39b 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -198,6 +198,7 @@
     VkPipelineShaderStageCreateInfo shaderStageInfo[3];
     SkSL::Program::Settings settings;
     settings.fCaps = this->caps()->shaderCaps();
+    settings.fVkCaps = &this->gpu()->vkCaps();
     settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
     settings.fSharpenTextures =
                         this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
@@ -318,8 +319,7 @@
                                  samplerDSHandle,
                                  fUniformHandles,
                                  fUniformHandler.fUniforms,
-                                 fUniformHandler.fCurrentGeometryUBOOffset,
-                                 fUniformHandler.fCurrentFragmentUBOOffset,
+                                 fUniformHandler.fCurrentUBOOffset,
                                  fUniformHandler.fSamplers,
                                  std::move(fGeometryProcessor),
                                  std::move(fXferProcessor),
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.cpp b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
index 5e48441..cbef926 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.cpp
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
@@ -11,14 +11,10 @@
 #include "src/gpu/vk/GrVkUniformBuffer.h"
 
 GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
-                                                           uint32_t geometryUniformSize,
-                                                           uint32_t fragmentUniformSize)
-    : fGeometryUniformSize(geometryUniformSize)
-    , fFragmentUniformSize(fragmentUniformSize)
-    , fGeometryUniformsDirty(false)
-    , fFragmentUniformsDirty(false) {
-    fGeometryUniformData.reset(geometryUniformSize);
-    fFragmentUniformData.reset(fragmentUniformSize);
+                                                           uint32_t uniformSize)
+    : fUniformSize(uniformSize)
+    , fUniformsDirty(false) {
+    fUniformData.reset(uniformSize);
     int count = uniforms.count();
     fUniforms.push_back_n(count);
     // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
@@ -33,28 +29,13 @@
             uniform.fType = uniformInfo.fVariable.getType();
         )
 
-        if (!(kFragment_GrShaderFlag & uniformInfo.fVisibility)) {
-            uniform.fBinding = GrVkUniformHandler::kGeometryBinding;
-        } else {
-            SkASSERT(kFragment_GrShaderFlag == uniformInfo.fVisibility);
-            uniform.fBinding = GrVkUniformHandler::kFragBinding;
-        }
         uniform.fOffset = uniformInfo.fUBOffset;
     }
 }
 
 void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
-    void* buffer;
-    if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
-        buffer = fGeometryUniformData.get();
-        fGeometryUniformsDirty = true;
-    } else {
-        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
-        buffer = fFragmentUniformData.get();
-        fFragmentUniformsDirty = true;
-    }
-    buffer = static_cast<char*>(buffer)+uni.fOffset;
-    return buffer;
+    fUniformsDirty = true;
+    return static_cast<char*>(fUniformData.get())+uni.fOffset;
 }
 
 void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
@@ -324,15 +305,8 @@
     SkASSERT(arrayCount <= uni.fArrayCount ||
              (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
 
-    void* buffer;
-    if (GrVkUniformHandler::kGeometryBinding == uni.fBinding) {
-        buffer = fGeometryUniformData.get();
-        fGeometryUniformsDirty = true;
-    } else {
-        SkASSERT(GrVkUniformHandler::kFragBinding == uni.fBinding);
-        buffer = fFragmentUniformData.get();
-        fFragmentUniformsDirty = true;
-    }
+    void* buffer = fUniformData.get();
+    fUniformsDirty = true;
 
     set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
 }
@@ -360,18 +334,12 @@
 };
 
 bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
-                                                        GrVkUniformBuffer* geometryBuffer,
-                                                        GrVkUniformBuffer* fragmentBuffer) const {
+                                                        GrVkUniformBuffer* buffer) const {
     bool updatedBuffer = false;
-    if (geometryBuffer && fGeometryUniformsDirty) {
-        SkAssertResult(geometryBuffer->updateData(gpu, fGeometryUniformData.get(),
-                                                  fGeometryUniformSize, &updatedBuffer));
-        fGeometryUniformsDirty = false;
-    }
-    if (fragmentBuffer && fFragmentUniformsDirty) {
-        SkAssertResult(fragmentBuffer->updateData(gpu, fFragmentUniformData.get(),
-                                                  fFragmentUniformSize, &updatedBuffer));
-        fFragmentUniformsDirty = false;
+    if (buffer && fUniformsDirty) {
+        SkAssertResult(buffer->updateData(gpu, fUniformData.get(),
+                                          fUniformSize, &updatedBuffer));
+        fUniformsDirty = false;
     }
 
     return updatedBuffer;
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.h b/src/gpu/vk/GrVkPipelineStateDataManager.h
index 6a3b07f..91d5092 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.h
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.h
@@ -22,8 +22,7 @@
     typedef GrVkUniformHandler::UniformInfoArray UniformInfoArray;
 
     GrVkPipelineStateDataManager(const UniformInfoArray&,
-                                 uint32_t geometryUniformSize,
-                                 uint32_t fragmentUniformSize);
+                                 uint32_t uniformSize);
 
     void set1i(UniformHandle, int32_t) const override;
     void set1iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
@@ -60,11 +59,9 @@
     // VkBuffer object in order upload data. If true is returned, this is a signal to the caller
     // that they will need to update the descriptor set that is using these buffers.
     bool uploadUniformBuffers(GrVkGpu* gpu,
-                              GrVkUniformBuffer* geometryBuffer,
-                              GrVkUniformBuffer* fragmentBuffer) const;
+                              GrVkUniformBuffer* buffer) const;
 private:
     struct Uniform {
-        uint32_t fBinding;
         uint32_t fOffset;
         SkDEBUGCODE(
             GrSLType    fType;
@@ -77,15 +74,12 @@
 
     void* getBufferPtrAndMarkDirty(const Uniform& uni) const;
 
-    uint32_t fGeometryUniformSize;
-    uint32_t fFragmentUniformSize;
+    uint32_t fUniformSize;
 
     SkTArray<Uniform, true> fUniforms;
 
-    mutable SkAutoMalloc fGeometryUniformData;
-    mutable SkAutoMalloc fFragmentUniformData;
-    mutable bool         fGeometryUniformsDirty;
-    mutable bool         fFragmentUniformsDirty;
+    mutable SkAutoMalloc fUniformData;
+    mutable bool         fUniformsDirty;
 };
 
 #endif
diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp
index f1b62b0..a40aa6a 100644
--- a/src/gpu/vk/GrVkUniformHandler.cpp
+++ b/src/gpu/vk/GrVkUniformHandler.cpp
@@ -220,13 +220,7 @@
                                                                             int arrayCount,
                                                                             const char** outName) {
     SkASSERT(name && strlen(name));
-    // For now asserting the the visibility is either geometry types (vertex, tesselation, geometry,
-    // etc.) or only fragment.
-    SkASSERT(kVertex_GrShaderFlag == visibility ||
-             kGeometry_GrShaderFlag == visibility ||
-             (kVertex_GrShaderFlag | kGeometry_GrShaderFlag) == visibility ||
-             kFragment_GrShaderFlag == visibility);
-    GrSLTypeIsFloatType(type);
+    SkASSERT(GrSLTypeIsFloatType(type));
 
     UniformInfo& uni = fUniforms.push_back();
     uni.fVariable.setType(type);
@@ -247,15 +241,7 @@
     // we set the modifier to none for all uniforms declared inside the block.
     uni.fVariable.setTypeModifier(GrShaderVar::kNone_TypeModifier);
 
-    uint32_t* currentOffset;
-    uint32_t geomStages = kVertex_GrShaderFlag | kGeometry_GrShaderFlag;
-    if (geomStages & visibility) {
-        currentOffset = &fCurrentGeometryUBOOffset;
-    } else {
-        SkASSERT(kFragment_GrShaderFlag == visibility);
-        currentOffset = &fCurrentFragmentUBOOffset;
-    }
-    get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
+    get_ubo_aligned_offset(&uni.fUBOffset, &fCurrentUBOOffset, type, arrayCount);
 
     SkString layoutQualifier;
     layoutQualifier.appendf("offset=%d", uni.fUBOffset);
@@ -306,10 +292,6 @@
 }
 
 void GrVkUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
-    SkASSERT(kVertex_GrShaderFlag == visibility ||
-             kGeometry_GrShaderFlag == visibility ||
-             kFragment_GrShaderFlag == visibility);
-
     for (int i = 0; i < fSamplers.count(); ++i) {
         const UniformInfo& sampler = fSamplers[i];
         SkASSERT(sampler.fVariable.getType() == kTexture2DSampler_GrSLType);
@@ -320,27 +302,14 @@
     }
 
 #ifdef SK_DEBUG
-    bool firstGeomOffsetCheck = false;
-    bool firstFragOffsetCheck = false;
+    bool firstOffsetCheck = false;
     for (int i = 0; i < fUniforms.count(); ++i) {
         const UniformInfo& localUniform = fUniforms[i];
-        if (kVertex_GrShaderFlag == localUniform.fVisibility ||
-            kGeometry_GrShaderFlag == localUniform.fVisibility ||
-            (kVertex_GrShaderFlag | kGeometry_GrShaderFlag) == localUniform.fVisibility) {
-            if (!firstGeomOffsetCheck) {
-                // Check to make sure we are starting our offset at 0 so the offset qualifier we
-                // set on each variable in the uniform block is valid.
-                SkASSERT(0 == localUniform.fUBOffset);
-                firstGeomOffsetCheck = true;
-            }
-        } else {
-            SkASSERT(kFragment_GrShaderFlag == localUniform.fVisibility);
-            if (!firstFragOffsetCheck) {
-                // Check to make sure we are starting our offset at 0 so the offset qualifier we
-                // set on each variable in the uniform block is valid.
-                SkASSERT(0 == localUniform.fUBOffset);
-                firstFragOffsetCheck = true;
-            }
+        if (!firstOffsetCheck) {
+            // Check to make sure we are starting our offset at 0 so the offset qualifier we
+            // set on each variable in the uniform block is valid.
+            SkASSERT(0 == localUniform.fUBOffset);
+            firstOffsetCheck = true;
         }
     }
 #endif
@@ -357,21 +326,8 @@
     }
 
     if (!uniformsString.isEmpty()) {
-        uint32_t uniformBinding;
-        const char* stage;
-        if (kVertex_GrShaderFlag == visibility) {
-            uniformBinding = kGeometryBinding;
-            stage = "vertex";
-        } else if (kGeometry_GrShaderFlag == visibility) {
-            uniformBinding = kGeometryBinding;
-            stage = "geometry";
-        } else {
-            SkASSERT(kFragment_GrShaderFlag == visibility);
-            uniformBinding = kFragBinding;
-            stage = "fragment";
-        }
-        out->appendf("layout (set=%d, binding=%d) uniform %sUniformBuffer\n{\n",
-                     kUniformBufferDescSet, uniformBinding, stage);
+        out->appendf("layout (set=%d, binding=%d) uniform uniformBuffer\n{\n",
+                     kUniformBufferDescSet, kUniformBinding);
         out->appendf("%s\n};\n", uniformsString.c_str());
     }
 }
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index f280970..39ebac5 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -30,8 +30,7 @@
         kSamplerDescSet = 1,
     };
     enum {
-        kGeometryBinding = 0,
-        kFragBinding = 1,
+        kUniformBinding = 0
     };
 
     struct UniformInfo {
@@ -59,8 +58,7 @@
         : INHERITED(program)
         , fUniforms(kUniformsPerBlock)
         , fSamplers(kUniformsPerBlock)
-        , fCurrentGeometryUBOOffset(0)
-        , fCurrentFragmentUBOOffset(0) {
+        , fCurrentUBOOffset(0) {
     }
 
     UniformHandle internalAddUniformArray(uint32_t visibility,
@@ -93,10 +91,6 @@
 
     void appendUniformDecls(GrShaderFlags, SkString*) const override;
 
-    bool hasGeometryUniforms() const { return fCurrentGeometryUBOOffset > 0; }
-    bool hasFragmentUniforms() const { return fCurrentFragmentUBOOffset > 0; }
-
-
     const UniformInfo& getUniformInfo(UniformHandle u) const {
         return fUniforms[u.toIndex()];
     }
@@ -106,8 +100,7 @@
     UniformInfoArray    fSamplers;
     SkTArray<GrSwizzle> fSamplerSwizzles;
 
-    uint32_t            fCurrentGeometryUBOOffset;
-    uint32_t            fCurrentFragmentUBOOffset;
+    uint32_t            fCurrentUBOOffset;
 
     friend class GrVkPipelineStateBuilder;
     friend class GrVkDescriptorSetManager;
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index e2071c7..10f7a39 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -15,6 +15,10 @@
 #include "src/sksl/ir/SkSLIndexExpression.h"
 #include "src/sksl/ir/SkSLVariableReference.h"
 
+#ifdef SK_VULKAN
+#include "src/gpu/vk/GrVkCaps.h"
+#endif
+
 namespace SkSL {
 
 static const int32_t SKSL_MAGIC  = 0x0; // FIXME: we should probably register a magic number
@@ -1811,7 +1815,18 @@
             fields.emplace_back(Modifiers(), SKSL_RTHEIGHT_NAME, fContext.fFloat_Type.get());
             StringFragment name("sksl_synthetic_uniforms");
             Type intfStruct(-1, name, fields);
-            Layout layout(0, -1, -1, 1, -1, -1, -1, -1, Layout::Format::kUnspecified,
+            int binding;
+            int set;
+#ifdef SK_VULKAN
+            const GrVkCaps* vkCaps = fProgram.fSettings.fVkCaps;
+            SkASSERT(vkCaps);
+            binding = vkCaps->getFragmentUniformBinding();
+            set = vkCaps->getFragmentUniformSet();
+#else
+            binding = 0;
+            set = 0;
+#endif
+            Layout layout(0, -1, -1, binding, -1, set, -1, -1, Layout::Format::kUnspecified,
                           Layout::kUnspecified_Primitive, -1, -1, "", Layout::kNo_Key,
                           Layout::CType::kDefault);
             Variable* intfVar = (Variable*) fSynthetics.takeOwnership(std::unique_ptr<Symbol>(
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index b4397b9..293ae9d 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -19,6 +19,10 @@
 #include "src/sksl/ir/SkSLProgramElement.h"
 #include "src/sksl/ir/SkSLSymbolTable.h"
 
+#ifdef SK_VULKAN
+#include "src/gpu/vk/GrVkCaps.h"
+#endif
+
 // name of the render target width uniform
 #define SKSL_RTWIDTH_NAME "u_skRTWidth"
 
@@ -84,6 +88,9 @@
         const StandaloneShaderCaps* fCaps = &standaloneCaps;
 #else
         const GrShaderCaps* fCaps = nullptr;
+#ifdef SK_VULKAN
+        const GrVkCaps* fVkCaps = nullptr;
+#endif
 #endif
         // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
         // must be flipped.