Vulkan: Use push constants in PipelineLayoutCache.

This removes the internal pipeline layout for the masked clear shaders.
Instead use the PipelineLayoutCache.

Bug: angleproject:2462
Change-Id: I8f8365b866098ece3e964fd12447dfdea55c20ba
Reviewed-on: https://chromium-review.googlesource.com/1090758
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 2fcf5a6..38f91fc 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -596,8 +596,17 @@
     ANGLE_TRY(shaderLibrary->getShader(renderer, vk::InternalShaderID::PushConstantColor_frag,
                                        &pushConstantColor));
 
-    const vk::PipelineLayout *pipelineLayout = nullptr;
-    ANGLE_TRY(renderer->getInternalPushConstantPipelineLayout(&pipelineLayout));
+    // The shader uses a simple pipeline layout with a push constant range.
+    vk::PipelineLayoutDesc pipelineLayoutDesc;
+    pipelineLayoutDesc.updatePushConstantRange(gl::ShaderType::Fragment, 0,
+                                               sizeof(VkClearColorValue));
+
+    // The shader does not use any descriptor sets.
+    vk::DescriptorSetLayoutPointerArray descriptorSetLayouts;
+
+    vk::BindingPointer<vk::PipelineLayout> pipelineLayout;
+    ANGLE_TRY(
+        renderer->getPipelineLayout(pipelineLayoutDesc, descriptorSetLayouts, &pipelineLayout));
 
     vk::RecordingMode recordingMode = vk::RecordingMode::Start;
     vk::CommandBuffer *drawCommands = nullptr;
@@ -630,15 +639,16 @@
     }
 
     vk::PipelineAndSerial *pipeline = nullptr;
-    ANGLE_TRY(renderer->getInternalPipeline(*fullScreenQuad, *pushConstantColor, *pipelineLayout,
-                                            pipelineDesc, gl::AttributesMask(), &pipeline));
+    ANGLE_TRY(renderer->getInternalPipeline(*fullScreenQuad, *pushConstantColor,
+                                            pipelineLayout.get(), pipelineDesc,
+                                            gl::AttributesMask(), &pipeline));
     pipeline->updateSerial(renderer->getCurrentQueueSerial());
 
     vk::CommandBuffer *writeCommands = nullptr;
     ANGLE_TRY(appendWriteResource(renderer, &writeCommands));
 
     VkClearColorValue clearColorValue = contextVk->getClearColorValue().color;
-    drawCommands->pushConstants(*pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0,
+    drawCommands->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0,
                                 sizeof(VkClearColorValue), clearColorValue.float32);
 
     // TODO(jmadill): Masked combined color and depth/stencil clear. http://anglebug.com/2455
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 2f435ab..e077de1 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -211,8 +211,6 @@
     mPipelineLayoutCache.destroy(mDevice);
     mDescriptorSetLayoutCache.destroy(mDevice);
 
-    mInternalPushConstantPipelineLayout.destroy(mDevice);
-
     mRenderPassCache.destroy(mDevice);
     mPipelineCache.destroy(mDevice);
     mShaderLibrary.destroy(mDevice);
@@ -834,34 +832,6 @@
     return vk::NoError();
 }
 
-vk::Error RendererVk::getInternalPushConstantPipelineLayout(
-    const vk::PipelineLayout **pipelineLayoutOut)
-{
-    *pipelineLayoutOut = &mInternalPushConstantPipelineLayout;
-    if (mInternalPushConstantPipelineLayout.valid())
-    {
-        return vk::NoError();
-    }
-
-    VkPushConstantRange pushConstantRange;
-    pushConstantRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
-    pushConstantRange.offset     = 0;
-    pushConstantRange.size       = sizeof(VkClearColorValue);
-
-    VkPipelineLayoutCreateInfo createInfo;
-    createInfo.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
-    createInfo.pNext                  = nullptr;
-    createInfo.flags                  = 0;
-    createInfo.setLayoutCount         = 0;
-    createInfo.pSetLayouts            = nullptr;
-    createInfo.pushConstantRangeCount = 1;
-    createInfo.pPushConstantRanges    = &pushConstantRange;
-
-    ANGLE_TRY(mInternalPushConstantPipelineLayout.init(mDevice, createInfo));
-
-    return vk::NoError();
-}
-
 Serial RendererVk::issueShaderSerial()
 {
     return mShaderSerialFactory.generate();
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.h b/src/libANGLE/renderer/vulkan/RendererVk.h
index d10854c..2dbee09 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.h
+++ b/src/libANGLE/renderer/vulkan/RendererVk.h
@@ -132,10 +132,6 @@
     // TODO(jmadill): Keep in ContextVk to enable threaded rendering.
     vk::CommandGraph *getCommandGraph();
 
-    // Used in internal shaders.
-    // TODO(jmadill): Use PipelineLayout cache. http://anglebug.com/2462
-    vk::Error getInternalPushConstantPipelineLayout(const vk::PipelineLayout **pipelineLayoutOut);
-
     // Issues a new serial for linked shader modules. Used in the pipeline cache.
     Serial issueShaderSerial();
 
@@ -200,10 +196,6 @@
     // DescriptorSetLayouts are also managed in a cache.
     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
 
-    // Used for internal shaders.
-    // TODO(jmadill): Use PipelineLayout cache. http://anglebug.com/2462
-    vk::PipelineLayout mInternalPushConstantPipelineLayout;
-
     // Internal shader library.
     vk::ShaderLibrary mShaderLibrary;
 };
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
index 24ebc1d..1a49f00 100644
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
@@ -1214,24 +1214,43 @@
     angle::FixedVector<VkDescriptorSetLayout, vk::kMaxDescriptorSetLayouts> setLayoutHandles;
     for (const vk::BindingPointer<vk::DescriptorSetLayout> &layoutPtr : descriptorSetLayouts)
     {
-        VkDescriptorSetLayout setLayout = layoutPtr.get().getHandle();
-        if (setLayout != VK_NULL_HANDLE)
+        if (layoutPtr.valid())
         {
-            setLayoutHandles.push_back(setLayout);
+            VkDescriptorSetLayout setLayout = layoutPtr.get().getHandle();
+            if (setLayout != VK_NULL_HANDLE)
+            {
+                setLayoutHandles.push_back(setLayout);
+            }
+        }
+    }
+
+    angle::FixedVector<VkPushConstantRange, vk::kMaxPushConstantRanges> pushConstantRanges;
+    const vk::PushConstantRangeArray<vk::PackedPushConstantRange> &descPushConstantRanges =
+        desc.getPushConstantRanges();
+    for (size_t shaderIndex = 0; shaderIndex < descPushConstantRanges.size(); ++shaderIndex)
+    {
+        const vk::PackedPushConstantRange &pushConstantDesc = descPushConstantRanges[shaderIndex];
+        if (pushConstantDesc.size > 0)
+        {
+            VkPushConstantRange pushConstantRange;
+            pushConstantRange.stageFlags =
+                shaderIndex == 0 ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT;
+            pushConstantRange.offset = pushConstantDesc.offset;
+            pushConstantRange.size   = pushConstantDesc.size;
+
+            pushConstantRanges.push_back(pushConstantRange);
         }
     }
 
     // No pipeline layout found. We must create a new one.
     VkPipelineLayoutCreateInfo createInfo;
-    createInfo.sType          = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
-    createInfo.pNext          = nullptr;
-    createInfo.flags          = 0;
-    createInfo.setLayoutCount = static_cast<uint32_t>(setLayoutHandles.size());
-    createInfo.pSetLayouts    = setLayoutHandles.data();
-
-    // TODO(jmadill): Init push constant ranges. http://anglebug.com/2462
-    createInfo.pushConstantRangeCount = 0;
-    createInfo.pPushConstantRanges    = nullptr;
+    createInfo.sType                  = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    createInfo.pNext                  = nullptr;
+    createInfo.flags                  = 0;
+    createInfo.setLayoutCount         = static_cast<uint32_t>(setLayoutHandles.size());
+    createInfo.pSetLayouts            = setLayoutHandles.data();
+    createInfo.pushConstantRangeCount = static_cast<uint32_t>(pushConstantRanges.size());
+    createInfo.pPushConstantRanges    = pushConstantRanges.data();
 
     vk::PipelineLayout newLayout;
     ANGLE_TRY(newLayout.init(device, createInfo));