diff options
| author | Tobin Ehlis <tobine@google.com> | 2016-08-17 11:10:41 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2016-08-23 18:41:47 -0600 |
| commit | 2a408c8aca2cad2621ea15aea293bf438bb11cfa (patch) | |
| tree | 0f20f4eda3acf9be597c4d63fcd138a73e182b9e | |
| parent | 30a92dd1dcd3c795110d79c9050194992158e46f (diff) | |
| download | usermoji-2a408c8aca2cad2621ea15aea293bf438bb11cfa.tar.xz | |
layers: Add tracking between sampler and cmd buffer
Update SAMPLER_NODE to inherit from BASE_NODE and keep track of
cb_bindings for sampler.
At draw time, add any bindings between cmd buffer and samplers that
are connected to active descriptors.
At DestroySampler() time, set CB_INVALID for any cmd buffers in
cb_bindings.
Also includes some additional plumbing to prepare for connecting
images/buffers that are tied to descriptor sets to cmd buffers that
those sets are bound to.
| -rw-r--r-- | layers/core_validation.cpp | 46 | ||||
| -rw-r--r-- | layers/core_validation_error_enums.h | 1 | ||||
| -rw-r--r-- | layers/core_validation_types.h | 3 | ||||
| -rw-r--r-- | layers/descriptor_sets.cpp | 38 | ||||
| -rw-r--r-- | layers/descriptor_sets.h | 7 |
5 files changed, 91 insertions, 4 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 38e4b2f7..da54af74 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -517,7 +517,13 @@ static bool update_cmd_buf_and_mem_references(layer_data *dev_data, const VkComm return skip_call; } -// Create binding link between given iamge node and command buffer node +// Create binding link between given sampler and command buffer node +void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *cb_node, SAMPLER_NODE *sampler_node) { + sampler_node->cb_bindings.insert(cb_node); + cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(sampler_node->sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT}); +} + +// Create binding link between given image node and command buffer node static bool addCommandBufferBindingImage(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_NODE *img_node, const char *apiName) { bool skip_call = false; // Skip validation if this image was created through WSI @@ -668,6 +674,8 @@ static const char *object_type_to_string(VkDebugReportObjectTypeEXT type) { return "query pool"; case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "pipeline"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: + return "sampler"; default: return "unknown"; } @@ -3943,6 +3951,12 @@ static void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *ob set_node->RemoveBoundCommandBuffer(cb_node); break; } + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: { + auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<const VkSampler &>(object->handle)); + if (sampler_node) + sampler_node->cb_bindings.erase(cb_node); + break; + } default: assert(0); // unhandled object type } @@ -4478,6 +4492,17 @@ static bool ValidateAndIncrementBoundObjects(layer_data const *dev_data, GLOBAL_ } break; } + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: { + auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<VkSampler &>(obj.handle)); + if (!sampler_node) { + skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, + obj.handle, __LINE__, DRAWSTATE_INVALID_SAMPLER, "DS", + "Cannot submit cmd buffer using deleted sampler 0x%" PRIx64 ".", obj.handle); + } else { + sampler_node->in_use.fetch_add(1); + } + break; + } default: // TODO : Merge handling of other objects types into this code break; @@ -4571,6 +4596,11 @@ static void DecrementBoundResources(layer_data const *dev_data, GLOBAL_CB_NODE c set_node->in_use.fetch_sub(1); break; } + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: { + auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<VkSampler &>(obj.handle)); + sampler_node->in_use.fetch_sub(1); + break; + } default: // TODO : Merge handling of other objects types into this code break; @@ -5701,8 +5731,18 @@ DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const Vk VKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) { - // TODO : Clean up any internal data structures using this obj. - get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySampler(device, sampler, pAllocator); + layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + // TODO : Add detection for in-flight sampler + std::unique_lock<std::mutex> lock(global_lock); + auto sampler_node = getSamplerNode(dev_data, sampler); + if (sampler_node) { + // Any bound cmd buffers are now invalid + invalidateCommandBuffers(sampler_node->cb_bindings, + {reinterpret_cast<uint64_t &>(sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT}); + dev_data->samplerMap.erase(sampler); + } + lock.unlock(); + dev_data->device_dispatch_table->DestroySampler(device, sampler, pAllocator); } VKAPI_ATTR void VKAPI_CALL diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h index e58b294b..8ceba84d 100644 --- a/layers/core_validation_error_enums.h +++ b/layers/core_validation_error_enums.h @@ -63,6 +63,7 @@ enum DRAW_STATE_ERROR { DRAWSTATE_INVALID_QUERY, // Invalid Query DRAWSTATE_INVALID_FENCE, // Invalid Fence DRAWSTATE_INVALID_EVENT, // Invalid Event + DRAWSTATE_INVALID_SAMPLER, // Invalid Sampler DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, // binding in vkCmdBindVertexData() too // large for PSO's // pVertexBindingDescriptions array diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index 6ac0bd76..bb41ec29 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -159,7 +159,7 @@ class BUFFER_NODE : public BASE_NODE { }; }; -struct SAMPLER_NODE { +struct SAMPLER_NODE : public BASE_NODE { VkSampler sampler; VkSamplerCreateInfo createInfo; @@ -657,6 +657,7 @@ VkSwapchainKHR getSwapchainFromImage(const layer_data *, VkImage); SWAPCHAIN_NODE *getSwapchainNode(const layer_data *, VkSwapchainKHR); void invalidateCommandBuffers(std::unordered_set<GLOBAL_CB_NODE *>, VK_OBJECT); bool ValidateMemoryIsBoundToBuffer(const layer_data *, const BUFFER_NODE *, const char *); +void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *, SAMPLER_NODE *); } #endif // CORE_VALIDATION_TYPES_H_ diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp index 38915b68..c07f505e 100644 --- a/layers/descriptor_sets.cpp +++ b/layers/descriptor_sets.cpp @@ -638,6 +638,13 @@ void cvdescriptorset::DescriptorSet::BindCommandBuffer(GLOBAL_CB_NODE *cb_node, // 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 + for (auto binding : bindings) { + auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(binding); + auto end_idx = p_layout_->GetGlobalEndIndexFromBinding(binding); + for (uint32_t i = start_idx; i <= end_idx; ++i) { + descriptors_[i]->BindCommandBuffer(device_data_, cb_node); + } + } } cvdescriptorset::SamplerDescriptor::SamplerDescriptor() : sampler_(VK_NULL_HANDLE), immutable_(false) { @@ -815,6 +822,14 @@ void cvdescriptorset::SamplerDescriptor::CopyUpdate(const Descriptor *src) { updated = true; } +void cvdescriptorset::SamplerDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { + if (!immutable_) { + auto sampler_node = getSamplerNode(dev_data, sampler_); + if (sampler_node) + core_validation::AddCommandBufferBindingSampler(cb_node, sampler_node); + } +} + cvdescriptorset::ImageSamplerDescriptor::ImageSamplerDescriptor() : sampler_(VK_NULL_HANDLE), immutable_(false), image_view_(VK_NULL_HANDLE), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) { updated = false; @@ -852,6 +867,16 @@ void cvdescriptorset::ImageSamplerDescriptor::CopyUpdate(const Descriptor *src) image_layout_ = image_layout; } +void cvdescriptorset::ImageSamplerDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, + GLOBAL_CB_NODE *cb_node) { + if (!immutable_) { + auto sampler_node = getSamplerNode(dev_data, sampler_); + if (sampler_node) + core_validation::AddCommandBufferBindingSampler(cb_node, sampler_node); + } + // TODO : add cb_binding for image +} + cvdescriptorset::ImageDescriptor::ImageDescriptor(const VkDescriptorType type) : storage_(false), image_view_(VK_NULL_HANDLE), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) { updated = false; @@ -875,6 +900,10 @@ void cvdescriptorset::ImageDescriptor::CopyUpdate(const Descriptor *src) { image_layout_ = image_layout; } +void cvdescriptorset::ImageDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { + // TODO : bind image and cmd buffer +} + cvdescriptorset::BufferDescriptor::BufferDescriptor(const VkDescriptorType type) : storage_(false), dynamic_(false), buffer_(VK_NULL_HANDLE), offset_(0), range_(0) { updated = false; @@ -904,6 +933,10 @@ void cvdescriptorset::BufferDescriptor::CopyUpdate(const Descriptor *src) { range_ = buff_desc->range_; } +void cvdescriptorset::BufferDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { + // TODO : bind buffer and cmd buffer +} + cvdescriptorset::TexelDescriptor::TexelDescriptor(const VkDescriptorType type) : buffer_view_(VK_NULL_HANDLE), storage_(false) { updated = false; descriptor_class = TexelBuffer; @@ -920,6 +953,11 @@ void cvdescriptorset::TexelDescriptor::CopyUpdate(const Descriptor *src) { updated = true; buffer_view_ = static_cast<const TexelDescriptor *>(src)->buffer_view_; } + +void cvdescriptorset::TexelDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { + // TODO : bind buffer and cmd buffer +} + // This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated // sets, and then calls their respective Validate[Write|Copy]Update functions. // If the update hits an issue for which the callback returns "true", meaning that the call down the chain should diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h index 42c5895d..92eb09a2 100644 --- a/layers/descriptor_sets.h +++ b/layers/descriptor_sets.h @@ -149,6 +149,8 @@ class Descriptor { virtual ~Descriptor(){}; virtual void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) = 0; virtual void CopyUpdate(const Descriptor *) = 0; + // Create binding between resources of this descriptor and given cb_node + virtual void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) = 0; virtual DescriptorClass GetClass() const { return descriptor_class; }; // Special fast-path check for SamplerDescriptors that are immutable virtual bool IsImmutableSampler() const { return false; }; @@ -170,6 +172,7 @@ class SamplerDescriptor : public Descriptor { SamplerDescriptor(const VkSampler *); void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) override; void CopyUpdate(const Descriptor *) override; + void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) override; virtual bool IsImmutableSampler() const override { return immutable_; }; VkSampler GetSampler() const { return sampler_; } @@ -185,6 +188,7 @@ class ImageSamplerDescriptor : public Descriptor { ImageSamplerDescriptor(const VkSampler *); void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) override; void CopyUpdate(const Descriptor *) override; + void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) override; virtual bool IsImmutableSampler() const override { return immutable_; }; VkSampler GetSampler() const { return sampler_; } VkImageView GetImageView() const { return image_view_; } @@ -202,6 +206,7 @@ class ImageDescriptor : public Descriptor { ImageDescriptor(const VkDescriptorType); void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) override; void CopyUpdate(const Descriptor *) override; + void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) override; virtual bool IsStorage() const override { return storage_; } VkImageView GetImageView() const { return image_view_; } VkImageLayout GetImageLayout() const { return image_layout_; } @@ -217,6 +222,7 @@ class TexelDescriptor : public Descriptor { TexelDescriptor(const VkDescriptorType); void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) override; void CopyUpdate(const Descriptor *) override; + void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) override; virtual bool IsStorage() const override { return storage_; } VkBufferView GetBufferView() const { return buffer_view_; } @@ -230,6 +236,7 @@ class BufferDescriptor : public Descriptor { BufferDescriptor(const VkDescriptorType); void WriteUpdate(const VkWriteDescriptorSet *, const uint32_t) override; void CopyUpdate(const Descriptor *) override; + void BindCommandBuffer(const core_validation::layer_data *, GLOBAL_CB_NODE *) override; virtual bool IsDynamic() const override { return dynamic_; } virtual bool IsStorage() const override { return storage_; } VkBuffer GetBuffer() const { return buffer_; } |
