aboutsummaryrefslogtreecommitdiff
path: root/layers
diff options
context:
space:
mode:
authorMike Schuchardt <mikes@lunarg.com>2017-08-25 12:11:34 -0600
committerMike Schuchardt <mikes@lunarg.com>2017-10-06 16:52:00 -0600
commit25c48b05f3d885455d98fe9bab2a9ea28a237edb (patch)
treea7920e05c392ac97bb9202fe63429a33476d3cc0 /layers
parent038a014b4948eb800a70d169abe37253adae1fbb (diff)
downloadusermoji-25c48b05f3d885455d98fe9bab2a9ea28a237edb.tar.xz
layers: Refactor vkQueueBindSparse for pre/post
Change-Id: I140e11653a0fa97e61d6df9c87e5223b7f28a04f
Diffstat (limited to 'layers')
-rw-r--r--layers/core_validation.cpp126
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;
}