summaryrefslogtreecommitdiff
path: root/layers
diff options
context:
space:
mode:
authorTobin Ehlis <tobine@google.com>2016-08-17 09:49:13 -0600
committerTobin Ehlis <tobine@google.com>2016-08-23 18:41:47 -0600
commitaa21bc3b3c5c7adfeb488fc80bdcb339d63615b8 (patch)
tree08c247fffafa89ab328eb75d6e4c114220fe5a48 /layers
parent5c288f35b2eab0dab95d18768235fef6ffd69b30 (diff)
layers: Only bind active sets to cmd buffers
Don't create a binding between every set bound to a cmd buffer, but only the sets that are verified active at draw time. Gather up active descriptorset bindings in prepration of also binding the resources from each individual active set to the cmd buffer.
Diffstat (limited to 'layers')
-rw-r--r--layers/core_validation.cpp25
-rw-r--r--layers/descriptor_sets.cpp8
-rw-r--r--layers/descriptor_sets.h2
3 files changed, 23 insertions, 12 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index fef906ad..38e4b2f7 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -3083,10 +3083,10 @@ static bool validatePipelineDrawtimeState(layer_data const *my_data,
}
// Validate overall state at the time of a draw call
-static bool validate_and_update_draw_state(layer_data *my_data, GLOBAL_CB_NODE *pCB, const bool indexedDraw,
+static bool validate_and_update_draw_state(layer_data *my_data, GLOBAL_CB_NODE *cb_node, const bool indexedDraw,
const VkPipelineBindPoint bindPoint, const char *function) {
bool result = false;
- auto const &state = pCB->lastBound[bindPoint];
+ auto const &state = cb_node->lastBound[bindPoint];
PIPELINE_NODE *pPipe = state.pipeline_node;
if (nullptr == pPipe) {
result |= log_msg(
@@ -3099,7 +3099,7 @@ static bool validate_and_update_draw_state(layer_data *my_data, GLOBAL_CB_NODE *
}
// First check flag states
if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint)
- result = validate_draw_state_flags(my_data, pCB, pPipe, indexedDraw);
+ result = validate_draw_state_flags(my_data, cb_node, pPipe, indexedDraw);
// Now complete other state checks
if (VK_NULL_HANDLE != state.pipeline_layout.layout) {
@@ -3130,14 +3130,20 @@ static bool validate_and_update_draw_state(layer_data *my_data, GLOBAL_CB_NODE *
} else { // Valid set is bound and layout compatible, validate that it's updated
// Pull the set node
cvdescriptorset::DescriptorSet *pSet = state.boundDescriptorSets[setIndex];
+ // Gather active bindings
+ std::unordered_set<uint32_t> bindings;
+ for (auto binding : setBindingPair.second) {
+ bindings.insert(binding.first);
+ }
+ // Bind this set and its active descriptor resources to the command buffer
+ pSet->BindCommandBuffer(cb_node, bindings);
// Save vector of all active sets to verify dynamicOffsets below
- activeSetBindingsPairs.push_back(std::make_tuple(pSet, setBindingPair.second,
- &state.dynamicOffsets[setIndex]));
+ activeSetBindingsPairs.push_back(std::make_tuple(pSet, setBindingPair.second, &state.dynamicOffsets[setIndex]));
// Make sure set has been updated if it has no immutable samplers
// If it has immutable samplers, we'll flag error later as needed depending on binding
if (!pSet->IsUpdated()) {
- for (auto binding : setBindingPair.second) {
- if (!pSet->GetImmutableSamplerPtrFromBinding(binding.first)) {
+ for (auto binding : bindings) {
+ if (!pSet->GetImmutableSamplerPtrFromBinding(binding)) {
result |= log_msg(
my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
(uint64_t)pSet->GetSet(), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
@@ -3150,12 +3156,12 @@ static bool validate_and_update_draw_state(layer_data *my_data, GLOBAL_CB_NODE *
}
}
// For given active slots, verify any dynamic descriptors and record updated images & buffers
- result |= validate_and_update_drawtime_descriptor_state(my_data, pCB, activeSetBindingsPairs, function);
+ result |= validate_and_update_drawtime_descriptor_state(my_data, cb_node, activeSetBindingsPairs, function);
}
// Check general pipeline state that needs to be validated at drawtime
if (VK_PIPELINE_BIND_POINT_GRAPHICS == bindPoint)
- result |= validatePipelineDrawtimeState(my_data, state, pCB, pPipe);
+ result |= validatePipelineDrawtimeState(my_data, state, cb_node, pPipe);
return result;
}
@@ -6998,7 +7004,6 @@ CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelin
for (uint32_t i = 0; i < setCount; i++) {
cvdescriptorset::DescriptorSet *pSet = getSetNode(dev_data, pDescriptorSets[i]);
if (pSet) {
- pSet->BindCommandBuffer(pCB);
pCB->lastBound[pipelineBindPoint].pipeline_layout = *pipeline_layout;
pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i + firstSet] = pSet;
skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index d9eb2777..38915b68 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -624,7 +624,11 @@ void cvdescriptorset::DescriptorSet::PerformCopyUpdate(const VkCopyDescriptorSet
InvalidateBoundCmdBuffers();
}
-void cvdescriptorset::DescriptorSet::BindCommandBuffer(GLOBAL_CB_NODE *cb_node) {
+// Bind cb_node to this set and this set to cb_node.
+// Prereq: This should be called for a set that has been confirmed to be active for the given cb_node, meaning it's going
+// to be used in a draw by the given cb_node
+// TODO: For all of the active bindings, bind their underlying image/buffer/sampler resources to the cb_node
+void cvdescriptorset::DescriptorSet::BindCommandBuffer(GLOBAL_CB_NODE *cb_node, const std::unordered_set<uint32_t> &bindings) {
// bind cb to this descriptor set
cb_bindings.insert(cb_node);
// Add bindings for descriptor set and individual objects in the set
@@ -632,6 +636,8 @@ void cvdescriptorset::DescriptorSet::BindCommandBuffer(GLOBAL_CB_NODE *cb_node)
// TODO : Can bind individual objects from within each descriptor : buffers/images and their views, samplers & memory
// The trick is we should only bind the objects actually "in use" by the cmd buffer, meaning that we need to
// check active descriptor slots based on last bound state for this CB
+ // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's
+ // resources
}
cvdescriptorset::SamplerDescriptor::SamplerDescriptor() : sampler_(VK_NULL_HANDLE), immutable_(false) {
diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h
index 6656873a..42c5895d 100644
--- a/layers/descriptor_sets.h
+++ b/layers/descriptor_sets.h
@@ -334,7 +334,7 @@ class DescriptorSet : public BASE_NODE {
// Return unordered_set of all command buffers that this set is bound to
std::unordered_set<GLOBAL_CB_NODE *> GetBoundCmdBuffers() const { return cb_bindings; }
// Bind given cmd_buffer to this descriptor set
- void BindCommandBuffer(GLOBAL_CB_NODE *cb_node);
+ void BindCommandBuffer(GLOBAL_CB_NODE *, const std::unordered_set<uint32_t> &);
// If given cmd_buffer is in the cb_bindings set, remove it
void RemoveBoundCommandBuffer(GLOBAL_CB_NODE *cb_node) { cb_bindings.erase(cb_node); }
VkSampler const *GetImmutableSamplerPtrFromBinding(const uint32_t index) const {