tests: Add DescriptorBufferUpdateNoMemoryBound test
Attempt a descriptor update with a buffer that hasn't had memory bound to
it and verify that correct error is flagged.
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index e91a3d1..29dd04e 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -7344,6 +7344,97 @@
vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
}
+TEST_F(VkLayerTest, DescriptorBufferUpdateNoMemoryBound) {
+ TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
+ "that doesn't have memory bound");
+ VkResult err;
+ m_errorMonitor->SetDesiredFailureMsg(
+ VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ " used without first calling vkBindBufferMemory.");
+
+ ASSERT_NO_FATAL_FAILURE(InitState());
+ ASSERT_NO_FATAL_FAILURE(InitViewport());
+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+ VkDescriptorPoolSize ds_type_count = {};
+ ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+ ds_type_count.descriptorCount = 1;
+
+ VkDescriptorPoolCreateInfo ds_pool_ci = {};
+ ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ ds_pool_ci.pNext = NULL;
+ ds_pool_ci.maxSets = 1;
+ ds_pool_ci.poolSizeCount = 1;
+ ds_pool_ci.pPoolSizes = &ds_type_count;
+
+ VkDescriptorPool ds_pool;
+ err =
+ vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+ ASSERT_VK_SUCCESS(err);
+
+ VkDescriptorSetLayoutBinding dsl_binding = {};
+ dsl_binding.binding = 0;
+ dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+ dsl_binding.descriptorCount = 1;
+ dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+ dsl_binding.pImmutableSamplers = NULL;
+
+ VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+ ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ ds_layout_ci.pNext = NULL;
+ ds_layout_ci.bindingCount = 1;
+ ds_layout_ci.pBindings = &dsl_binding;
+ VkDescriptorSetLayout ds_layout;
+ err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL,
+ &ds_layout);
+ ASSERT_VK_SUCCESS(err);
+
+ VkDescriptorSet descriptorSet;
+ VkDescriptorSetAllocateInfo alloc_info = {};
+ alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ alloc_info.descriptorSetCount = 1;
+ alloc_info.descriptorPool = ds_pool;
+ alloc_info.pSetLayouts = &ds_layout;
+ err = vkAllocateDescriptorSets(m_device->device(), &alloc_info,
+ &descriptorSet);
+ ASSERT_VK_SUCCESS(err);
+
+ // Create a buffer to update the descriptor with
+ uint32_t qfi = 0;
+ VkBufferCreateInfo buffCI = {};
+ buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ buffCI.size = 1024;
+ buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ buffCI.queueFamilyIndexCount = 1;
+ buffCI.pQueueFamilyIndices = &qfi;
+
+ VkBuffer dyub;
+ err = vkCreateBuffer(m_device->device(), &buffCI, NULL, &dyub);
+ ASSERT_VK_SUCCESS(err);
+
+ // Attempt to update descriptor without binding memory to it
+ VkDescriptorBufferInfo buffInfo = {};
+ buffInfo.buffer = dyub;
+ buffInfo.offset = 0;
+ buffInfo.range = 1024;
+
+ VkWriteDescriptorSet descriptor_write;
+ memset(&descriptor_write, 0, sizeof(descriptor_write));
+ descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ descriptor_write.dstSet = descriptorSet;
+ descriptor_write.dstBinding = 0;
+ descriptor_write.descriptorCount = 1;
+ descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
+ descriptor_write.pBufferInfo = &buffInfo;
+
+ vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+ m_errorMonitor->VerifyFound();
+
+ vkDestroyBuffer(m_device->device(), dyub, NULL);
+ vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+ vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
TEST_F(VkLayerTest, InvalidPushConstants) {
VkResult err;
ASSERT_NO_FATAL_FAILURE(InitState());