VulkanUnitTests: Call vkDestroyDevice()

The system vulkan driver can get sulky if you don't free memory.

Bug: b/123749916
Change-Id: I9bf2de63a788200c401b41fa3efdfb36f3c15245
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27772
Presubmit-Ready: Ben Clayton <headlessclayton@gmail.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/tests/VulkanUnitTests/Device.cpp b/tests/VulkanUnitTests/Device.cpp
index fd2ad95..098e736 100644
--- a/tests/VulkanUnitTests/Device.cpp
+++ b/tests/VulkanUnitTests/Device.cpp
@@ -29,10 +29,19 @@
 	  physicalDevice(physicalDevice),
 	  queueFamilyIndex(queueFamilyIndex) {}
 
+Device::~Device()
+{
+	if (device != nullptr)
+	{
+		driver->vkDeviceWaitIdle(device);
+		driver->vkDestroyDevice(device, nullptr);
+	}
+}
+
 bool Device::IsValid() const { return device != nullptr; }
 
 VkResult Device::CreateComputeDevice(
-		Driver const *driver, VkInstance instance, Device *out)
+		Driver const *driver, VkInstance instance, std::unique_ptr<Device> &out)
 {
     VkResult result;
 
@@ -77,13 +86,13 @@
         };
 
         VkDevice device;
-        result = driver->vkCreateDevice(physicalDevice, &deviceCreateInfo, 0, &device);
+        result = driver->vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
         if (result != VK_SUCCESS)
         {
             return result;
         }
 
-		*out = Device(driver, device, physicalDevice, static_cast<uint32_t>(queueFamilyIndex));
+		out.reset(new Device(driver, device, physicalDevice, static_cast<uint32_t>(queueFamilyIndex)));
         return VK_SUCCESS;
     }
 
diff --git a/tests/VulkanUnitTests/Device.hpp b/tests/VulkanUnitTests/Device.hpp
index f38ce9f..37b9108 100644
--- a/tests/VulkanUnitTests/Device.hpp
+++ b/tests/VulkanUnitTests/Device.hpp
@@ -14,6 +14,7 @@
 
 #include <vulkan/vulkan_core.h>
 
+#include <memory>
 #include <vector>
 
 class Driver;
@@ -24,6 +25,7 @@
 {
 public:
 	Device();
+	~Device();
 
 	// CreateComputeDevice enumerates the physical devices, looking for a device
 	// that supports compute.
@@ -33,7 +35,7 @@
 	// returned (as there was no Vulkan error), but calling Device::IsValid()
 	// on this device will return false.
 	static VkResult CreateComputeDevice(
-			Driver const *driver, VkInstance instance, Device *out);
+			Driver const *driver, VkInstance instance, std::unique_ptr<Device>& out);
 
 	// IsValid returns true if the Device is initialized and can be used.
 	bool IsValid() const;
diff --git a/tests/VulkanUnitTests/VkInstanceFuncs.hpp b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
index 5efb525..2dc357c 100644
--- a/tests/VulkanUnitTests/VkInstanceFuncs.hpp
+++ b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
@@ -42,6 +42,7 @@
             VkPipelineLayout*);
 VK_INSTANCE(vkCreateShaderModule, VkResult, VkDevice, const VkShaderModuleCreateInfo*, const VkAllocationCallbacks*,
             VkShaderModule*);
+VK_INSTANCE(vkDestroyDevice, VkResult, VkDevice, const VkAllocationCallbacks*)
 VK_INSTANCE(vkEndCommandBuffer, VkResult, VkCommandBuffer);
 VK_INSTANCE(vkEnumeratePhysicalDevices, VkResult, VkInstance, uint32_t*, VkPhysicalDevice*)
 VK_INSTANCE(vkGetDeviceQueue, void, VkDevice, uint32_t, uint32_t, VkQueue*);
@@ -49,8 +50,9 @@
 VK_INSTANCE(vkGetPhysicalDeviceProperties, void, VkPhysicalDevice, VkPhysicalDeviceProperties*)
 VK_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties, void, VkPhysicalDevice, uint32_t*, VkQueueFamilyProperties*);
 VK_INSTANCE(vkMapMemory, VkResult, VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void**);
+VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo*, VkFence);
+VK_INSTANCE(vkQueueWaitIdle, VkResult, VkQueue);
 VK_INSTANCE(vkUnmapMemory, void, VkDevice, VkDeviceMemory);
 VK_INSTANCE(vkUpdateDescriptorSets, void, VkDevice, uint32_t, const VkWriteDescriptorSet*, uint32_t,
             const VkCopyDescriptorSet*);
-VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo*, VkFence);
-VK_INSTANCE(vkQueueWaitIdle, VkResult, VkQueue);
\ No newline at end of file
+VK_INSTANCE(vkDeviceWaitIdle, VkResult, VkDevice);
\ No newline at end of file
diff --git a/tests/VulkanUnitTests/unittests.cpp b/tests/VulkanUnitTests/unittests.cpp
index fb1e0d1..e89b435 100644
--- a/tests/VulkanUnitTests/unittests.cpp
+++ b/tests/VulkanUnitTests/unittests.cpp
@@ -200,9 +200,9 @@
 

     ASSERT_TRUE(driver.resolve(instance));

 

-    Device device;

-    VK_ASSERT(Device::CreateComputeDevice(&driver, instance, &device));

-    ASSERT_TRUE(device.IsValid());

+    std::unique_ptr<Device> device;

+    VK_ASSERT(Device::CreateComputeDevice(&driver, instance, device));

+    ASSERT_TRUE(device->IsValid());

 

     // struct Buffers

     // {

@@ -225,12 +225,12 @@
     size_t buffersSize = sizeof(uint32_t) * buffersTotalElements;

 

     VkDeviceMemory memory;

-    VK_ASSERT(device.AllocateMemory(buffersSize,

+    VK_ASSERT(device->AllocateMemory(buffersSize,

             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,

             &memory));

 

     uint32_t* buffers;

-    VK_ASSERT(device.MapMemory(memory, 0, buffersSize, 0, (void**)&buffers));

+    VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void**)&buffers));

 

     buffers[magic0Offset] = magic0;

     buffers[magic1Offset] = magic1;

@@ -241,23 +241,23 @@
         buffers[inOffset + i] = input(i);

     }

 

-    device.UnmapMemory(memory);

+    device->UnmapMemory(memory);

     buffers = nullptr;

 

     VkBuffer bufferIn;

-    VK_ASSERT(device.CreateStorageBuffer(memory,

+    VK_ASSERT(device->CreateStorageBuffer(memory,

             sizeof(uint32_t) * numElements,

             sizeof(uint32_t) * inOffset,

             &bufferIn));

 

     VkBuffer bufferOut;

-    VK_ASSERT(device.CreateStorageBuffer(memory,

+    VK_ASSERT(device->CreateStorageBuffer(memory,

             sizeof(uint32_t) * numElements,

             sizeof(uint32_t) * outOffset,

             &bufferOut));

 

     VkShaderModule shaderModule;

-    VK_ASSERT(device.CreateShaderModule(code, &shaderModule));

+    VK_ASSERT(device->CreateShaderModule(code, &shaderModule));

 

     std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings =

     {

@@ -278,19 +278,19 @@
     };

 

     VkDescriptorSetLayout descriptorSetLayout;

-    VK_ASSERT(device.CreateDescriptorSetLayout(descriptorSetLayoutBindings, &descriptorSetLayout));

+    VK_ASSERT(device->CreateDescriptorSetLayout(descriptorSetLayoutBindings, &descriptorSetLayout));

 

     VkPipelineLayout pipelineLayout;

-    VK_ASSERT(device.CreatePipelineLayout(descriptorSetLayout, &pipelineLayout));

+    VK_ASSERT(device->CreatePipelineLayout(descriptorSetLayout, &pipelineLayout));

 

     VkPipeline pipeline;

-    VK_ASSERT(device.CreateComputePipeline(shaderModule, pipelineLayout, &pipeline));

+    VK_ASSERT(device->CreateComputePipeline(shaderModule, pipelineLayout, &pipeline));

 

     VkDescriptorPool descriptorPool;

-    VK_ASSERT(device.CreateStorageBufferDescriptorPool(2, &descriptorPool));

+    VK_ASSERT(device->CreateStorageBufferDescriptorPool(2, &descriptorPool));

 

     VkDescriptorSet descriptorSet;

-    VK_ASSERT(device.AllocateDescriptorSet(descriptorPool, descriptorSetLayout, &descriptorSet));

+    VK_ASSERT(device->AllocateDescriptorSet(descriptorPool, descriptorSetLayout, &descriptorSet));

 

     std::vector<VkDescriptorBufferInfo> descriptorBufferInfos =

     {

@@ -305,15 +305,15 @@
             VK_WHOLE_SIZE,  // range

         }

     };

-    device.UpdateStorageBufferDescriptorSets(descriptorSet, descriptorBufferInfos);

+    device->UpdateStorageBufferDescriptorSets(descriptorSet, descriptorBufferInfos);

 

     VkCommandPool commandPool;

-    VK_ASSERT(device.CreateCommandPool(&commandPool));

+    VK_ASSERT(device->CreateCommandPool(&commandPool));

 

     VkCommandBuffer commandBuffer;

-    VK_ASSERT(device.AllocateCommandBuffer(commandPool, &commandBuffer));

+    VK_ASSERT(device->AllocateCommandBuffer(commandPool, &commandBuffer));

 

-    VK_ASSERT(device.BeginCommandBuffer(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, commandBuffer));

+    VK_ASSERT(device->BeginCommandBuffer(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, commandBuffer));

 

     driver.vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);

 

@@ -324,9 +324,9 @@
 

     VK_ASSERT(driver.vkEndCommandBuffer(commandBuffer));

 

-    VK_ASSERT(device.QueueSubmitAndWait(commandBuffer));

+    VK_ASSERT(device->QueueSubmitAndWait(commandBuffer));

 

-    VK_ASSERT(device.MapMemory(memory, 0, buffersSize, 0, (void**)&buffers));

+    VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void**)&buffers));

 

     for (size_t i = 0; i < numElements; ++i)

     {

@@ -339,7 +339,7 @@
     EXPECT_EQ(buffers[magic1Offset], magic1);

     EXPECT_EQ(buffers[magic2Offset], magic2);

 

-    device.UnmapMemory(memory);

+    device->UnmapMemory(memory);

     buffers = nullptr;

 }