layers: MR118, Add validation for semaphore ordering
Conflicts:
layers/draw_state.cpp
layers/draw_state.h
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index 4ce634c..b18e772 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -114,15 +114,15 @@
unordered_map<VkDevice, DEVICE_NODE> deviceMap;
unordered_map<VkEvent, EVENT_NODE> eventMap;
unordered_map<QueryObject, bool> queryToStateMap;
- // Map for layout chains
+ unordered_map<VkSemaphore, uint32_t> semaphoreSignaledMap;
unordered_map<void*, GLOBAL_CB_NODE*> commandBufferMap;
unordered_map<VkFramebuffer, VkFramebufferCreateInfo*> frameBufferMap;
unordered_map<VkImage, IMAGE_NODE*> imageLayoutMap;
unordered_map<VkRenderPass, RENDER_PASS_NODE*> renderPassMap;
- unordered_map<VkShaderModule, shader_module*> shaderModuleMap;
+ unordered_map<VkShaderModule, shader_module*> shaderModuleMap;
// Current render pass
- VkRenderPassBeginInfo renderPassBeginInfo;
- uint32_t currentSubpass;
+ VkRenderPassBeginInfo renderPassBeginInfo;
+ uint32_t currentSubpass;
layer_data() :
report_data(nullptr),
@@ -131,6 +131,7 @@
device_extensions()
{};
};
+
// Code imported from ShaderChecker
static void
build_type_def_index(std::vector<unsigned> const &words, std::unordered_map<unsigned, unsigned> &type_def_index);
@@ -3065,6 +3066,18 @@
// Same goes for any secondary CBs under the primary CB
for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
const VkSubmitInfo *submit = &pSubmits[submit_idx];
+ for (uint32_t i=0; i < submit->waitSemaphoreCount; ++i) {
+ if (dev_data->semaphoreSignaledMap[submit->pWaitSemaphores[i]]) {
+ dev_data->semaphoreSignaledMap[submit->pWaitSemaphores[i]] = 0;
+ } else {
+ skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+ "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 " that has no way to be signaled.",
+ reinterpret_cast<uint64_t>(queue), reinterpret_cast<uint64_t>(submit->pWaitSemaphores[i]));
+ }
+ }
+ for (uint32_t i=0; i < submit->signalSemaphoreCount; ++i) {
+ dev_data->semaphoreSignaledMap[submit->pSignalSemaphores[i]] = 1;
+ }
for (uint32_t i=0; i < submit->commandBufferCount; i++) {
#ifndef DISABLE_IMAGE_LAYOUT_VALIDATION
@@ -3189,7 +3202,9 @@
VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator)
{
- get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
+ layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ dev_data->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
+ dev_data->semaphoreSignaledMap.erase(semaphore);
// TODO : Clean up any internal data structures using this obj.
}
@@ -5736,6 +5751,48 @@
return result;
}
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(
+ VkQueue queue,
+ uint32_t bindInfoCount,
+ const VkBindSparseInfo* pBindInfo,
+ VkFence fence)
+{
+ layer_data* dev_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
+ bool skip_call = false;
+
+ for (uint32_t bindIdx=0; bindIdx < bindInfoCount; ++bindIdx) {
+ const VkBindSparseInfo& bindInfo = pBindInfo[bindIdx];
+ for (uint32_t i=0; i < bindInfo.waitSemaphoreCount; ++i) {
+ if (dev_data->semaphoreSignaledMap[bindInfo.pWaitSemaphores[i]]) {
+ dev_data->semaphoreSignaledMap[bindInfo.pWaitSemaphores[i]] = 0;
+ } else {
+ skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+ "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 " that has no way to be signaled.",
+ reinterpret_cast<uint64_t>(queue), reinterpret_cast<uint64_t>(bindInfo.pWaitSemaphores[i]));
+ }
+ }
+ for (uint32_t i=0; i < bindInfo.signalSemaphoreCount; ++i) {
+ dev_data->semaphoreSignaledMap[bindInfo.pSignalSemaphores[i]] = 1;
+ }
+ }
+
+ if (!skip_call)
+ return dev_data->device_dispatch_table->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
+ VkDevice device,
+ const VkSemaphoreCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSemaphore* pSemaphore)
+{
+ layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ VkResult result = dev_data->device_dispatch_table->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
+ if (result == VK_SUCCESS) {
+ dev_data->semaphoreSignaledMap[*pSemaphore] = 0;
+ }
+}
+
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
VkDevice device,
const VkSwapchainCreateInfoKHR *pCreateInfo,
@@ -5810,6 +5867,15 @@
#ifndef DISABLE_IMAGE_LAYOUT_VALIDATION
if (pPresentInfo) {
+ for (uint32_t i=0; i < pPresentInfo->waitSemaphoreCount; ++i) {
+ if (dev_data->semaphoreSignaledMap[pPresentInfo->pWaitSemaphores[i]]) {
+ dev_data->semaphoreSignaledMap[pPresentInfo->pWaitSemaphores[i]] = 0;
+ } else {
+ skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
+ "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 " that has no way to be signaled.",
+ reinterpret_cast<uint64_t>(queue), reinterpret_cast<uint64_t>(pPresentInfo->pWaitSemaphores[i]));
+ }
+ }
for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
auto swapchain_data = dev_data->device_extensions.swapchainMap.find(pPresentInfo->pSwapchains[i]);
if (swapchain_data != dev_data->device_extensions.swapchainMap.end() && pPresentInfo->pImageIndices[i] < swapchain_data->second->images.size()) {
@@ -5831,6 +5897,19 @@
return VK_ERROR_VALIDATION_FAILED_EXT;
}
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t timeout,
+ VkSemaphore semaphore,
+ VkFence fence,
+ uint32_t* pImageIndex)
+{
+ layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+ VkResult result = dev_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+ dev_data->semaphoreSignaledMap[semaphore] = 1;
+}
+
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
@@ -6116,6 +6195,12 @@
return (PFN_vkVoidFunction) vkMapMemory;
if (!strcmp(funcName, "vkGetQueryPoolResults"))
return (PFN_vkVoidFunction) vkGetQueryPoolResults;
+ if (!strcmp(funcName, "vkBindImageMemory"))
+ return (PFN_vkVoidFunction) vkBindImageMemory;
+ if (!strcmp(funcName, "vkQueueBindSparse"))
+ return (PFN_vkVoidFunction) vkQueueBindSparse;
+ if (!strcmp(funcName, "vkCreateSemaphore"))
+ return (PFN_vkVoidFunction) vkCreateSemaphore;
if (dev_data->device_extensions.wsi_enabled)
{
@@ -6125,6 +6210,8 @@
return (PFN_vkVoidFunction) vkDestroySwapchainKHR;
if (!strcmp(funcName, "vkGetSwapchainImagesKHR"))
return (PFN_vkVoidFunction) vkGetSwapchainImagesKHR;
+ if (!strcmp(funcName, "vkAcquireNextImageKHR"))
+ return (PFN_vkVoidFunction) vkAcquireNextImageKHR;
if (!strcmp(funcName, "vkQueuePresentKHR"))
return (PFN_vkVoidFunction) vkQueuePresentKHR;
}