aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Lobodzinski <mark@lunarg.com>2016-08-09 16:42:24 -0600
committerMark Lobodzinski <mark@lunarg.com>2016-08-10 16:56:13 -0600
commitfe95850a199edf5afa78f31abce18d47c3a4b1de (patch)
tree30774808309f570a7307db7265c978a5068b6bc8
parent80730868afdc2b0ba88f99c92f1c4612d349fc7f (diff)
downloadusermoji-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.cpp33
-rw-r--r--layers/core_validation.h1
-rw-r--r--layers/core_validation_error_enums.h2
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
};