layers: Validate image view type requirement for descriptor sets
Signed-off-by: Chris Forbes <chrisforbes@google.com>
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index b3a4967..21c2060 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -327,10 +327,24 @@
}
}
}
+
+
+static char const * string_descriptor_req_view_type(descriptor_req req) {
+ for (unsigned i = 0; i <= VK_IMAGE_VIEW_TYPE_END_RANGE; i++) {
+ if (req & (1 << i)) {
+ return string_VkImageViewType(VkImageViewType(i));
+ }
+ }
+
+ return "(none)";
+}
+
+
// Is this sets underlying layout compatible with passed in layout according to "Pipeline Layout Compatibility" in spec?
bool cvdescriptorset::DescriptorSet::IsCompatible(const DescriptorSetLayout *layout, std::string *error) const {
return layout->IsCompatible(p_layout_, error);
}
+
// Validate that the state of this set is appropriate for the given bindings and dynami_offsets at Draw time
// This includes validating that all descriptors in the given bindings are updated,
// that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
@@ -360,7 +374,8 @@
*error = error_str.str();
return false;
} else {
- if (GeneralBuffer == descriptors_[i]->GetClass()) {
+ auto descriptor_class = descriptors_[i]->GetClass();
+ if (descriptor_class == GeneralBuffer) {
// Verify that buffers are valid
auto buffer = static_cast<BufferDescriptor *>(descriptors_[i].get())->GetBuffer();
auto buffer_node = getBufferNode(device_data_, buffer);
@@ -411,12 +426,54 @@
}
}
}
+ else if (descriptor_class == ImageSampler || descriptor_class == Image) {
+ auto image_view = (descriptor_class == ImageSampler)
+ ? static_cast<ImageSamplerDescriptor *>(descriptors_[i].get())->GetImageView()
+ : static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageView();
+ auto reqs = binding_pair.second;
+
+ auto image_view_data = getImageViewData(device_data_, image_view);
+ assert(image_view_data);
+
+ if (~reqs & (1 << image_view_data->viewType)) {
+ // bad view type
+ std::stringstream error_str;
+ error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+ << " requires an image view of type " << string_descriptor_req_view_type(reqs)
+ << " but got " << string_VkImageViewType(image_view_data->viewType) << ".";
+ *error = error_str.str();
+ return false;
+ }
+
+ auto image_node = getImageNode(device_data_, image_view_data->image);
+ assert(image_node);
+
+ if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) &&
+ image_node->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) {
+ std::stringstream error_str;
+ error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+ << " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got "
+ << string_VkSampleCountFlagBits(image_node->createInfo.samples) << ".";
+ *error = error_str.str();
+ return false;
+ }
+
+ if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) &&
+ image_node->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) {
+ std::stringstream error_str;
+ error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
+ << " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT.";
+ *error = error_str.str();
+ return false;
+ }
+ }
}
}
}
}
return true;
}
+
// For given bindings, place any update buffers or images into the passed-in unordered_sets
uint32_t cvdescriptorset::DescriptorSet::GetStorageUpdates(const std::unordered_map<uint32_t, descriptor_req> &bindings,
std::unordered_set<VkBuffer> *buffer_set,