aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lentine <mlentine@google.com>2016-02-10 16:18:47 -0600
committerTobin Ehlis <tobine@google.com>2016-02-12 09:28:59 -0700
commit8f84adfccd4798251e2504c91707cb41e5f15d3a (patch)
treefa950e0a7728432019a66297b4710140cd8a7153
parent6035cae8dc04be9aafba15bb696170708888e5a6 (diff)
downloadusermoji-8f84adfccd4798251e2504c91707cb41e5f15d3a.tar.xz
layers: Validate wait event sourceStageMask.
-rw-r--r--layers/draw_state.cpp37
-rwxr-xr-xlayers/draw_state.h2
2 files changed, 38 insertions, 1 deletions
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index eb9c238d..ccdcd96e 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -3188,6 +3188,7 @@ static void resetCB(layer_data* my_data, const VkCommandBuffer cb)
pCB->activeQueries.clear();
pCB->startedQueries.clear();
pCB->imageLayoutMap.clear();
+ pCB->eventToStageMap.clear();
pCB->drawData.clear();
pCB->currentDrawData.buffers.clear();
pCB->primaryCommandBuffer = VK_NULL_HANDLE;
@@ -3798,6 +3799,10 @@ void decrementResources(layer_data* my_data, VkCommandBuffer cmdBuffer) {
for (auto queryStatePair : pCB->queryToStateMap) {
my_data->queryToStateMap[queryStatePair.first] = queryStatePair.second;
}
+ for (auto eventStagePair : pCB->eventToStageMap) {
+ my_data->eventMap[eventStagePair.first].stageMask =
+ eventStagePair.second;
+ }
}
void decrementResources(layer_data* my_data, uint32_t fenceCount, const VkFence* pFences) {
@@ -6091,6 +6096,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer command
skipCall |= addCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()");
skipCall |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent");
pCB->events.push_back(event);
+ pCB->eventToStageMap[event] = stageMask;
}
loader_platform_thread_unlock_mutex(&globalLock);
if (VK_FALSE == skipCall)
@@ -6315,7 +6321,7 @@ VkBool32 ValidateBarriers(VkCommandBuffer cmdBuffer, uint32_t memBarrierCount,
DRAWSTATE_INVALID_BARRIER, "DS",
"Buffer Barrier 0x%" PRIx64 " has offset %" PRIu64
" and size %" PRIu64
- " whos sum is greater than total size %" PRIu64 ".",
+ " whose sum is greater than total size %" PRIu64 ".",
reinterpret_cast<const uint64_t &>(mem_barrier->buffer),
reinterpret_cast<const uint64_t &>(mem_barrier->offset),
reinterpret_cast<const uint64_t &>(mem_barrier->size),
@@ -6337,9 +6343,37 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(
loader_platform_thread_lock_mutex(&globalLock);
GLOBAL_CB_NODE* pCB = getCBNode(dev_data, commandBuffer);
if (pCB) {
+ VkPipelineStageFlags stageMask = 0;
for (uint32_t i = 0; i < eventCount; ++i) {
pCB->waitedEvents.push_back(pEvents[i]);
pCB->events.push_back(pEvents[i]);
+ auto event_data = pCB->eventToStageMap.find(pEvents[i]);
+ if (event_data != pCB->eventToStageMap.end()) {
+ stageMask |= event_data->second;
+ } else {
+ auto global_event_data = dev_data->eventMap.find(pEvents[i]);
+ if (global_event_data == dev_data->eventMap.end()) {
+ skipCall |= log_msg(
+ dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
+ reinterpret_cast<const uint64_t &>(pEvents[i]),
+ __LINE__, DRAWSTATE_INVALID_FENCE, "DS",
+ "Fence 0x%" PRIx64
+ " cannot be waited on if it has never been set.",
+ reinterpret_cast<const uint64_t &>(pEvents[i]));
+ } else {
+ stageMask |= global_event_data->second.stageMask;
+ }
+ }
+ }
+ if (sourceStageMask != stageMask) {
+ skipCall |= log_msg(
+ dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+ DRAWSTATE_INVALID_FENCE, "DS",
+ "srcStageMask in vkCmdWaitEvents must be the bitwise OR of the "
+ "stageMask parameters used in calls to vkCmdSetEvent and "
+ "VK_PIPELINE_STAGE_HOST_BIT if used with vkSetEvent.");
}
if (pCB->state == CB_RECORDING) {
skipCall |= addCmd(dev_data, pCB, CMD_WAITEVENTS, "vkCmdWaitEvents()");
@@ -7406,6 +7440,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event) {
layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
loader_platform_thread_lock_mutex(&globalLock);
dev_data->eventMap[event].needsSignaled = false;
+ dev_data->eventMap[event].stageMask = VK_PIPELINE_STAGE_HOST_BIT;
loader_platform_thread_unlock_mutex(&globalLock);
VkResult result = dev_data->device_dispatch_table->SetEvent(device, event);
return result;
diff --git a/layers/draw_state.h b/layers/draw_state.h
index a84ebd1f..3852fa53 100755
--- a/layers/draw_state.h
+++ b/layers/draw_state.h
@@ -372,6 +372,7 @@ class EVENT_NODE : public BASE_NODE {
public:
using BASE_NODE::in_use;
bool needsSignaled;
+ VkPipelineStageFlags stageMask;
};
class QUEUE_NODE {
@@ -680,6 +681,7 @@ typedef struct _GLOBAL_CB_NODE {
unordered_set<QueryObject> startedQueries;
unordered_map<ImageSubresourcePair, IMAGE_CMD_BUF_NODE> imageLayoutMap;
unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
+ unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
vector<DRAW_DATA> drawData;
DRAW_DATA currentDrawData;
VkCommandBuffer primaryCommandBuffer;