aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobin Ehlis <tobine@google.com>2016-08-17 11:10:41 -0600
committerTobin Ehlis <tobine@google.com>2016-08-23 18:41:47 -0600
commit2a408c8aca2cad2621ea15aea293bf438bb11cfa (patch)
tree0f20f4eda3acf9be597c4d63fcd138a73e182b9e
parent30a92dd1dcd3c795110d79c9050194992158e46f (diff)
downloadusermoji-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.cpp46
-rw-r--r--layers/core_validation_error_enums.h1
-rw-r--r--layers/core_validation_types.h3
-rw-r--r--layers/descriptor_sets.cpp38
-rw-r--r--layers/descriptor_sets.h7
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_; }