aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Lobodzinski <mark@lunarg.com>2017-11-13 09:38:23 -0700
committerMark Lobodzinski <mark@lunarg.com>2017-11-15 10:34:31 -0700
commit4dd2152a1fb5db933704fdecbcbb07bcf27b3ac1 (patch)
treec1cf9a836f05d0d3ab0a20d71331ebe0d9da7b27
parent3cbbb655d78ad16fa26ea7f838f0c19a1e2035a8 (diff)
downloadusermoji-4dd2152a1fb5db933704fdecbcbb07bcf27b3ac1.tar.xz
layers: Validate device dispatchable objects
Device object validation required dereferencing possibly bad device objects. Moved ownership of device objects to instance objects, and to search each of the layer_data object lists for a created device handle matching the our candidate device object. Change-Id: If5615294c397ff6991d4d21ac75ab58d1b0b0841
-rw-r--r--layers/object_tracker.h8
-rw-r--r--layers/object_tracker_utils.cpp38
2 files changed, 39 insertions, 7 deletions
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index a45d30b3..d9fdf8b4 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -145,7 +145,8 @@ void AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, co
void AllocateDescriptorSet(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSet descriptor_set);
void CreateSwapchainImageObject(VkDevice dispatchable_object, VkImage swapchain_image, VkSwapchainKHR swapchain);
void ReportUndestroyedObjects(VkDevice device, UNIQUE_VALIDATION_ERROR_CODE error_code);
-
+bool ValidateDeviceObject(uint64_t device_handle, enum UNIQUE_VALIDATION_ERROR_CODE invalid_handle_code,
+ enum UNIQUE_VALIDATION_ERROR_CODE wrong_device_code);
template <typename T1, typename T2>
bool ValidateObject(T1 dispatchable_object, T2 object, VulkanObjectType object_type, bool null_allowed,
@@ -154,6 +155,11 @@ bool ValidateObject(T1 dispatchable_object, T2 object, VulkanObjectType object_t
return false;
}
auto object_handle = HandleToUint64(object);
+
+ if (object_type == kVulkanObjectTypeDevice) {
+ return ValidateDeviceObject(object_handle, invalid_handle_code, wrong_device_code);
+ }
+
VkDebugReportObjectTypeEXT debug_object_type = get_debug_report_enum[object_type];
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(dispatchable_object), layer_data_map);
diff --git a/layers/object_tracker_utils.cpp b/layers/object_tracker_utils.cpp
index 93c325fb..f4f148db 100644
--- a/layers/object_tracker_utils.cpp
+++ b/layers/object_tracker_utils.cpp
@@ -99,6 +99,26 @@ void ValidateQueueFlags(VkQueue queue, const char *function) {
}
}
+// Look for this device object in any of the instance child devices lists.
+// NOTE: This is of dubious value. In most circumstances Vulkan will die a flaming death if a dispatchable object is invalid.
+// However, if this layer is loaded first and GetProcAddress is used to make API calls, it will detect bad DOs.
+bool ValidateDeviceObject(uint64_t device_handle, enum UNIQUE_VALIDATION_ERROR_CODE invalid_handle_code,
+ enum UNIQUE_VALIDATION_ERROR_CODE wrong_device_code) {
+ VkInstance last_instance = nullptr;
+ for (auto layer_data : layer_data_map) {
+ for (auto object : layer_data.second->object_map[kVulkanObjectTypeDevice]) {
+ // Grab last instance to use for possible error message
+ last_instance = layer_data.second->instance;
+ if (object.second->handle == device_handle) return false;
+ }
+ }
+
+ layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(last_instance), layer_data_map);
+ return log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device_handle,
+ __LINE__, invalid_handle_code, LayerName, "Invalid Device Object 0x%" PRIxLEAST64 ". %s", device_handle,
+ validation_error_map[invalid_handle_code]);
+}
+
void AllocateCommandBuffer(VkDevice device, const VkCommandPool command_pool, const VkCommandBuffer command_buffer,
VkCommandBufferLevel level) {
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
@@ -326,16 +346,14 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
for (auto iit = instance_data->object_map[kVulkanObjectTypePhysicalDevice].begin();
iit != instance_data->object_map[kVulkanObjectTypePhysicalDevice].end();) {
ObjTrackState *pNode = iit->second;
-
VkPhysicalDevice physical_device = reinterpret_cast<VkPhysicalDevice>(pNode->handle);
+
DestroyObject(instance, physical_device, kVulkanObjectTypePhysicalDevice, nullptr, VALIDATION_ERROR_UNDEFINED,
VALIDATION_ERROR_UNDEFINED);
iit = instance_data->object_map[kVulkanObjectTypePhysicalDevice].begin();
}
- DestroyObject(instance, instance, kVulkanObjectTypeInstance, pAllocator, VALIDATION_ERROR_258004ec, VALIDATION_ERROR_258004ee);
- // Report any remaining objects in LL
-
+ // Destroy child devices
for (auto iit = instance_data->object_map[kVulkanObjectTypeDevice].begin();
iit != instance_data->object_map[kVulkanObjectTypeDevice].end();) {
ObjTrackState *pNode = iit->second;
@@ -347,8 +365,14 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
OBJTRACK_OBJECT_LEAK, LayerName, "OBJ ERROR : %s object 0x%" PRIxLEAST64 " has not been destroyed.",
string_VkDebugReportObjectTypeEXT(debug_object_type), pNode->handle);
+ // Report any remaining objects in LL
ReportUndestroyedObjects(device, VALIDATION_ERROR_258004ea);
+
+ DestroyObject(instance, device, kVulkanObjectTypeDevice, pAllocator, VALIDATION_ERROR_258004ec, VALIDATION_ERROR_258004ee);
+ iit = instance_data->object_map[kVulkanObjectTypeDevice].begin();
}
+
+
instance_data->object_map[kVulkanObjectTypeDevice].clear();
VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
@@ -380,8 +404,9 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
std::unique_lock<std::mutex> lock(global_lock);
+ layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
ValidateObject(device, device, kVulkanObjectTypeDevice, true, VALIDATION_ERROR_24a05601, VALIDATION_ERROR_UNDEFINED);
- DestroyObject(device, device, kVulkanObjectTypeDevice, pAllocator, VALIDATION_ERROR_24a002f6, VALIDATION_ERROR_24a002f8);
+ DestroyObject(device_data->instance, device, kVulkanObjectTypeDevice, pAllocator, VALIDATION_ERROR_24a002f6, VALIDATION_ERROR_24a002f8);
// Report any remaining objects associated with this VkDevice object in LL
ReportUndestroyedObjects(device, VALIDATION_ERROR_24a002f4);
@@ -639,10 +664,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
// Add link back to physDev
device_data->physical_device = physicalDevice;
+ device_data->instance = phy_dev_data->instance;
initDeviceTable(*pDevice, fpGetDeviceProcAddr, ot_device_table_map);
- CreateObject(*pDevice, *pDevice, kVulkanObjectTypeDevice, pAllocator);
+ CreateObject(phy_dev_data->instance, *pDevice, kVulkanObjectTypeDevice, pAllocator);
return result;
}