From fe95850a199edf5afa78f31abce18d47c3a4b1de Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Tue, 9 Aug 2016 16:42:24 -0600 Subject: 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 --- layers/core_validation.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'layers/core_validation.cpp') 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(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(pCB->commandBuffer), pPool->queueFamilyIndex, + reinterpret_cast(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(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(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(pCB->commandBuffer), primary_pool->queueFamilyIndex, + reinterpret_cast(pSubCB->commandBuffer), secondary_pool->queueFamilyIndex); + } + return skip_call; } -- cgit v1.2.3