layers: Validate VkMutableDescriptorTypeList
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index cd4864c..abe346c 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -3646,6 +3646,86 @@
return skip;
}
+bool StatelessValidation::ValidateMutableDescriptorTypeCreateInfo(const VkDescriptorSetLayoutCreateInfo &create_info,
+ const VkMutableDescriptorTypeCreateInfoVALVE &mutable_create_info,
+ const char *func_name) const {
+ bool skip = false;
+
+ for (uint32_t i = 0; i < create_info.bindingCount; ++i) {
+ uint32_t mutable_type_count = 0;
+ if (mutable_create_info.mutableDescriptorTypeListCount > i) {
+ mutable_type_count = mutable_create_info.pMutableDescriptorTypeLists[i].descriptorTypeCount;
+ }
+ if (create_info.pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
+ if (mutable_type_count == 0) {
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-descriptorTypeCount-04597",
+ "%s: VkDescriptorSetLayoutCreateInfo::pBindings[%" PRIu32
+ "].descriptorType is VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but "
+ "VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].descriptorTypeCount is 0.",
+ func_name, i, i);
+ }
+ } else {
+ if (mutable_type_count > 0) {
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-descriptorTypeCount-04599",
+ "%s: VkDescriptorSetLayoutCreateInfo::pBindings[%" PRIu32
+ "].descriptorType is %s, but "
+ "VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].descriptorTypeCount is not 0.",
+ func_name, i, string_VkDescriptorType(create_info.pBindings[i].descriptorType), i);
+ }
+ }
+ }
+
+ for (uint32_t j = 0; j < mutable_create_info.mutableDescriptorTypeListCount; ++j) {
+ for (uint32_t k = 0; k < mutable_create_info.pMutableDescriptorTypeLists[j].descriptorTypeCount; ++k) {
+ switch (mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k]) {
+ case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-pDescriptorTypes-04600",
+ "%s: VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32 "] is VK_DESCRIPTOR_TYPE_MUTABLE_VALVE.",
+ func_name, j, k);
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-pDescriptorTypes-04601",
+ "%s: VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32 "] is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.",
+ func_name, j, k);
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-pDescriptorTypes-04602",
+ "%s: VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32 "] is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.",
+ func_name, j, k);
+ break;
+ case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
+ skip |= LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-pDescriptorTypes-04603",
+ "%s: VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32 "] is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT.",
+ func_name, j, k);
+ break;
+ default:
+ break;
+ }
+ for (uint32_t l = k + 1; l < mutable_create_info.pMutableDescriptorTypeLists[j].descriptorTypeCount; ++l) {
+ if (mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k] ==
+ mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[l]) {
+ skip |=
+ LogError(device, "VUID-VkMutableDescriptorTypeListVALVE-pDescriptorTypes-04598",
+ "%s: VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32
+ "] and VkMutableDescriptorTypeCreateInfoVALVE::pMutableDescriptorTypeLists[%" PRIu32
+ "].pDescriptorTypes[%" PRIu32 "] are both %s.",
+ func_name, j, k, j, l,
+ string_VkDescriptorType(mutable_create_info.pMutableDescriptorTypeLists[j].pDescriptorTypes[k]));
+ }
+ }
+ }
+ }
+
+ return skip;
+}
+
bool StatelessValidation::manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
@@ -3734,6 +3814,11 @@
}
}
}
+
+ if (mutable_descriptor_type) {
+ ValidateMutableDescriptorTypeCreateInfo(*pCreateInfo, *mutable_descriptor_type,
+ "vkDescriptorSetLayoutCreateInfo");
+ }
}
if (pCreateInfo) {
if ((pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) &&
diff --git a/layers/stateless_validation.h b/layers/stateless_validation.h
index f1b304d..62f708c 100644
--- a/layers/stateless_validation.h
+++ b/layers/stateless_validation.h
@@ -1420,6 +1420,9 @@
bool manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) const;
+ bool ValidateMutableDescriptorTypeCreateInfo(const VkDescriptorSetLayoutCreateInfo &create_info,
+ const VkMutableDescriptorTypeCreateInfoVALVE &mutable_create_info,
+ const char *func_name) const;
bool manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDescriptorSetLayout *pSetLayout) const;