diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2017-11-13 09:38:23 -0700 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2017-11-15 10:34:31 -0700 |
| commit | 4dd2152a1fb5db933704fdecbcbb07bcf27b3ac1 (patch) | |
| tree | c1cf9a836f05d0d3ab0a20d71331ebe0d9da7b27 | |
| parent | 3cbbb655d78ad16fa26ea7f838f0c19a1e2035a8 (diff) | |
| download | usermoji-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.h | 8 | ||||
| -rw-r--r-- | layers/object_tracker_utils.cpp | 38 |
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; } |
