layers: Add DrawState check to verify that Pipeline layout from vkCmdBindDescriptorSets() matches layout from PSO at Draw time.

Also fix a bug where PSO status flags were not getting set into Cmd Buffer.
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 992c85d..3b50649 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -361,36 +361,18 @@
     loader_platform_thread_unlock_mutex(&globalLock);
 }
 // Check object status for selected flag state
-static bool32_t validate_status(VkCmdBuffer cb, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VkFlags msg_flags, DRAW_STATE_ERROR error_code, const char* fail_msg)
+static bool32_t validate_status(GLOBAL_CB_NODE* pNode, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VkFlags msg_flags, DRAW_STATE_ERROR error_code, const char* fail_msg)
 {
-    if (cmdBufferMap.find(cb) != cmdBufferMap.end()) {
-        GLOBAL_CB_NODE* pNode = cmdBufferMap[cb];
-        // If non-zero enable mask is present, check it against status but if enable_mask
-        //  is 0 then no enable required so we should always just check status
-        if ((!enable_mask) || (enable_mask & pNode->status)) {
-            if ((pNode->status & status_mask) != status_flag) {
-                log_msg(mdd(cb), msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, error_code, "DS",
-                        "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(cb), fail_msg);
-                return VK_FALSE;
-            }
+    // If non-zero enable mask is present, check it against status but if enable_mask
+    //  is 0 then no enable required so we should always just check status
+    if ((!enable_mask) || (enable_mask & pNode->status)) {
+        if ((pNode->status & status_mask) != status_flag) {
+            log_msg(mdd(pNode->cmdBuffer), msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, pNode->cmdBuffer, 0, error_code, "DS",
+                    "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(pNode->cmdBuffer), fail_msg);
+            return VK_FALSE;
         }
-        return VK_TRUE;
-    } else {
-        // If we do not find it print an error
-        log_msg(mdd(cb), msg_flags, (VkObjectType) 0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
-                "Unable to obtain status for non-existent CB object 0x%" PRIxLEAST64, reinterpret_cast<VkUintPtrLeast64>(cb));
-        return VK_FALSE;
     }
-}
-static bool32_t validate_draw_state_flags(VkCmdBuffer cb, bool32_t indexedDraw) {
-    bool32_t result;
-    result = validate_status(cb, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
-    result &= validate_status(cb, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND,   CBSTATUS_RASTER_BOUND,   VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_NOT_BOUND,   "Raster object not bound to this command buffer");
-    result &= validate_status(cb, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND,   CBSTATUS_COLOR_BLEND_BOUND,   VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_COLOR_BLEND_NOT_BOUND,   "Color-blend object not bound to this command buffer");
-    result &= validate_status(cb, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
-    if (indexedDraw)
-        result &= validate_status(cb, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, CBSTATUS_INDEX_BUFFER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound to this command buffer when Index Draw attempted");
-    return result;
+    return VK_TRUE;
 }
 // Print the last bound dynamic state
 static void printDynamicState(const VkCmdBuffer cb)
@@ -424,7 +406,30 @@
     loader_platform_thread_unlock_mutex(&globalLock);
     return pipelineMap[pipeline];
 }
-
+// Validate state stored as flags at time of draw call
+static bool32_t validate_draw_state_flags(GLOBAL_CB_NODE* pCB, bool32_t indexedDraw) {
+    bool32_t result;
+    result = validate_status(pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
+    result &= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND,   CBSTATUS_RASTER_BOUND,   VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_NOT_BOUND,   "Raster object not bound to this command buffer");
+    result &= validate_status(pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND,   CBSTATUS_COLOR_BLEND_BOUND,   VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_COLOR_BLEND_NOT_BOUND,   "Color-blend object not bound to this command buffer");
+    result &= validate_status(pCB, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_REPORT_ERROR_BIT,  DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
+    if (indexedDraw)
+        result &= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, CBSTATUS_INDEX_BUFFER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound to this command buffer when Index Draw attempted");
+    return result;
+}
+// Validate overall state at the time of a draw call
+static bool32_t validate_draw_state(GLOBAL_CB_NODE* pCB, bool32_t indexedDraw) {
+    // First check flag states
+    bool32_t result = validate_draw_state_flags(pCB, indexedDraw);
+    PIPELINE_NODE* pPipe = getPipeline(pCB->lastBoundPipeline);
+    // Now complete other state checks
+    if (pCB->lastBoundPipelineLayout != pPipe->graphicsPipelineCI.layout) {
+        result = VK_FALSE;
+        log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE_LAYOUT, pCB->lastBoundPipelineLayout, 0, DRAWSTATE_PIPELINE_LAYOUT_MISMATCH, "DS",
+                "Pipeline layout from last vkCmdBindDescriptorSets() (%s) does not match PSO Pipeline layout (%s)", pCB->lastBoundPipelineLayout, pPipe->graphicsPipelineCI.layout);
+    }
+    return result;
+}
 // For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
 static VkSamplerCreateInfo* getSamplerCreateInfo(const VkSampler sampler)
 {
@@ -2121,6 +2126,7 @@
             if (pPN) {
                 pCB->lastBoundPipeline = pipeline;
                 loader_platform_thread_lock_mutex(&globalLock);
+                set_cb_pso_status(pCB, pPN);
                 g_lastBoundPipeline = pPN;
                 loader_platform_thread_unlock_mutex(&globalLock);
                 validatePipelineState(pCB, pipelineBindPoint, pipeline);
@@ -2171,6 +2177,7 @@
                     if (getSetNode(pDescriptorSets[i])) {
                         loader_platform_thread_lock_mutex(&globalLock);
                         pCB->lastBoundDescriptorSet = pDescriptorSets[i];
+                        pCB->lastBoundPipelineLayout = layout;
                         pCB->boundDescriptorSets.push_back(pDescriptorSets[i]);
                         g_lastBoundDescriptorSet = pDescriptorSets[i];
                         loader_platform_thread_unlock_mutex(&globalLock);
@@ -2237,9 +2244,7 @@
             updateCBTracking(cmdBuffer);
             addCmd(pCB, CMD_DRAW);
             pCB->drawCount[DRAW]++;
-            loader_platform_thread_lock_mutex(&globalLock);
-            valid = validate_draw_state_flags(cmdBuffer, VK_FALSE);
-            loader_platform_thread_unlock_mutex(&globalLock);
+            valid = validate_draw_state(pCB, VK_FALSE);
             log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS",
                     "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
             synchAndPrintDSConfig(cmdBuffer);
@@ -2261,9 +2266,7 @@
             updateCBTracking(cmdBuffer);
             addCmd(pCB, CMD_DRAWINDEXED);
             pCB->drawCount[DRAW_INDEXED]++;
-            loader_platform_thread_lock_mutex(&globalLock);
-            valid = validate_draw_state_flags(cmdBuffer, VK_TRUE);
-            loader_platform_thread_unlock_mutex(&globalLock);
+            valid = validate_draw_state(pCB, VK_TRUE);
             log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS",
                     "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
             synchAndPrintDSConfig(cmdBuffer);
@@ -2285,9 +2288,7 @@
             updateCBTracking(cmdBuffer);
             addCmd(pCB, CMD_DRAWINDIRECT);
             pCB->drawCount[DRAW_INDIRECT]++;
-            loader_platform_thread_lock_mutex(&globalLock);
-            valid = validate_draw_state_flags(cmdBuffer, VK_FALSE);
-            loader_platform_thread_unlock_mutex(&globalLock);
+            valid = validate_draw_state(pCB, VK_FALSE);
             log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS",
                     "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
             synchAndPrintDSConfig(cmdBuffer);
@@ -2309,9 +2310,7 @@
             updateCBTracking(cmdBuffer);
             addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
             pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
-            loader_platform_thread_lock_mutex(&globalLock);
-            valid = validate_draw_state_flags(cmdBuffer, VK_TRUE);
-            loader_platform_thread_unlock_mutex(&globalLock);
+            valid = validate_draw_state(pCB, VK_TRUE);
             log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS",
                     "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
             synchAndPrintDSConfig(cmdBuffer);