aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobin Ehlis <tobine@google.com>2016-05-26 11:21:59 -0600
committerTobin Ehlis <tobine@google.com>2016-06-02 09:54:34 -0600
commit2fc91e01eeb0cec1b03332570c5eebe0d380a305 (patch)
tree77b8eca5ab44e0d527d62b37b68a7ed4933681f1
parent3fe78667aeae10ab4fe5cb881d0f67a80200753b (diff)
downloadusermoji-2fc91e01eeb0cec1b03332570c5eebe0d380a305.tar.xz
layers: Add DescriptorSet interface for allocation
Create a top-level "Validate" and "Perform" interface for the vkAllocateDescriptorSets() function in DescriptorSet class. Refactor AllocateDescriptorSets() in core_validation to use the new interface. All checks are now performed in a "Pre" function and all state updates are recorded in a "Post" function.
-rw-r--r--layers/core_validation.cpp106
-rw-r--r--layers/descriptor_sets.cpp93
-rw-r--r--layers/descriptor_sets.h21
3 files changed, 127 insertions, 93 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index cf44ce68..e7201a7d 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -5869,110 +5869,36 @@ ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescript
// Ensure the pool contains enough descriptors and descriptor sets to satisfy
// an allocation request. Fills requiredDescriptorsByType with the total number
// of descriptors of each type required, for later update.
-static bool PreCallValidateAllocateDescriptorSets(const layer_data *dev_data, const DESCRIPTOR_POOL_NODE *pPoolNode, uint32_t count,
- std::vector<cvdescriptorset::DescriptorSetLayout const *> const &layout_nodes,
- uint32_t requiredDescriptorsByType[]) {
- bool skipCall = false;
-
- // Track number of descriptorSets allowable in this pool
- if (pPoolNode->availableSets < count) {
- skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
- reinterpret_cast<const uint64_t &>(pPoolNode->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
- "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64
- ". This pool only has %d descriptorSets remaining.",
- count, reinterpret_cast<const uint64_t &>(pPoolNode->pool), pPoolNode->availableSets);
- }
-
- // Count total descriptors required per type
- for (auto layout_node : layout_nodes) {
- if (layout_node) {
- for (uint32_t j = 0; j < layout_node->GetBindingCount(); ++j) {
- const auto &binding_layout = layout_node->GetDescriptorSetLayoutBindingPtrFromIndex(j);
- uint32_t typeIndex = static_cast<uint32_t>(binding_layout->descriptorType);
- requiredDescriptorsByType[typeIndex] += binding_layout->descriptorCount;
- }
- }
- }
-
- // Determine whether descriptor counts are satisfiable
- for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
- if (requiredDescriptorsByType[i] > pPoolNode->availableDescriptorTypeCount[i]) {
- skipCall |= log_msg(
- dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
- reinterpret_cast<const uint64_t &>(pPoolNode->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
- "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
- ". This pool only has %d descriptors of this type remaining.",
- requiredDescriptorsByType[i], string_VkDescriptorType(VkDescriptorType(i)), (uint64_t)pPoolNode->pool,
- pPoolNode->availableDescriptorTypeCount[i]);
- }
- }
-
- return skipCall;
+static bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo) {
+ // All state checks for AllocateDescriptorSets is done in single function
+ return cvdescriptorset::ValidateAllocateDescriptorSets(dev_data->report_data, pAllocateInfo, dev_data->descriptorSetLayoutMap,
+ dev_data->descriptorPoolMap);
+}
+// Allocation state was good and call down chain was made so update state based on allocating descriptor sets
+static void PostCallRecordAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo,
+ VkDescriptorSet *pDescriptorSets) {
+ // All the updates are contained in a single cvdescriptorset function
+ cvdescriptorset::PerformAllocateDescriptorSets(
+ pAllocateInfo, pDescriptorSets, &dev_data->descriptorPoolMap, &dev_data->setMap, dev_data->descriptorSetLayoutMap,
+ dev_data->bufferMap, dev_data->memObjMap, dev_data->bufferViewMap, dev_data->samplerMap, dev_data->imageViewMap,
+ dev_data->imageMap, dev_data->device_extensions.imageToSwapchainMap, dev_data->device_extensions.swapchainMap);
}
VKAPI_ATTR VkResult VKAPI_CALL
AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) {
- bool skipCall = false;
layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
- uint32_t requiredDescriptorsByType[VK_DESCRIPTOR_TYPE_RANGE_SIZE] {};
- std::vector<cvdescriptorset::DescriptorSetLayout const *> layout_nodes(pAllocateInfo->descriptorSetCount, nullptr);
-
std::unique_lock<std::mutex> lock(global_lock);
-
- for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
- layout_nodes[i] = getDescriptorSetLayout(dev_data, pAllocateInfo->pSetLayouts[i]);
- if (!layout_nodes[i]) {
- skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
- (uint64_t)pAllocateInfo->pSetLayouts[i], __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS",
- "Unable to find set layout node for layout 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
- (uint64_t)pAllocateInfo->pSetLayouts[i]);
- }
- }
-
- DESCRIPTOR_POOL_NODE *pPoolNode = getPoolNode(dev_data, pAllocateInfo->descriptorPool);
-
- if (!pPoolNode) {
- skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
- (uint64_t)pAllocateInfo->descriptorPool, __LINE__, DRAWSTATE_INVALID_POOL, "DS",
- "Unable to find pool node for pool 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
- (uint64_t)pAllocateInfo->descriptorPool);
- } else { // Make sure pool has all the available descriptors before calling down chain
- skipCall |= PreCallValidateAllocateDescriptorSets(dev_data, pPoolNode, pAllocateInfo->descriptorSetCount,
- layout_nodes, requiredDescriptorsByType);
- }
+ bool skip_call = PreCallValidateAllocateDescriptorSets(dev_data, pAllocateInfo);
lock.unlock();
- if (skipCall)
+ if (skip_call)
return VK_ERROR_VALIDATION_FAILED_EXT;
VkResult result = dev_data->device_dispatch_table->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
if (VK_SUCCESS == result) {
lock.lock();
- if (pPoolNode) {
- /* Account for sets and descriptors allocated */
- pPoolNode->availableSets -= pAllocateInfo->descriptorSetCount;
- for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
- pPoolNode->availableDescriptorTypeCount[i] -= requiredDescriptorsByType[i];
- }
-
- /* Create tracking object for each descriptor set; insert into
- * global map and the pool's set.
- */
- for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
- if (layout_nodes[i]) {
- auto pNewNode = new cvdescriptorset::DescriptorSet(
- pDescriptorSets[i], layout_nodes[i], &dev_data->bufferMap, &dev_data->memObjMap, &dev_data->bufferViewMap,
- &dev_data->samplerMap, &dev_data->imageViewMap, &dev_data->imageMap,
- &dev_data->device_extensions.imageToSwapchainMap, &dev_data->device_extensions.swapchainMap);
-
- pPoolNode->sets.insert(pNewNode);
- pNewNode->in_use.store(0);
- dev_data->setMap[pDescriptorSets[i]] = pNewNode;
- }
- }
- }
+ PostCallRecordAllocateDescriptorSets(dev_data, pAllocateInfo, pDescriptorSets);
lock.unlock();
}
return result;
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index 0530f40c..ede1b5a3 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -1222,3 +1222,96 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
// All checks passed so update contents are good
return true;
}
+// Verify that the state at allocate time is correct, but don't actually allocate the sets yet
+bool cvdescriptorset::ValidateAllocateDescriptorSets(
+ const debug_report_data *report_data, const VkDescriptorSetAllocateInfo *p_alloc_info,
+ const std::unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> &set_layout_map,
+ const std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> &pool_map) {
+ bool skip_call = false;
+ uint32_t requiredDescriptorsByType[VK_DESCRIPTOR_TYPE_RANGE_SIZE]{};
+
+ for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
+ auto layout_it = set_layout_map.find(p_alloc_info->pSetLayouts[i]);
+ if (layout_it == set_layout_map.end()) {
+ skip_call |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
+ reinterpret_cast<const uint64_t &>(p_alloc_info->pSetLayouts[i]), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS",
+ "Unable to find set layout node for layout 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
+ reinterpret_cast<const uint64_t &>(p_alloc_info->pSetLayouts[i]));
+ }
+ // Count total descriptors required per type
+ for (uint32_t j = 0; j < layout_it->second->GetBindingCount(); ++j) {
+ const auto &binding_layout = layout_it->second->GetDescriptorSetLayoutBindingPtrFromIndex(j);
+ uint32_t typeIndex = static_cast<uint32_t>(binding_layout->descriptorType);
+ requiredDescriptorsByType[typeIndex] += binding_layout->descriptorCount;
+ }
+ }
+ auto pool_it = pool_map.find(p_alloc_info->descriptorPool);
+ if (pool_it == pool_map.end()) {
+ skip_call |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+ reinterpret_cast<const uint64_t &>(p_alloc_info->descriptorPool), __LINE__, DRAWSTATE_INVALID_POOL, "DS",
+ "Unable to find pool node for pool 0x%" PRIxLEAST64 " specified in vkAllocateDescriptorSets() call",
+ reinterpret_cast<const uint64_t &>(p_alloc_info->descriptorPool));
+ } else { // Make sure pool has all the available descriptors before calling down chain
+ // Track number of descriptorSets allowable in this pool
+ if (pool_it->second->availableSets < p_alloc_info->descriptorSetCount) {
+ skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+ reinterpret_cast<uint64_t &>(pool_it->second->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
+ "DS", "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64
+ ". This pool only has %d descriptorSets remaining.",
+ p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_it->second->pool),
+ pool_it->second->availableSets);
+ }
+ // Determine whether descriptor counts are satisfiable
+ for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
+ if (requiredDescriptorsByType[i] > pool_it->second->availableDescriptorTypeCount[i]) {
+ skip_call |=
+ log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+ reinterpret_cast<const uint64_t &>(pool_it->second->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
+ "DS", "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
+ ". This pool only has %d descriptors of this type remaining.",
+ requiredDescriptorsByType[i], string_VkDescriptorType(VkDescriptorType(i)),
+ reinterpret_cast<uint64_t &>(pool_it->second->pool), pool_it->second->availableDescriptorTypeCount[i]);
+ }
+ }
+ }
+ return skip_call;
+}
+// Decrement allocated sets from the pool and insert new sets into set_map
+void cvdescriptorset::PerformAllocateDescriptorSets(
+ const VkDescriptorSetAllocateInfo *p_alloc_info, const VkDescriptorSet *descriptor_sets,
+ std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *pool_map,
+ std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *set_map,
+ const std::unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> &layout_map,
+ const std::unordered_map<VkBuffer, BUFFER_NODE> &buffer_map,
+ const std::unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> &mem_obj_map,
+ const std::unordered_map<VkBufferView, VkBufferViewCreateInfo> &buffer_view_map,
+ const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> &sampler_map,
+ const std::unordered_map<VkImageView, VkImageViewCreateInfo> &image_view_map,
+ const std::unordered_map<VkImage, IMAGE_NODE> &image_map,
+ const std::unordered_map<VkImage, VkSwapchainKHR> &image_to_swapchain_map,
+ const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> &swapchain_map) {
+ auto pool_state = (*pool_map)[p_alloc_info->descriptorPool];
+ /* Account for sets allocated from pool */
+ pool_state->availableSets -= p_alloc_info->descriptorSetCount;
+ /* Create tracking object for each descriptor set; insert into
+ * global map and the pool's set.
+ */
+ for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
+ auto layout_state = layout_map.find(p_alloc_info->pSetLayouts[i])->second;
+ // Account for individual descriptors allocated from pool
+ for (uint32_t j = 0; j < layout_state->GetBindingCount(); ++j) {
+ const auto &binding_layout = layout_state->GetDescriptorSetLayoutBindingPtrFromIndex(j);
+ uint32_t type_index = static_cast<uint32_t>(binding_layout->descriptorType);
+ pool_state->availableDescriptorTypeCount[type_index] -= binding_layout->descriptorCount;
+ }
+ auto new_ds =
+ new cvdescriptorset::DescriptorSet(descriptor_sets[i], layout_state, &buffer_map, &mem_obj_map, &buffer_view_map,
+ &sampler_map, &image_view_map, &image_map, &image_to_swapchain_map, &swapchain_map);
+
+ pool_state->sets.insert(new_ds);
+ new_ds->in_use.store(0);
+ (*set_map)[descriptor_sets[i]] = new_ds;
+ }
+}
diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h
index b0496b1e..af062dd7 100644
--- a/layers/descriptor_sets.h
+++ b/layers/descriptor_sets.h
@@ -245,14 +245,29 @@ class BufferDescriptor : public Descriptor {
VkDeviceSize offset_;
VkDeviceSize range_;
};
-// Helper functions for Updating descriptor sets since it crosses multiple sets
-// Validate will make sure an update is ok without actually performing it
+// Helper functions for descriptor set functions that cross multiple sets
+// "Validate" will make sure an update is ok without actually performing it
bool ValidateUpdateDescriptorSets(const debug_report_data *,
const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &, uint32_t,
const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *);
-// Perform does the update with the assumption that ValidateUpdateDescriptorSets() has passed for the given update
+// "Perform" does the update with the assumption that ValidateUpdateDescriptorSets() has passed for the given update
void PerformUpdateDescriptorSets(const std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> &, uint32_t,
const VkWriteDescriptorSet *, uint32_t, const VkCopyDescriptorSet *);
+// Validate that Allocation state is ok
+bool ValidateAllocateDescriptorSets(const debug_report_data *, const VkDescriptorSetAllocateInfo *,
+ const std::unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> &,
+ const std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> &);
+// Update state based on allocating new descriptorsets
+void PerformAllocateDescriptorSets(
+ const VkDescriptorSetAllocateInfo *, const VkDescriptorSet *, std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *,
+ std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *,
+ const std::unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> &,
+ const std::unordered_map<VkBuffer, BUFFER_NODE> &, const std::unordered_map<VkDeviceMemory, DEVICE_MEM_INFO> &,
+ const std::unordered_map<VkBufferView, VkBufferViewCreateInfo> &,
+ const std::unordered_map<VkSampler, std::unique_ptr<SAMPLER_NODE>> &,
+ const std::unordered_map<VkImageView, VkImageViewCreateInfo> &, const std::unordered_map<VkImage, IMAGE_NODE> &,
+ const std::unordered_map<VkImage, VkSwapchainKHR> &, const std::unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> &);
+
/*
* DescriptorSet class
*