Vulkan: Add PipelineDesc.

The PipelineDesc class is a 512-byte packed description of the entire
Vulkan pipeline state. It uses the alignas keyword and some static
asserts to verify that the structures are packed. This ensures that
when ANGLE uses MurmurHash to hash the entire struct, and memcmp to
check for identity, that there are no garbage padding bits.

This CL does not implement the Pipeline cache, but it will help, since
now we have a packed type that can be used as the key to a hash map.

Bug: angleproject:2163
Change-Id: I16efa927f08d30d89a9c4c8943edd211c6878ac8
Reviewed-on: https://chromium-review.googlesource.com/829893
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 6ce71d2..7f5587a 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -29,8 +29,6 @@
 {
     mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
     mCurrentArrayBufferResources.fill(nullptr);
-    mCurrentVertexBindingDescs.reserve(state.getMaxAttribs());
-    mCurrentVertexAttribDescs.reserve(state.getMaxAttribs());
 }
 
 VertexArrayVk::~VertexArrayVk()
@@ -131,11 +129,10 @@
 void VertexArrayVk::invalidateVertexDescriptions()
 {
     mCurrentVertexDescsValid = false;
-    mCurrentVertexBindingDescs.clear();
-    mCurrentVertexAttribDescs.clear();
 }
 
-void VertexArrayVk::updateVertexDescriptions(const gl::Context *context)
+void VertexArrayVk::updateVertexDescriptions(const gl::Context *context,
+                                             vk::PipelineDesc *pipelineDesc)
 {
     if (mCurrentVertexDescsValid)
     {
@@ -147,29 +144,16 @@
 
     const gl::Program *programGL = context->getGLState().getProgram();
 
+    pipelineDesc->resetVertexInputState();
+
     for (auto attribIndex : programGL->getActiveAttribLocationsMask())
     {
         const auto &attrib  = attribs[attribIndex];
         const auto &binding = bindings[attrib.bindingIndex];
         if (attrib.enabled)
         {
-            VkVertexInputBindingDescription bindingDesc;
-            bindingDesc.binding = static_cast<uint32_t>(mCurrentVertexBindingDescs.size());
-            bindingDesc.stride  = static_cast<uint32_t>(gl::ComputeVertexAttributeTypeSize(attrib));
-            bindingDesc.inputRate = (binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE
-                                                              : VK_VERTEX_INPUT_RATE_VERTEX);
-
-            gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
-
-            VkVertexInputAttributeDescription attribDesc;
-            attribDesc.binding  = bindingDesc.binding;
-            attribDesc.format   = vk::GetNativeVertexFormat(vertexFormatType);
-            attribDesc.location = static_cast<uint32_t>(attribIndex);
-            attribDesc.offset =
-                static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
-
-            mCurrentVertexBindingDescs.push_back(bindingDesc);
-            mCurrentVertexAttribDescs.push_back(attribDesc);
+            pipelineDesc->updateVertexInputInfo(static_cast<uint32_t>(attribIndex), binding,
+                                                attrib);
         }
         else
         {
@@ -180,14 +164,4 @@
     mCurrentVertexDescsValid = true;
 }
 
-const std::vector<VkVertexInputBindingDescription> &VertexArrayVk::getVertexBindingDescs() const
-{
-    return mCurrentVertexBindingDescs;
-}
-
-const std::vector<VkVertexInputAttributeDescription> &VertexArrayVk::getVertexAttribDescs() const
-{
-    return mCurrentVertexAttribDescs;
-}
-
 }  // namespace rx