tests: Add validation test for failing memory aliasing bug
Change-Id: I42c2b61fa7c722ef23d80b320d2c306f769af079
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index a3cc0a9..cbcc071 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -612,6 +612,126 @@
}
#endif
+// This is a positive test. No failures are expected.
+TEST_F(VkLayerTest, TestAliasedMemoryTracking) {
+ VkResult err;
+ bool pass;
+
+ TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
+ "the buffer, create an image, and bind the same memory to "
+ "it");
+
+ m_errorMonitor->ExpectSuccess();
+
+ ASSERT_NO_FATAL_FAILURE(InitState());
+
+ VkBuffer buffer;
+ VkImage image;
+ VkDeviceMemory mem;
+ VkMemoryRequirements mem_reqs;
+
+ VkBufferCreateInfo buf_info = {};
+ buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ buf_info.pNext = NULL;
+ buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ buf_info.size = 256;
+ buf_info.queueFamilyIndexCount = 0;
+ buf_info.pQueueFamilyIndices = NULL;
+ buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ buf_info.flags = 0;
+ err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
+ ASSERT_VK_SUCCESS(err);
+
+ vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+
+ VkMemoryAllocateInfo alloc_info = {};
+ alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ alloc_info.pNext = NULL;
+ alloc_info.memoryTypeIndex = 0;
+
+ // Ensure memory is big enough for both bindings
+ alloc_info.allocationSize = 0x10000;
+
+ pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+ if (!pass) {
+ vkDestroyBuffer(m_device->device(), buffer, NULL);
+ return;
+ }
+
+ err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
+ ASSERT_VK_SUCCESS(err);
+
+ uint8_t *pData;
+ err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0,
+ (void **)&pData);
+ ASSERT_VK_SUCCESS(err);
+
+ memset(pData, 0xCADECADE, mem_reqs.size);
+
+ vkUnmapMemory(m_device->device(), mem);
+
+ err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+ ASSERT_VK_SUCCESS(err);
+
+ // NOW, destroy the buffer. Obviously, the resource no longer occupies this
+ // memory. In fact, it was never used by the GPU.
+ // Just be be sure, wait for idle.
+ vkDestroyBuffer(m_device->device(), buffer, NULL);
+ vkDeviceWaitIdle(m_device->device());
+
+ VkImageCreateInfo image_create_info = {};
+ image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ image_create_info.pNext = NULL;
+ image_create_info.imageType = VK_IMAGE_TYPE_2D;
+ image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
+ image_create_info.extent.width = 64;
+ image_create_info.extent.height = 64;
+ image_create_info.extent.depth = 1;
+ image_create_info.mipLevels = 1;
+ image_create_info.arrayLayers = 1;
+ image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+ image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+ image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+ image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ image_create_info.queueFamilyIndexCount = 0;
+ image_create_info.pQueueFamilyIndices = NULL;
+ image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ image_create_info.flags = 0;
+
+ VkMemoryAllocateInfo mem_alloc = {};
+ mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ mem_alloc.pNext = NULL;
+ mem_alloc.allocationSize = 0;
+ mem_alloc.memoryTypeIndex = 0;
+
+ /* Create a mappable image. It will be the texture if linear images are ok
+ * to be textures or it will be the staging image if they are not.
+ */
+ err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+ ASSERT_VK_SUCCESS(err);
+
+ vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+
+ mem_alloc.allocationSize = mem_reqs.size;
+
+ pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+ if (!pass) {
+ vkDestroyImage(m_device->device(), image, NULL);
+ return;
+ }
+
+ // VALDIATION FAILURE:
+ err = vkBindImageMemory(m_device->device(), image, mem, 0);
+ ASSERT_VK_SUCCESS(err);
+
+ m_errorMonitor->VerifyNotFound();
+
+ vkDestroyBuffer(m_device->device(), buffer, NULL);
+ vkDestroyImage(m_device->device(), image, NULL);
+}
+
TEST_F(VkLayerTest, EnableWsiBeforeUse) {
VkResult err;
bool pass;