diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2016-08-09 16:42:24 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2016-08-10 16:56:13 -0600 |
| commit | fe95850a199edf5afa78f31abce18d47c3a4b1de (patch) | |
| tree | 30774808309f570a7307db7265c978a5068b6bc8 | |
| parent | 80730868afdc2b0ba88f99c92f1c4612d349fc7f (diff) | |
| download | usermoji-fe95850a199edf5afa78f31abce18d47c3a4b1de.tar.xz | |
layers: GH790, Validate queue family at submit-time
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
| -rw-r--r-- | layers/core_validation.cpp | 33 | ||||
| -rw-r--r-- | layers/core_validation.h | 1 | ||||
| -rw-r--r-- | layers/core_validation_error_enums.h | 2 |
3 files changed, 36 insertions, 0 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index c04ec9fa..c681696b 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -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; } diff --git a/layers/core_validation.h b/layers/core_validation.h index 4d34c235..5dcafbb6 100644 --- a/layers/core_validation.h +++ b/layers/core_validation.h @@ -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; diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h index 058e95f5..56a8b2c1 100644 --- a/layers/core_validation_error_enums.h +++ b/layers/core_validation_error_enums.h @@ -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 }; |
