diff options
| author | Mike Schuchardt <mikes@lunarg.com> | 2017-08-25 12:11:34 -0600 |
|---|---|---|
| committer | Mike Schuchardt <mikes@lunarg.com> | 2017-10-06 16:52:00 -0600 |
| commit | 25c48b05f3d885455d98fe9bab2a9ea28a237edb (patch) | |
| tree | a7920e05c392ac97bb9202fe63429a33476d3cc0 /layers | |
| parent | 038a014b4948eb800a70d169abe37253adae1fbb (diff) | |
| download | usermoji-25c48b05f3d885455d98fe9bab2a9ea28a237edb.tar.xz | |
layers: Refactor vkQueueBindSparse for pre/post
Change-Id: I140e11653a0fa97e61d6df9c87e5223b7f28a04f
Diffstat (limited to 'layers')
| -rw-r--r-- | layers/core_validation.cpp | 126 |
1 files changed, 81 insertions, 45 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 5d1e7f51..d6823412 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -8746,17 +8746,61 @@ VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) { return result; } -VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, - VkFence fence) { - layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); - VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; - bool skip = false; - unique_lock_t lock(global_lock); +static bool PreCallValidateQueueBindSparse(layer_data *dev_data, VkQueue queue, uint32_t bindInfoCount, + const VkBindSparseInfo *pBindInfo, VkFence fence) { auto pFence = GetFenceNode(dev_data, fence); - auto pQueue = GetQueueState(dev_data, queue); + bool skip = ValidateFenceForSubmit(dev_data, pFence); + if (skip) { + return true; + } + + unordered_set<VkSemaphore> signaled_semaphores; + unordered_set<VkSemaphore> unsignaled_semaphores; + for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) { + const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx]; + + std::vector<SEMAPHORE_WAIT> semaphore_waits; + std::vector<VkSemaphore> semaphore_signals; + for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) { + VkSemaphore semaphore = bindInfo.pWaitSemaphores[i]; + auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); + if (pSemaphore) { + if (unsignaled_semaphores.count(semaphore) || + (!(signaled_semaphores.count(semaphore)) && !(pSemaphore->signaled))) { + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, + HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", + "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, + HandleToUint64(semaphore)); + } else { + signaled_semaphores.erase(semaphore); + unsignaled_semaphores.insert(semaphore); + } + } + } + for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { + VkSemaphore semaphore = bindInfo.pSignalSemaphores[i]; + auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); + if (pSemaphore) { + if (signaled_semaphores.count(semaphore) || (!(unsignaled_semaphores.count(semaphore)) && pSemaphore->signaled)) { + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, + HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", + "Queue 0x%p is signaling semaphore 0x%" PRIx64 + " that has already been signaled but not waited on by queue 0x%" PRIx64 ".", + queue, HandleToUint64(semaphore), HandleToUint64(pSemaphore->signaler.first)); + } else { + unsignaled_semaphores.erase(semaphore); + signaled_semaphores.insert(semaphore); + } + } + } + } - // First verify that fence is not in use - skip |= ValidateFenceForSubmit(dev_data, pFence); + return skip; +} +static void PostCallRecordQueueBindSparse(layer_data *dev_data, VkQueue queue, uint32_t bindInfoCount, + const VkBindSparseInfo *pBindInfo, VkFence fence) { + auto pFence = GetFenceNode(dev_data, fence); + auto pQueue = GetQueueState(dev_data, queue); if (pFence) { SubmitFence(pQueue, pFence, std::max(1u, bindInfoCount)); @@ -8768,17 +8812,15 @@ VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoC for (uint32_t j = 0; j < bindInfo.bufferBindCount; j++) { for (uint32_t k = 0; k < bindInfo.pBufferBinds[j].bindCount; k++) { auto sparse_binding = bindInfo.pBufferBinds[j].pBinds[k]; - if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, - HandleToUint64(bindInfo.pBufferBinds[j].buffer), kVulkanObjectTypeBuffer)) - skip = true; + SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, + HandleToUint64(bindInfo.pBufferBinds[j].buffer), kVulkanObjectTypeBuffer); } } for (uint32_t j = 0; j < bindInfo.imageOpaqueBindCount; j++) { for (uint32_t k = 0; k < bindInfo.pImageOpaqueBinds[j].bindCount; k++) { auto sparse_binding = bindInfo.pImageOpaqueBinds[j].pBinds[k]; - if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, - HandleToUint64(bindInfo.pImageOpaqueBinds[j].image), kVulkanObjectTypeImage)) - skip = true; + SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, + HandleToUint64(bindInfo.pImageOpaqueBinds[j].image), kVulkanObjectTypeImage); } } for (uint32_t j = 0; j < bindInfo.imageBindCount; j++) { @@ -8786,9 +8828,8 @@ VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoC auto sparse_binding = bindInfo.pImageBinds[j].pBinds[k]; // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4; - if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, size}, - HandleToUint64(bindInfo.pImageBinds[j].image), kVulkanObjectTypeImage)) - skip = true; + SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, size}, + HandleToUint64(bindInfo.pImageBinds[j].image), kVulkanObjectTypeImage); } } @@ -8798,39 +8839,23 @@ VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoC VkSemaphore semaphore = bindInfo.pWaitSemaphores[i]; auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); if (pSemaphore) { - if (pSemaphore->signaled) { - if (pSemaphore->signaler.first != VK_NULL_HANDLE) { - semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); - pSemaphore->in_use.fetch_add(1); - } - pSemaphore->signaler.first = VK_NULL_HANDLE; - pSemaphore->signaled = false; - } else { - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, - HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", - "vkQueueBindSparse: Queue 0x%p is waiting on semaphore 0x%" PRIx64 - " that has no way to be signaled.", - queue, HandleToUint64(semaphore)); + if (pSemaphore->signaler.first != VK_NULL_HANDLE) { + semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); + pSemaphore->in_use.fetch_add(1); } + pSemaphore->signaler.first = VK_NULL_HANDLE; + pSemaphore->signaled = false; } } for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { VkSemaphore semaphore = bindInfo.pSignalSemaphores[i]; auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); if (pSemaphore) { - if (pSemaphore->signaled) { - skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, - HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", - "vkQueueBindSparse: Queue 0x%p is signaling semaphore 0x%" PRIx64 - ", but that semaphore is already signaled.", - queue, HandleToUint64(semaphore)); - } else { - pSemaphore->signaler.first = queue; - pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; - pSemaphore->signaled = true; - pSemaphore->in_use.fetch_add(1); - semaphore_signals.push_back(semaphore); - } + pSemaphore->signaler.first = queue; + pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; + pSemaphore->signaled = true; + pSemaphore->in_use.fetch_add(1); + semaphore_signals.push_back(semaphore); } } @@ -8843,11 +8868,22 @@ VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoC pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), std::vector<VkSemaphore>(), fence); } +} +VKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, + VkFence fence) { + layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); + unique_lock_t lock(global_lock); + bool skip = PreCallValidateQueueBindSparse(dev_data, queue, bindInfoCount, pBindInfo, fence); lock.unlock(); - if (!skip) return dev_data->dispatch_table.QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); + if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; + + VkResult result = dev_data->dispatch_table.QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); + lock.lock(); + PostCallRecordQueueBindSparse(dev_data, queue, bindInfoCount, pBindInfo, fence); + lock.unlock(); return result; } |
