diff options
-rw-r--r-- | layers/core_validation.cpp | 25 | ||||
-rw-r--r-- | layers/descriptor_sets.cpp | 8 | ||||
-rw-r--r-- | layers/descriptor_sets.h | 2 |
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 { |