aboutsummaryrefslogtreecommitdiff
path: root/layers/core_validation.cpp
diff options
context:
space:
mode:
authorJohn Zulauf <jzulauf@lunarg.com>2017-12-22 17:14:54 -0700
committerjzulauf-lunarg <32470354+jzulauf-lunarg@users.noreply.github.com>2018-01-04 17:08:05 -0700
commit8467279d2b5cd6278c26b94fbe87d8499bb0e6b5 (patch)
tree046ade3da1926ca2bf9cd7d004c051f20243ff18 /layers/core_validation.cpp
parent70fe5b4ab8cdf00aa4fee86b4c661a3a330961ed (diff)
downloadusermoji-8467279d2b5cd6278c26b94fbe87d8499bb0e6b5.tar.xz
layers: Add validation caching for draw/dispatch
Validation of descriptors at draw or dispatch time is now cached, s.t. without changes that affect validity, validation checks are not repeated. Change-Id: I713662d00813989bf4441921456afca431d730d7
Diffstat (limited to 'layers/core_validation.cpp')
-rw-r--r--layers/core_validation.cpp45
1 files changed, 34 insertions, 11 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 123db135..d55ceded 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -1184,15 +1184,24 @@ static bool ValidateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, CMD
cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex];
// Validate the draw-time state for this descriptor set
std::string err_str;
- if (!descriptor_set->IsPushDescriptor() &&
- !descriptor_set->ValidateDrawState(set_binding_pair.second, state.dynamicOffsets[setIndex], cb_node, function,
- &err_str)) {
- auto set = descriptor_set->GetSet();
- result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(set), __LINE__,
- DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
- "Descriptor set 0x%" PRIx64 " encountered the following validation error at %s time: %s",
- HandleToUint64(set), function, err_str.c_str());
+ if (!descriptor_set->IsPushDescriptor()) {
+ // For the "bindless" style resource usage with many descriptors, need to optimize command <-> descriptor
+ // binding validation. Take the requested binding set and prefilter it to eliminate redundant validation checks.
+ // Here, the currently bound pipeline determines whether an image validation check is redundant...
+ // for images are the "req" portion of the binding_req is indirectly (but tightly) coupled to the pipeline.
+ const cvdescriptorset::PrefilterBindRequestMap reduced_map(*descriptor_set, set_binding_pair.second, cb_node,
+ pPipe);
+ const auto &binding_req_map = reduced_map.Map();
+
+ if (!descriptor_set->ValidateDrawState(binding_req_map, state.dynamicOffsets[setIndex], cb_node, function,
+ &err_str)) {
+ auto set = descriptor_set->GetSet();
+ result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(set), __LINE__,
+ DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
+ "Descriptor set 0x%" PRIx64 " encountered the following validation error at %s time: %s",
+ HandleToUint64(set), function, err_str.c_str());
+ }
}
}
}
@@ -1214,10 +1223,14 @@ static void UpdateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, cons
// Pull the set node
cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex];
if (!descriptor_set->IsPushDescriptor()) {
+ // For the "bindless" style resource usage with many descriptors, need to optimize command <-> descriptor binding
+ const cvdescriptorset::PrefilterBindRequestMap reduced_map(*descriptor_set, set_binding_pair.second, cb_state);
+ const auto &binding_req_map = reduced_map.Map();
+
// Bind this set and its active descriptor resources to the command buffer
- descriptor_set->BindCommandBuffer(cb_state, set_binding_pair.second);
+ descriptor_set->BindCommandBuffer(cb_state, binding_req_map);
// For given active slots record updated images & buffers
- descriptor_set->GetStorageUpdates(set_binding_pair.second, &cb_state->updateBuffers, &cb_state->updateImages);
+ descriptor_set->GetStorageUpdates(binding_req_map, &cb_state->updateBuffers, &cb_state->updateImages);
}
}
}
@@ -1762,6 +1775,7 @@ static void ResetCommandBufferState(layer_data *dev_data, const VkCommandBuffer
pCB->hasDrawCmd = false;
pCB->state = CB_NEW;
pCB->submitCount = 0;
+ pCB->image_layout_change_count = 1; // Start at 1. 0 is insert value for validation cache versions, s.t. new == dirty
pCB->status = 0;
pCB->static_status = 0;
pCB->viewportMask = 0;
@@ -5369,6 +5383,13 @@ VKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer,
return result;
}
+static void PostCallRecordEndCommandBuffer(layer_data *dev_data, GLOBAL_CB_NODE *cb_state) {
+ // Cached validation is specific to a specific recording of a specific command buffer.
+ for (auto descriptor_set : cb_state->validated_descriptor_sets) {
+ descriptor_set->ClearCachedValidation(cb_state);
+ }
+ cb_state->validated_descriptor_sets.clear();
+}
VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) {
bool skip = false;
@@ -5394,6 +5415,7 @@ VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) {
lock.unlock();
auto result = dev_data->dispatch_table.EndCommandBuffer(commandBuffer);
lock.lock();
+ PostCallRecordEndCommandBuffer(dev_data, pCB);
if (VK_SUCCESS == result) {
pCB->state = CB_RECORDED;
}
@@ -5709,6 +5731,7 @@ static void PreCallRecordCmdBindDescriptorSets(layer_data *device_data, GLOBAL_C
pDynamicOffsets + total_dynamic_descriptors + set_dynamic_descriptor_count);
total_dynamic_descriptors += set_dynamic_descriptor_count;
}
+ cb_state->validated_descriptor_sets.insert(descriptor_set);
}
// For any previously bound sets, need to set them to "invalid" if they were disturbed by this update
if (firstSet > 0) {