aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Kraus <petr_kraus@email.cz>2017-05-08 23:45:36 +0200
committerMark Lobodzinski <mark@lunarg.com>2017-05-11 15:30:02 -0600
commit358d80f303f54e02ab7606dfb3b4b379f3f42453 (patch)
treea13b9190ada2cfff1e1168133febb2632bc4789a
parent2b8725c2e537ba0c5606dd34967928db760d865e (diff)
downloadusermoji-358d80f303f54e02ab7606dfb3b4b379f3f42453.tar.xz
layers: Update DeviceQueueCreate checks
- remove some potential false-positives from QF check - update error db with existing check - use error db unique codes on existing checks - move check that need state to core_validation - deal with VK_QUEUE_FAMILY_IGNORED case - improve error messages texts - make messages return appropriate object - move code that looks displaced to appropriate places - add locks
-rw-r--r--layers/core_validation.cpp239
-rw-r--r--layers/core_validation.h2
-rw-r--r--layers/parameter_validation.cpp254
-rw-r--r--layers/vk_validation_error_database.txt8
4 files changed, 286 insertions, 217 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 50030c94..29fe53fa 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -50,6 +50,7 @@
#include <string.h>
#include <string>
#include <tuple>
+#include <inttypes.h>
#include "vk_loader_platform.h"
#include "vk_dispatch_table_helper.h"
@@ -79,6 +80,19 @@
}
#endif
+// TODO: remove on NDK update (r15 will probably have proper STL impl)
+#ifdef __ANDROID__
+namespace std {
+
+template <typename T>
+std::string to_string(T var) {
+ std::ostringstream ss;
+ ss << var;
+ return ss.str();
+}
+}
+#endif
+
// This intentionally includes a cpp file
#include "vk_safe_struct.cpp"
@@ -3428,54 +3442,81 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
layer_data_map.erase(key);
}
-// Verify that queue family has been properly requested
-static bool ValidateRequestedQueueFamilyProperties(instance_layer_data *instance_data, VkPhysicalDevice gpu,
- const VkDeviceCreateInfo *create_info) {
+static bool ValidatePhysicalDeviceQueueFamily(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state,
+ uint32_t requested_queue_family, int32_t err_code, const char *cmd_name,
+ const char *queue_family_var_name, const char *vu_note = nullptr) {
bool skip = false;
- auto physical_device_state = GetPhysicalDeviceState(instance_data, gpu);
- // First check is app has actually requested queueFamilyProperties
- if (!physical_device_state) {
+
+ if (!vu_note) vu_note = validation_error_map[err_code];
+
+ const char *conditional_ext_cmd =
+ instance_data->extensions.khr_get_physical_device_properties2 ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR" : "";
+
+ std::string count_note = (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState)
+ ? "the pQueueFamilyPropertyCount was never obtained"
+ : "i.e. is not less than " + std::to_string(pd_state->queue_family_count);
+
+ if (requested_queue_family >= pd_state->queue_family_count) {
skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
- 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
- "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
- } else if (QUERY_DETAILS != physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
- // TODO: This is not called out as an invalid use in the spec so make more informative recommendation.
- skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, VALIDATION_ERROR_00054, "DL",
- "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties(). %s",
- validation_error_map[VALIDATION_ERROR_00054]);
- } else {
- // Check that the requested queue properties are valid
- for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
- uint32_t requestedIndex = create_info->pQueueCreateInfos[i].queueFamilyIndex;
- if (requestedIndex >= physical_device_state->queue_family_properties.size()) {
- skip |= log_msg(
- instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
- __LINE__, VALIDATION_ERROR_00054, "DL",
- "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested. %s", requestedIndex,
- validation_error_map[VALIDATION_ERROR_00054]);
- } else if (create_info->pQueueCreateInfos[i].queueCount >
- physical_device_state->queue_family_properties[requestedIndex].queueCount) {
+ reinterpret_cast<uint64_t>(pd_state->phys_device), __LINE__, err_code, "DL",
+ "%s: %s (=%" PRIu32 ") is not less than any previously obtained pQueueFamilyPropertyCount from "
+ "vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s",
+ cmd_name, queue_family_var_name, requested_queue_family, conditional_ext_cmd, count_note.c_str(), vu_note);
+ }
+ return skip;
+}
+
+// Verify VkDeviceQueueCreateInfos
+static bool ValidateDeviceQueueCreateInfos(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state,
+ uint32_t info_count, const VkDeviceQueueCreateInfo *infos) {
+ bool skip = false;
+
+ for (uint32_t i = 0; i < info_count; ++i) {
+ const auto requested_queue_family = infos[i].queueFamilyIndex;
+
+ // Verify that requested queue family is known to be valid at this point in time
+ std::string queue_family_var_name = "pCreateInfo->pQueueCreateInfos[" + std::to_string(i) + "].queueFamilyIndex";
+ skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, requested_queue_family, VALIDATION_ERROR_00054,
+ "vkCreateDevice", queue_family_var_name.c_str());
+
+ // Verify that requested queue count of queue family is known to be valid at this point in time
+ if (requested_queue_family < pd_state->queue_family_count) {
+ const auto requested_queue_count = infos[i].queueCount;
+ const auto queue_family_props_count = pd_state->queue_family_properties.size();
+ const bool queue_family_has_props = requested_queue_family < queue_family_props_count;
+ const char *conditional_ext_cmd = instance_data->extensions.khr_get_physical_device_properties2
+ ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR"
+ : "";
+ std::string count_note =
+ !queue_family_has_props
+ ? "the pQueueFamilyProperties[" + std::to_string(requested_queue_family) + "] was never obtained"
+ : "i.e. is not less than or equal to " +
+ std::to_string(pd_state->queue_family_properties[requested_queue_family].queueCount);
+
+ if (!queue_family_has_props ||
+ requested_queue_count > pd_state->queue_family_properties[requested_queue_family].queueCount) {
skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__,
- VALIDATION_ERROR_02055, "DL",
- "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
- "requested queueCount is %u. %s",
- requestedIndex, physical_device_state->queue_family_properties[requestedIndex].queueCount,
- create_info->pQueueCreateInfos[i].queueCount, validation_error_map[VALIDATION_ERROR_02055]);
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, reinterpret_cast<uint64_t>(pd_state->phys_device),
+ __LINE__, VALIDATION_ERROR_02055, "DL",
+ "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueCount (=%" PRIu32 ") is not "
+ "less than or equal to available queue count for this "
+ "pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex} (=%" PRIu32 ") obtained previously "
+ "from vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s",
+ i, requested_queue_count, i, requested_queue_family, conditional_ext_cmd, count_note.c_str(),
+ validation_error_map[VALIDATION_ERROR_02055]);
}
}
}
+
return skip;
}
// Verify that features have been queried and that they are available
-static bool ValidateRequestedFeatures(instance_layer_data *dev_data, VkPhysicalDevice phys,
+static bool ValidateRequestedFeatures(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state,
const VkPhysicalDeviceFeatures *requested_features) {
bool skip = false;
- auto phys_device_state = GetPhysicalDeviceState(dev_data, phys);
- const VkBool32 *actual = reinterpret_cast<VkBool32 *>(&phys_device_state->features);
+ const VkBool32 *actual = reinterpret_cast<const VkBool32 *>(&pd_state->features);
const VkBool32 *requested = reinterpret_cast<const VkBool32 *>(requested_features);
// TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
// Need to provide the struct member name with the issue. To do that seems like we'll
@@ -3485,19 +3526,19 @@ static bool ValidateRequestedFeatures(instance_layer_data *dev_data, VkPhysicalD
for (uint32_t i = 0; i < total_bools; i++) {
if (requested[i] > actual[i]) {
// TODO: Add index to struct member name helper to be able to include a feature name
- skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
- 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
"While calling vkCreateDevice(), requesting feature #%u in VkPhysicalDeviceFeatures struct, "
"which is not available on this device.",
i);
errors++;
}
}
- if (errors && (UNCALLED == phys_device_state->vkGetPhysicalDeviceFeaturesState)) {
+ if (errors && (UNCALLED == pd_state->vkGetPhysicalDeviceFeaturesState)) {
// If user didn't request features, notify them that they should
// TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error
- skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
- __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+ 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL",
"You requested features that are unavailable on this device. You should first query feature "
"availability by calling vkGetPhysicalDeviceFeatures().");
}
@@ -3506,18 +3547,19 @@ static bool ValidateRequestedFeatures(instance_layer_data *dev_data, VkPhysicalD
VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
- instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map);
bool skip = false;
+ instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map);
+ auto pd_state = GetPhysicalDeviceState(instance_data, gpu);
+ std::unique_lock<std::mutex> lock(global_lock);
// Check that any requested features are available
if (pCreateInfo->pEnabledFeatures) {
- skip |= ValidateRequestedFeatures(instance_data, gpu, pCreateInfo->pEnabledFeatures);
+ skip |= ValidateRequestedFeatures(instance_data, pd_state, pCreateInfo->pEnabledFeatures);
}
- skip |= ValidateRequestedQueueFamilyProperties(instance_data, gpu, pCreateInfo);
+ skip |=
+ ValidateDeviceQueueCreateInfos(instance_data, pd_state, pCreateInfo->queueCreateInfoCount, pCreateInfo->pQueueCreateInfos);
- if (skip) {
- return VK_ERROR_VALIDATION_FAILED_EXT;
- }
+ if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
@@ -3532,12 +3574,14 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDevice
// Advance the link info for the next element on the chain
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+ lock.unlock();
+
VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
if (result != VK_SUCCESS) {
return result;
}
- std::unique_lock<std::mutex> lock(global_lock);
+ lock.lock();
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
device_data->instance_data = instance_data;
@@ -10808,41 +10852,41 @@ VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uin
// Common function to handle validation for GetPhysicalDeviceQueueFamilyProperties & 2KHR version
static bool ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data,
PHYSICAL_DEVICE_STATE *pd_state,
- uint32_t *pQueueFamilyPropertyCount, bool qfp_null,
- const char *count_var_name, const char *caller_name) {
+ uint32_t requested_queue_family_property_count, bool qfp_null,
+ const char *caller_name) {
bool skip = false;
- if (qfp_null) {
- pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
- } else {
- // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to get
- // count
+ if (!qfp_null) {
+ // Verify that for each physical device, this command is called first with NULL pQueueFamilyProperties in order to get count
if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
- skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
- "Call sequence has %s() w/ non-NULL "
- "pQueueFamilyProperties. You should first call %s() w/ "
- "NULL pQueueFamilyProperties to query pCount.",
- caller_name, caller_name);
- }
- // Then verify that pCount that is passed in on second call matches what was returned
- if (pd_state->queueFamilyPropertiesCount != *pQueueFamilyPropertyCount) {
- // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
- // provide as warning
- skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
- "Call to %s() w/ %s value %u, but actual count supported by this physicalDevice is %u.", caller_name,
- count_var_name, *pQueueFamilyPropertyCount, pd_state->queueFamilyPropertiesCount);
+ skip |= log_msg(
+ instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+ reinterpret_cast<uint64_t>(pd_state->phys_device), __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
+ "%s is called with non-NULL pQueueFamilyProperties before obtaining pQueueFamilyPropertyCount. It is recommended "
+ "to first call %s with NULL pQueueFamilyProperties in order to obtain the maximal pQueueFamilyPropertyCount.",
+ caller_name, caller_name);
+ // Then verify that pCount that is passed in on second call matches what was returned
+ } else if (pd_state->queue_family_count != requested_queue_family_property_count) {
+ skip |= log_msg(
+ instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+ reinterpret_cast<uint64_t>(pd_state->phys_device), __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
+ "%s is called with non-NULL pQueueFamilyProperties and pQueueFamilyPropertyCount value %" PRIu32
+ ", but the largest previously returned pQueueFamilyPropertyCount for this physicalDevice is %" PRIu32
+ ". It is recommended to instead receive all the properties by calling %s with pQueueFamilyPropertyCount that was "
+ "previously obtained by calling %s with NULL pQueueFamilyProperties.",
+ caller_name, requested_queue_family_property_count, pd_state->queue_family_count, caller_name, caller_name);
}
pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
}
+
return skip;
}
static bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data,
- PHYSICAL_DEVICE_STATE *pd_state, uint32_t *pCount,
+ PHYSICAL_DEVICE_STATE *pd_state,
+ uint32_t *pQueueFamilyPropertyCount,
VkQueueFamilyProperties *pQueueFamilyProperties) {
- return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, pCount,
- (nullptr == pQueueFamilyProperties), "pCount",
+ return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount,
+ (nullptr == pQueueFamilyProperties),
"vkGetPhysicalDeviceQueueFamilyProperties()");
}
@@ -10850,8 +10894,8 @@ static bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_l
PHYSICAL_DEVICE_STATE *pd_state,
uint32_t *pQueueFamilyPropertyCount,
VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
- return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, pQueueFamilyPropertyCount,
- (nullptr == pQueueFamilyProperties), "pQueueFamilyPropertyCount",
+ return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount,
+ (nullptr == pQueueFamilyProperties),
"vkGetPhysicalDeviceQueueFamilyProperties2KHR()");
}
@@ -10859,10 +10903,15 @@ static bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_l
static void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count,
VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
if (!pQueueFamilyProperties) {
- pd_state->queueFamilyPropertiesCount = count;
+ if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState)
+ pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
+ pd_state->queue_family_count = count;
} else { // Save queue family properties
- if (pd_state->queue_family_properties.size() < count) pd_state->queue_family_properties.resize(count);
- for (uint32_t i = 0; i < count; i++) {
+ pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
+ pd_state->queue_family_count = std::max(pd_state->queue_family_count, count);
+
+ pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count));
+ for (uint32_t i = 0; i < count; ++i) {
pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties;
}
}
@@ -10889,18 +10938,26 @@ static void PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(PHYSICAL_DE
StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(pd_state, count, pQueueFamilyProperties);
}
-VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
VkQueueFamilyProperties *pQueueFamilyProperties) {
instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice);
assert(physical_device_state);
- bool skip =
- PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_data, physical_device_state, pCount, pQueueFamilyProperties);
- if (skip) {
- return;
- }
- instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount, pQueueFamilyProperties);
- PostCallRecordGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pCount, pQueueFamilyProperties);
+ std::unique_lock<std::mutex> lock(global_lock);
+
+ bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_data, physical_device_state,
+ pQueueFamilyPropertyCount, pQueueFamilyProperties);
+
+ lock.unlock();
+
+ if (skip) return;
+
+ instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
+ pQueueFamilyProperties);
+
+ lock.lock();
+ PostCallRecordGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pQueueFamilyProperties);
}
VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
@@ -10909,13 +10966,19 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysical
instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice);
assert(physical_device_state);
+ std::unique_lock<std::mutex> lock(global_lock);
+
bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_data, physical_device_state,
pQueueFamilyPropertyCount, pQueueFamilyProperties);
- if (skip) {
- return;
- }
+
+ lock.unlock();
+
+ if (skip) return;
+
instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount,
pQueueFamilyProperties);
+
+ lock.lock();
PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(physical_device_state, *pQueueFamilyPropertyCount,
pQueueFamilyProperties);
}
diff --git a/layers/core_validation.h b/layers/core_validation.h
index 62cbf0a2..fd1c8b4d 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -150,7 +150,6 @@ enum CALL_STATE {
struct PHYSICAL_DEVICE_STATE {
// Track the call state and array sizes for various query functions
CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState = UNCALLED;
- uint32_t queueFamilyPropertiesCount = 0;
CALL_STATE vkGetPhysicalDeviceLayerPropertiesState = UNCALLED;
CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState = UNCALLED;
CALL_STATE vkGetPhysicalDeviceFeaturesState = UNCALLED;
@@ -159,6 +158,7 @@ struct PHYSICAL_DEVICE_STATE {
CALL_STATE vkGetPhysicalDeviceSurfaceFormatsKHRState = UNCALLED;
VkPhysicalDeviceFeatures features = {};
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
+ uint32_t queue_family_count = 0;
std::vector<VkQueueFamilyProperties> queue_family_properties;
VkSurfaceCapabilitiesKHR surfaceCapabilities = {};
std::vector<VkPresentModeKHR> present_modes;
diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp
index d45d7d6b..c6653902 100644
--- a/layers/parameter_validation.cpp
+++ b/layers/parameter_validation.cpp
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include <iostream>
#include <string>
@@ -36,6 +37,7 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
+#include <mutex>
#include "vk_loader_platform.h"
#include "vulkan/vk_layer.h"
@@ -77,11 +79,15 @@ struct layer_data {
VkPhysicalDeviceLimits device_limits = {};
VkPhysicalDeviceFeatures physical_device_features = {};
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
+ VkDevice device = VK_NULL_HANDLE;
DeviceExtensions enables;
VkLayerDispatchTable dispatch_table = {};
};
+// TODO : This can be much smarter, using separate locks for separate global data
+static std::mutex global_lock;
+
static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
static std::unordered_map<void *, layer_data *> layer_data_map;
static std::unordered_map<void *, instance_layer_data *> instance_layer_data_map;
@@ -1224,25 +1230,24 @@ static bool validate_string(debug_report_data *report_data, const char *apiName,
return skip;
}
-static bool validate_queue_family_index(layer_data *device_data, const char *function_name, const char *parameter_name,
- uint32_t index) {
- assert(device_data != nullptr);
- debug_report_data *report_data = device_data->report_data;
+static bool ValidateDeviceQueueFamily(layer_data *device_data, uint32_t queue_family, const char *cmd_name,
+ const char *parameter_name, int32_t error_code, bool optional = false,
+ const char *vu_note = nullptr) {
bool skip = false;
- if (index == VK_QUEUE_FAMILY_IGNORED) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1,
- LayerName, "%s: %s cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name);
- } else {
- const auto &queue_data = device_data->queueFamilyIndexMap.find(index);
- if (queue_data == device_data->queueFamilyIndexMap.end()) {
- skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1,
- LayerName,
- "%s: %s (%d) must be one of the indices specified when the device was created, via "
- "the VkDeviceQueueCreateInfo structure.",
- function_name, parameter_name, index);
- return false;
- }
+ if (!vu_note) vu_note = validation_error_map[error_code];
+
+ if (!optional && queue_family == VK_QUEUE_FAMILY_IGNORED) {
+ skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+ reinterpret_cast<uint64_t>(device_data->device), __LINE__, error_code, LayerName,
+ "%s: %s is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family index value. %s",
+ cmd_name, parameter_name, vu_note);
+ } else if (device_data->queueFamilyIndexMap.find(queue_family) == device_data->queueFamilyIndexMap.end()) {
+ skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+ reinterpret_cast<uint64_t>(device_data->device), __LINE__, error_code, LayerName,
+ "%s: %s (=%" PRIu32 ") is not one of the queue families given via VkDeviceQueueCreateInfo structures when "
+ "the device was created. %s",
+ cmd_name, parameter_name, queue_family, vu_note);
}
return skip;
@@ -1497,55 +1502,104 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties(VkPhysicalDevice ph
}
}
-static void validateDeviceCreateInfo(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
- const std::vector<VkQueueFamilyProperties> properties) {
- std::unordered_set<uint32_t> set;
+static bool ValidateDeviceCreateInfo(instance_layer_data *instance_data, VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo) {
+ bool skip = false;
- auto my_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
+ if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
+ for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
+ skip |= validate_string(instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
+ pCreateInfo->ppEnabledLayerNames[i]);
+ }
+ }
+
+ if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
+ for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ skip |= validate_string(instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
+ pCreateInfo->ppEnabledExtensionNames[i]);
+ }
+ }
+
+ if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
+ // Check for get_physical_device_properties2 struct
+ struct std_header {
+ VkStructureType sType;
+ const void *pNext;
+ };
+ std_header *cur_pnext = (std_header *)pCreateInfo->pNext;
+ while (cur_pnext) {
+ if (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR == cur_pnext->sType) {
+ // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+ 0, __LINE__, INVALID_USAGE, LayerName,
+ "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
+ "pCreateInfo->pEnabledFeatures is non-NULL.");
+ break;
+ }
+ cur_pnext = (std_header *)cur_pnext->pNext;
+ }
+ }
+ if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
+ // Check for get_physical_device_properties2 struct
+ struct std_header {
+ VkStructureType sType;
+ const void *pNext;
+ };
+ std_header *cur_pnext = (std_header *)pCreateInfo->pNext;
+ while (cur_pnext) {
+ if (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR == cur_pnext->sType) {
+ // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
+ 0, __LINE__, INVALID_USAGE, LayerName,
+ "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
+ "pCreateInfo->pEnabledFeatures is non-NULL.");
+ break;
+ }
+ cur_pnext = (std_header *)cur_pnext->pNext;
+ }
+ }
+
+ // Validate pCreateInfo->pQueueCreateInfos
+ if (pCreateInfo->pQueueCreateInfos) {
+ std::unordered_set<uint32_t> set;
- if ((pCreateInfo != nullptr) && (pCreateInfo->pQueueCreateInfos != nullptr)) {
for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
- if (set.count(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex)) {
- log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
- VALIDATION_ERROR_00035, LayerName,
- "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex, is not unique within this "
- "structure. %s",
- i, validation_error_map[VALIDATION_ERROR_00035]);
+ const uint32_t requested_queue_family = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
+ if (requested_queue_family == VK_QUEUE_FAMILY_IGNORED) {
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, reinterpret_cast<uint64_t>(physicalDevice),
+ __LINE__, VALIDATION_ERROR_00054, LayerName,
+ "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex is "
+ "VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family index value. %s",
+ i, validation_error_map[VALIDATION_ERROR_00054]);
+ } else if (set.count(requested_queue_family)) {
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, reinterpret_cast<uint64_t>(physicalDevice),
+ __LINE__, VALIDATION_ERROR_00035, LayerName,
+ "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex (=%" PRIu32 ") is "
+ "not unique within pCreateInfo->pQueueCreateInfos array. %s",
+ i, requested_queue_family, validation_error_map[VALIDATION_ERROR_00035]);
} else {
- set.insert(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex);
+ set.insert(requested_queue_family);
}
if (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities != nullptr) {
for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; ++j) {
- if ((pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] < 0.f) ||
- (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] > 1.f)) {
- log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, INVALID_USAGE, LayerName,
- "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->pQueuePriorities[%d], must be "
- "between 0 and 1. Actual value is %f",
- i, j, pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j]);
+ const float queue_priority = pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j];
+ if (!(queue_priority >= 0.f) || !(queue_priority <= 1.f)) {
+ skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, reinterpret_cast<uint64_t>(physicalDevice),
+ __LINE__, VALIDATION_ERROR_02056, LayerName,
+ "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].pQueuePriorities[%" PRIu32
+ "] (=%f) is not between 0 and 1 (inclusive). %s",
+ i, j, queue_priority, validation_error_map[VALIDATION_ERROR_02056]);
}
}
}
-
- if (pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex >= properties.size()) {
- log_msg(
- my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
- INVALID_USAGE, LayerName,
- "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex cannot be more than the number "
- "of queue families.",
- i);
- } else if (pCreateInfo->pQueueCreateInfos[i].queueCount >
- properties[pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex].queueCount) {
- log_msg(
- my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
- INVALID_USAGE, LayerName,
- "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueCount cannot be more than the number of "
- "queues for the given family index.",
- i);
- }
}
}
+
+ return skip;
}
void storeCreateDeviceData(VkDevice device, const VkDeviceCreateInfo *pCreateInfo) {
@@ -1570,62 +1624,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
bool skip = false;
auto my_instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map);
assert(my_instance_data != nullptr);
+ std::unique_lock<std::mutex> lock(global_lock);
skip |= parameter_validation_vkCreateDevice(my_instance_data->report_data, pCreateInfo, pAllocator, pDevice);
- if (pCreateInfo != NULL) {
- if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
- for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
- skip |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
- pCreateInfo->ppEnabledLayerNames[i]);
- }
- }
-
- if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
- for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
- skip |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
- pCreateInfo->ppEnabledExtensionNames[i]);
- }
- }
- if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
- // Check for get_physical_device_properties2 struct
- struct std_header {
- VkStructureType sType;
- const void *pNext;
- };
- std_header *cur_pnext = (std_header *)pCreateInfo->pNext;
- while (cur_pnext) {
- if (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR == cur_pnext->sType) {
- // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
- skip |= log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE, LayerName,
- "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
- "pCreateInfo->pEnabledFeatures is non-NULL.");
- break;
- }
- cur_pnext = (std_header *)cur_pnext->pNext;
- }
- }
- if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
- // Check for get_physical_device_properties2 struct
- struct std_header {
- VkStructureType sType;
- const void *pNext;
- };
- std_header *cur_pnext = (std_header *)pCreateInfo->pNext;
- while (cur_pnext) {
- if (VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR == cur_pnext->sType) {
- // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
- skip |= log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE, LayerName,
- "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
- "pCreateInfo->pEnabledFeatures is non-NULL.");
- break;
- }
- cur_pnext = (std_header *)cur_pnext->pNext;
- }
- }
- }
+ if (pCreateInfo != NULL) skip |= ValidateDeviceCreateInfo(my_instance_data, physicalDevice, pCreateInfo);
if (!skip) {
VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
@@ -1642,10 +1645,14 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
// Advance the link info for the next element on the chain
chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+ lock.unlock();
+
result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ lock.lock();
validate_result(my_instance_data->report_data, "vkCreateDevice", {}, result);
+
if (result == VK_SUCCESS) {
layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
assert(my_device_data != nullptr);
@@ -1655,12 +1662,6 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
my_device_data->enables.InitFromDeviceCreateInfo(pCreateInfo);
- uint32_t count;
- my_instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
- std::vector<VkQueueFamilyProperties> properties(count);
- my_instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, &properties[0]);
-
- validateDeviceCreateInfo(physicalDevice, pCreateInfo, properties);
storeCreateDeviceData(*pDevice, pCreateInfo);
// Query and save physical device limits for this device
@@ -1668,6 +1669,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
my_instance_data->dispatch_table.GetPhysicalDeviceProperties(physicalDevice, &device_properties);
memcpy(&my_device_data->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits));
my_device_data->physical_device = physicalDevice;
+ my_device_data->device = *pDevice;
// Save app-enabled features in this device's layer_data structure
if (pCreateInfo->pEnabledFeatures) {
@@ -1702,34 +1704,38 @@ VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCall
}
static bool PreGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex) {
+ bool skip = false;
layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
assert(my_device_data != nullptr);
- validate_queue_family_index(my_device_data, "vkGetDeviceQueue", "queueFamilyIndex", queueFamilyIndex);
+ skip |=
+ ValidateDeviceQueueFamily(my_device_data, queueFamilyIndex, "vkGetDeviceQueue", "queueFamilyIndex", VALIDATION_ERROR_00060);
const auto &queue_data = my_device_data->queueFamilyIndexMap.find(queueFamilyIndex);
- if (queue_data->second <= queueIndex) {
- log_msg(
- my_device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
- VALIDATION_ERROR_00061, LayerName,
- "vkGetDeviceQueue() parameter, uint32_t queueIndex %d, must be less than the number of queues given when the device "
- "was created. %s",
- queueIndex, validation_error_map[VALIDATION_ERROR_00061]);
- return false;
+ if (queue_data != my_device_data->queueFamilyIndexMap.end() && queue_data->second <= queueIndex) {
+ skip |= log_msg(my_device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+ reinterpret_cast<uint64_t>(device), __LINE__, VALIDATION_ERROR_00061, LayerName,
+ "vkGetDeviceQueue: queueIndex (=%" PRIu32 ") is not less than the number of queues requested from "
+ "queueFamilyIndex (=%" PRIu32 ") when the device was created (i.e. is not less than %" PRIu32 "). %s",
+ queueIndex, queueFamilyIndex, queue_data->second, validation_error_map[VALIDATION_ERROR_00061]);
}
- return true;
+
+ return skip;
}
VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
bool skip = false;
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
assert(my_data != NULL);
+ std::unique_lock<std::mutex> lock(global_lock);
skip |= parameter_validation_vkGetDeviceQueue(my_data->report_data, queueFamilyIndex, queueIndex, pQueue);
if (!skip) {
PreGetDeviceQueue(device, queueFamilyIndex, queueIndex);
+ lock.unlock();
+
my_data->dispatch_table.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
}
}
@@ -3963,8 +3969,8 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkComman
layer_data *my_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
assert(my_data != NULL);
- skip |=
- validate_queue_family_index(my_data, "vkCreateCommandPool", "pCreateInfo->queueFamilyIndex", pCreateInfo->queueFamilyIndex);
+ skip |= ValidateDeviceQueueFamily(my_data, pCreateInfo->queueFamilyIndex, "vkCreateCommandPool",
+ "pCreateInfo->queueFamilyIndex", VALIDATION_ERROR_00068);
skip |= parameter_validation_vkCreateCommandPool(my_data->report_data, pCreateInfo, pAllocator, pCommandPool);
diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt
index a6d38f49..ea5f16b1 100644
--- a/layers/vk_validation_error_database.txt
+++ b/layers/vk_validation_error_database.txt
@@ -61,8 +61,8 @@ VALIDATION_ERROR_00055~^~N~^~Unknown~^~vkCreateDevice~^~For more information ref
VALIDATION_ERROR_00056~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_00057~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_00058~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueuePriorities must be a pointer to an array of queueCount float values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~implicit
-VALIDATION_ERROR_00059~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~implicit
-VALIDATION_ERROR_00060~^~N~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be one of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDeviceQueue)~^~
+VALIDATION_ERROR_00059~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~implicit, TBD in parameter validation layer
+VALIDATION_ERROR_00060~^~Y~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be one of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDeviceQueue)~^~
VALIDATION_ERROR_00061~^~Y~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueIndex must be less than the number of queues created for the specified queue family index when device was created, via the queueCount member of the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDeviceQueue)~^~
VALIDATION_ERROR_00062~^~Y~^~None~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDeviceQueue)~^~implicit
VALIDATION_ERROR_00063~^~N~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueue must be a pointer to a VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDeviceQueue)~^~implicit
@@ -70,7 +70,7 @@ VALIDATION_ERROR_00064~^~Y~^~None~^~vkCreateCommandPool~^~For more information r
VALIDATION_ERROR_00065~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'pCreateInfo must be a pointer to a valid VkCommandPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCreateCommandPool)~^~implicit
VALIDATION_ERROR_00066~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCreateCommandPool)~^~implicit
VALIDATION_ERROR_00067~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'pCommandPool must be a pointer to a VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCreateCommandPool)~^~implicit
-VALIDATION_ERROR_00068~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'queueFamilyIndex must be the index of a queue family available in the calling commands device parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkCommandPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00068~^~Y~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'queueFamilyIndex must be the index of a queue family available in the calling commands device parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkCommandPoolCreateFlagBits)~^~
VALIDATION_ERROR_00069~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkCommandPoolCreateFlagBits)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_00070~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkCommandPoolCreateFlagBits)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_00071~^~N~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.2. Command Pools' which states 'flags must be a valid combination of VkCommandPoolCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkCommandPoolCreateFlagBits)~^~implicit, TBD in parameter validation layer.
@@ -1915,7 +1915,7 @@ VALIDATION_ERROR_02052~^~N~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For mor
VALIDATION_ERROR_02053~^~N~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '33.2. Debug Report Callbacks' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~implicit
VALIDATION_ERROR_02054~^~N~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '33.2. Debug Report Callbacks' which states 'callback must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~implicit
VALIDATION_ERROR_02055~^~Y~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be less than or equal to the queueCount member of the VkQueueFamilyProperties structure, as returned by vkGetPhysicalDeviceQueueFamilyProperties in the pQueueFamilyProperties[queueFamilyIndex]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~
-VALIDATION_ERROR_02056~^~N~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'Each element of pQueuePriorities must be between 0.0 and 1.0 inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_02056~^~Y~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'Each element of pQueuePriorities must be between 0.0 and 1.0 inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkDeviceQueueCreateInfo)~^~
VALIDATION_ERROR_02057~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~
VALIDATION_ERROR_02058~^~N~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::subpass set to the index of the subpass which the given command buffer will be executed in' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~
VALIDATION_ERROR_02059~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.7. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, the render passes specified in the pname::pBeginInfo::pInheritanceInfo::renderPass members of the vkBeginCommandBuffer commands used to begin recording each element of pCommandBuffers must be compatible with the current render pass.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdExecuteCommands)~^~