tests: Add validation for layout lifetime issues
authorJohn Zulauf <jzulauf@lunarg.com>
Wed, 17 Jan 2018 18:23:49 +0000 (11:23 -0700)
committerjzulauf-lunarg <32470354+jzulauf-lunarg@users.noreply.github.com>
Thu, 18 Jan 2018 17:20:18 +0000 (10:20 -0700)
Add unit tests for valid usages that flag when descriptor set update
operations are being performed with descriptor sets create from
destroyed descriptor set layouts. The tests use overloaded VUIDs
(generic "must be valid * handles) which need to be replaced (and
unclaimed) with specific ones when they are added to the spec.

    VALIDATION_ERROR_15c00280 (write dst must be valid) ->
            write dst created from destroyed layout
    VALIDATION_ERROR_03207601 (copy dst must be valid) ->
            copy dst created from destroyed layout
    VALIDATION_ERROR_0322d201 (copy src must be valid) ->
            copy src created from destroyed layout

Change-Id: Ic37a745120899c072e2e5d8ceb96c5d93074355e

layers/vk_validation_error_database.txt
tests/layer_validation_tests.cpp

index 5581de3..ed53c3a 100644 (file)
@@ -292,10 +292,10 @@ VALIDATION_ERROR_032002b4~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDe
 VALIDATION_ERROR_032002b6~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-dstBinding-00347~^~core~^~The spec valid usage text states 'dstBinding must be a valid binding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-dstBinding-00347)~^~
 VALIDATION_ERROR_032002b8~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-dstArrayElement-00348~^~core~^~The spec valid usage text states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-dstArrayElement-00348)~^~
 VALIDATION_ERROR_032002ba~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-srcSet-00349~^~core~^~The spec valid usage text states 'If srcSet is equal to dstSet, then the source and destination ranges of descriptors must not overlap, where the ranges may include array elements from consecutive bindings as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-srcSet-00349)~^~
-VALIDATION_ERROR_03207601~^~Y~^~None~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-dstSet-parameter~^~core~^~The spec valid usage text states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-dstSet-parameter)~^~implicit
+VALIDATION_ERROR_03207601~^~Y~^~UpdateDestroyDescriptorSetLayout~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-dstSet-parameter~^~core~^~The spec valid usage text states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-dstSet-parameter)~^~implicit
 VALIDATION_ERROR_0321c40d~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-pNext-pNext~^~core~^~The spec valid usage text states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-pNext-pNext)~^~implicit, TBD in parameter validation layer.
 VALIDATION_ERROR_0322b00b~^~N~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-sType-sType~^~core~^~The spec valid usage text states 'sType must be VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-sType-sType)~^~implicit, TBD in parameter validation layer.
-VALIDATION_ERROR_0322d201~^~Y~^~None~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-srcSet-parameter~^~core~^~The spec valid usage text states 'srcSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-srcSet-parameter)~^~implicit
+VALIDATION_ERROR_0322d201~^~Y~^~UpdateDestroyDescriptorSetLayout~^~vkUpdateDescriptorSets~^~VUID-VkCopyDescriptorSet-srcSet-parameter~^~core~^~The spec valid usage text states 'srcSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkCopyDescriptorSet-srcSet-parameter)~^~implicit
 VALIDATION_ERROR_0340009e~^~N~^~Unknown~^~vkQueueSubmit~^~VUID-VkD3D12FenceSubmitInfoKHR-waitSemaphoreValuesCount-00079~^~core~^~The spec valid usage text states 'waitSemaphoreValuesCount must be the same value as VkSubmitInfo::waitSemaphoreCount, where VkSubmitInfo is in the pNext chain of this VkD3D12FenceSubmitInfoKHR structure.' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkD3D12FenceSubmitInfoKHR-waitSemaphoreValuesCount-00079)~^~
 VALIDATION_ERROR_034000a0~^~N~^~Unknown~^~vkQueueSubmit~^~VUID-VkD3D12FenceSubmitInfoKHR-signalSemaphoreValuesCount-00080~^~core~^~The spec valid usage text states 'signalSemaphoreValuesCount must be the same value as VkSubmitInfo::signalSemaphoreCount, where VkSubmitInfo is in the pNext chain of this VkD3D12FenceSubmitInfoKHR structure.' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkD3D12FenceSubmitInfoKHR-signalSemaphoreValuesCount-00080)~^~
 VALIDATION_ERROR_03423201~^~N~^~Unknown~^~vkQueueSubmit~^~VUID-VkD3D12FenceSubmitInfoKHR-pSignalSemaphoreValues-parameter~^~core~^~The spec valid usage text states 'If signalSemaphoreValuesCount is not 0, and pSignalSemaphoreValues is not NULL, pSignalSemaphoreValues must be a valid pointer to an array of signalSemaphoreValuesCount uint64_t values' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkD3D12FenceSubmitInfoKHR-pSignalSemaphoreValues-parameter)~^~implicit
@@ -1591,7 +1591,7 @@ VALIDATION_ERROR_15c00278~^~Y~^~DSUpdateEmptyBinding~^~vkUpdateDescriptorSets~^~
 VALIDATION_ERROR_15c0027a~^~N~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-descriptorCount-00317~^~core~^~The spec valid usage text states 'All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a descriptorCount of zero, must have identical descriptorType and stageFlags.' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorCount-00317)~^~
 VALIDATION_ERROR_15c0027c~^~N~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-descriptorCount-00318~^~core~^~The spec valid usage text states 'All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those with a descriptorCount of zero, must all either use immutable samplers or must all not use immutable samplers.' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorCount-00318)~^~
 VALIDATION_ERROR_15c0027e~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-descriptorType-00319~^~core~^~The spec valid usage text states 'descriptorType must match the type of dstBinding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorType-00319)~^~
-VALIDATION_ERROR_15c00280~^~Y~^~None~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-dstSet-00320~^~core~^~The spec valid usage text states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-dstSet-00320)~^~implicit
+VALIDATION_ERROR_15c00280~^~Y~^~UpdateDestroyDescriptorSetLayout~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-dstSet-00320~^~core~^~The spec valid usage text states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-dstSet-00320)~^~implicit
 VALIDATION_ERROR_15c00282~^~Y~^~WriteDescriptorSetIntegrityCheck,DSUpdateOutOfBounds~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-dstArrayElement-00321~^~core~^~The spec valid usage text states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-dstArrayElement-00321)~^~
 VALIDATION_ERROR_15c00284~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-descriptorType-00322~^~core~^~The spec valid usage text states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo must be a valid pointer to an array of descriptorCount valid VkDescriptorImageInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorType-00322)~^~
 VALIDATION_ERROR_15c00286~^~Y~^~InvalidBufferViewObject~^~vkUpdateDescriptorSets~^~VUID-VkWriteDescriptorSet-descriptorType-00323~^~core~^~The spec valid usage text states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBufferView must be a valid pointer to an array of descriptorCount valid VkBufferView handles' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorType-00323)~^~
index 23efe79..1244637 100644 (file)
@@ -15018,6 +15018,89 @@ TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
     vkDestroyImageView(m_device->device(), view, NULL);
 }
 
+TEST_F(VkLayerTest, UpdateDestroyDescriptorSetLayout) {
+    TEST_DESCRIPTION("Attempt updates to descriptor sets with destroyed descriptor set layouts");
+    // TODO: Update to match the descriptor set layout specific VUIDs/VALIDATION_ERROR_* when present
+    const auto kWriteDestroyedLayout = VALIDATION_ERROR_15c00280;
+    const auto kCopyDstDestroyedLayout = VALIDATION_ERROR_03207601;
+    const auto kCopySrcDestroyedLayout = VALIDATION_ERROR_0322d201;
+
+    ASSERT_NO_FATAL_FAILURE(Init());
+
+    // Set up the descriptor (resource) and write/copy operations to use.
+    float data[16] = {};
+    VkConstantBufferObj buffer(m_device, sizeof(data), data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+    ASSERT_TRUE(buffer.initialized());
+
+    VkDescriptorBufferInfo info = {};
+    info.buffer = buffer.handle();
+    info.range = VK_WHOLE_SIZE;
+
+    VkWriteDescriptorSet write_descriptor = {};
+    write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    write_descriptor.dstSet = VK_NULL_HANDLE;  // must update this
+    write_descriptor.dstBinding = 0;
+    write_descriptor.descriptorCount = 1;
+    write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    write_descriptor.pBufferInfo = &info;
+
+    VkCopyDescriptorSet copy_descriptor = {};
+    copy_descriptor.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
+    copy_descriptor.srcSet = VK_NULL_HANDLE;  // must update
+    copy_descriptor.srcBinding = 0;
+    copy_descriptor.dstSet = VK_NULL_HANDLE;  // must update
+    copy_descriptor.dstBinding = 0;
+    copy_descriptor.descriptorCount = 1;
+
+    // Create valid and invalid source and destination descriptor sets
+    std::vector<VkDescriptorSetLayoutBinding> one_uniform_buffer = {
+        {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
+    };
+    OneOffDescriptorSet good_dst(m_device, one_uniform_buffer);
+    ASSERT_TRUE(good_dst.Initialized());
+
+    OneOffDescriptorSet bad_dst(m_device, one_uniform_buffer);
+    // Must assert before invalidating it below
+    ASSERT_TRUE(bad_dst.Initialized());
+    bad_dst.layout_ = VkDescriptorSetLayoutObj();
+
+    OneOffDescriptorSet good_src(m_device, one_uniform_buffer);
+    ASSERT_TRUE(good_src.Initialized());
+
+    // Put valid data in the good and bad sources, simultaneously doing a postive test on write and copy operations
+    m_errorMonitor->ExpectSuccess();
+    write_descriptor.dstSet = good_src.set_;
+    vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
+    m_errorMonitor->VerifyNotFound();
+
+    OneOffDescriptorSet bad_src(m_device, one_uniform_buffer);
+    ASSERT_TRUE(bad_src.Initialized());
+
+    // to complete our positive testing use copy, where above we used write.
+    copy_descriptor.srcSet = good_src.set_;
+    copy_descriptor.dstSet = bad_src.set_;
+    vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
+    bad_src.layout_ = VkDescriptorSetLayoutObj();
+    m_errorMonitor->VerifyNotFound();
+
+    // Trigger the three invalid use errors
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kWriteDestroyedLayout);
+    write_descriptor.dstSet = bad_dst.set_;
+    vkUpdateDescriptorSets(m_device->device(), 1, &write_descriptor, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopyDstDestroyedLayout);
+    copy_descriptor.dstSet = bad_dst.set_;
+    vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
+    m_errorMonitor->VerifyFound();
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, kCopySrcDestroyedLayout);
+    copy_descriptor.srcSet = bad_src.set_;
+    copy_descriptor.dstSet = good_dst.set_;
+    vkUpdateDescriptorSets(m_device->device(), 0, nullptr, 1, &copy_descriptor);
+    m_errorMonitor->VerifyFound();
+}
+
 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
     TEST_DESCRIPTION(
         "Call VkQueueSubmit with a semaphore that is already "