layers: GH790, Validate queue family at submit-time
authorMark Lobodzinski <mark@lunarg.com>
Tue, 9 Aug 2016 22:42:24 +0000 (16:42 -0600)
committerMark Lobodzinski <mark@lunarg.com>
Wed, 10 Aug 2016 22:56:13 +0000 (16:56 -0600)
Command buffers must come from a command pool created with the same
queue family index as the queue they are submitted on.

Change-Id: Ifd1d73a09643c11852d807cb7edfc881827005dd

layers/core_validation.cpp
layers/core_validation.h
layers/core_validation_error_enums.h

index c04ec9f..c681696 100644 (file)
@@ -4682,6 +4682,25 @@ static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB
     return skip_call;
 }
 
+// Validate that queueFamilyIndices of primary command buffers match this queue
+// Secondary command buffers were previously validated in vkCmdExecuteCommands().
+static bool validateQueueFamilyIndices(layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkQueue queue) {
+    bool skip_call = false;
+    auto pPool = getCommandPoolNode(dev_data, pCB->createInfo.commandPool);
+    auto queue_node = getQueueNode(dev_data, queue);
+
+    if (pPool && queue_node && (pPool->queueFamilyIndex != queue_node->queueFamilyIndex)) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+            reinterpret_cast<uint64_t>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS",
+            "vkQueueSubmit: Primary command buffer 0x%" PRIxLEAST64
+            " created in queue family %d is being submitted on queue 0x%" PRIxLEAST64 " from queue family %d.",
+            reinterpret_cast<uint64_t>(pCB->commandBuffer), pPool->queueFamilyIndex,
+            reinterpret_cast<uint64_t>(queue), queue_node->queueFamilyIndex);
+    }
+
+    return skip_call;
+}
+
 static bool validatePrimaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
     // Track in-use for resources off of primary and any secondary CBs
     bool skip_call = false;
@@ -4831,6 +4850,7 @@ QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, V
 
                 pCBNode->submitCount++; // increment submit count
                 skip_call |= validatePrimaryCommandBufferState(dev_data, pCBNode);
+                skip_call |= validateQueueFamilyIndices(dev_data, pCBNode, queue);
                 // Call submit-time functions to validate/update state
                 for (auto &function : pCBNode->validate_functions) {
                     skip_call |= function();
@@ -5059,6 +5079,7 @@ VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyI
     if (result.second == true) {
         QUEUE_NODE *pQNode = &dev_data->queueMap[*pQueue];
         pQNode->queue = *pQueue;
+        pQNode->queueFamilyIndex = queueFamilyIndex;
     }
 }
 
@@ -9947,6 +9968,18 @@ static bool validateSecondaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_
                         queryPoolData->second.createInfo.queryType, reinterpret_cast<void *>(pSubCB->commandBuffer));
         }
     }
+
+    auto primary_pool = getCommandPoolNode(dev_data, pCB->createInfo.commandPool);
+    auto secondary_pool = getCommandPoolNode(dev_data, pSubCB->createInfo.commandPool);
+    if (primary_pool && secondary_pool && (primary_pool->queueFamilyIndex != secondary_pool->queueFamilyIndex)) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                             reinterpret_cast<uint64_t>(pSubCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS",
+                             "vkCmdExecuteCommands(): Primary command buffer 0x%" PRIxLEAST64
+                             " created in queue family %d has secondary command buffer 0x%" PRIxLEAST64 " created in queue family %d.",
+                             reinterpret_cast<uint64_t>(pCB->commandBuffer), primary_pool->queueFamilyIndex,
+                             reinterpret_cast<uint64_t>(pSubCB->commandBuffer), secondary_pool->queueFamilyIndex);
+    }
+
     return skip_call;
 }
 
index 4d34c23..5dcafbb 100644 (file)
@@ -236,6 +236,7 @@ class EVENT_NODE : public BASE_NODE {
 class QUEUE_NODE {
   public:
     VkQueue queue;
+    uint32_t queueFamilyIndex;
     std::vector<VkFence> lastFences;
     std::vector<CB_SUBMISSION> untrackedSubmissions;
     std::unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
index 058e95f..56a8b2c 100644 (file)
@@ -219,6 +219,8 @@ enum DRAW_STATE_ERROR {
                                              // must be a valid VkLogicOp value
     DRAWSTATE_INVALID_QUEUE_INDEX,           // Specified queue index exceeds number
                                              // of queried queue families
+    DRAWSTATE_INVALID_QUEUE_FAMILY,          // Command buffer submitted on queue is from
+                                             // a different queue family
     DRAWSTATE_PUSH_CONSTANTS_ERROR,          // Push constants exceed maxPushConstantSize
 };