VulkanBenchmarks: improve and clarify resource ownership

* Identify members that are owning handles with a comment
* Reorder these members in creation order
* Reorder explicit destruction of these members in reverse order in destructors
* Replace raw pointers with unique_ptrs, but call reset explicitly in destructors to maintain reverse destruction order
* Define VULKAN_HPP_NO_NODISCARD_WARNINGS to future-proof for C++17 and up
* Remove vestigial vk::UniqueShaderModule and vk::UniquePipeline usage

Bug: b/176981107
Change-Id: Ia090be98c2f8ed47701dfc92388547985e5c57b4
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51829
Tested-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/tests/VulkanBenchmarks/VulkanBenchmarks.cpp b/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
index af107d9..2f566ce 100644
--- a/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
+++ b/tests/VulkanBenchmarks/VulkanBenchmarks.cpp
@@ -28,6 +28,7 @@
 #	define VK_USE_PLATFORM_WIN32_KHR
 #endif
 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
+#define VULKAN_HPP_NO_NODISCARD_WARNINGS
 #include <vulkan/vulkan.hpp>
 VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
 
@@ -211,16 +212,16 @@
 		instance.destroy(nullptr);
 	}
 
+private:
+	std::unique_ptr<vk::DynamicLoader> dl;
+
 protected:
 	const uint32_t queueFamilyIndex = 0;
 
-	vk::Instance instance;
+	vk::Instance instance;  // Owning handle
 	vk::PhysicalDevice physicalDevice;
-	vk::Device device;
+	vk::Device device;  // Owning handle
 	vk::Queue queue;
-
-private:
-	std::unique_ptr<vk::DynamicLoader> dl;
 };
 
 class ClearImageBenchmark : public VulkanBenchmark
@@ -317,11 +318,10 @@
 	}
 
 private:
-	vk::CommandPool commandPool;
-	vk::CommandBuffer commandBuffer;
-
-	vk::Image image;
-	vk::DeviceMemory memory;
+	vk::Image image;                  // Owning handle
+	vk::DeviceMemory memory;          // Owning handle
+	vk::CommandPool commandPool;      // Owning handle
+	vk::CommandBuffer commandBuffer;  // Owning handle
 };
 
 static void ClearImage(benchmark::State &state, vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect)
@@ -449,10 +449,10 @@
 class Swapchain
 {
 public:
-	Swapchain(vk::PhysicalDevice physicalDevice, vk::Device device, Window *window)
+	Swapchain(vk::PhysicalDevice physicalDevice, vk::Device device, Window &window)
 	    : device(device)
 	{
-		vk::SurfaceKHR surface = window->getSurface();
+		vk::SurfaceKHR surface = window.getSurface();
 
 		// Create the swapchain
 		vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface);
@@ -542,11 +542,11 @@
 private:
 	const vk::Device device;
 
-	vk::SwapchainKHR swapchain;
+	vk::SwapchainKHR swapchain;  // Owning handle
 	vk::Extent2D extent;
 
-	std::vector<vk::Image> images;  // Weak pointers. Presentable images owned by swapchain object.
-	std::vector<vk::ImageView> imageViews;
+	std::vector<vk::Image> images;          // Weak pointers. Presentable images owned by swapchain object.
+	std::vector<vk::ImageView> imageViews;  // Owning handles
 };
 
 class Buffer
@@ -597,8 +597,8 @@
 private:
 	const vk::Device device;
 	vk::DeviceSize size;
-	vk::Buffer buffer;
-	vk::DeviceMemory bufferMemory;
+	vk::Buffer buffer;              // Owning handle
+	vk::DeviceMemory bufferMemory;  // Owning handle
 };
 
 class Image
@@ -645,9 +645,9 @@
 
 	~Image()
 	{
-		device.destroyImage(image);
 		device.destroyImageView(imageView);
 		device.freeMemory(imageMemory);
+		device.destroyImage(image);
 	}
 
 	vk::Image getImage()
@@ -663,9 +663,9 @@
 private:
 	const vk::Device device;
 
-	vk::Image image;
-	vk::DeviceMemory imageMemory;
-	vk::ImageView imageView;
+	vk::Image image;               // Owning handle
+	vk::DeviceMemory imageMemory;  // Owning handle
+	vk::ImageView imageView;       // Owning handle
 };
 
 class Framebuffer
@@ -678,7 +678,7 @@
 
 		if(multisample)
 		{
-			multisampleImage = new Image(device, extent.width, extent.height, colorFormat, vk::SampleCountFlagBits::e4);
+			multisampleImage.reset(new Image(device, extent.width, extent.height, colorFormat, vk::SampleCountFlagBits::e4));
 
 			// We'll be rendering to attachment location 0
 			attachments[0] = multisampleImage->getImageView();
@@ -703,9 +703,8 @@
 
 	~Framebuffer()
 	{
+		multisampleImage.reset();
 		device.destroyFramebuffer(framebuffer);
-
-		delete multisampleImage;
 	}
 
 	vk::Framebuffer getFramebuffer()
@@ -715,10 +714,8 @@
 
 private:
 	const vk::Device device;
-
-	vk::Framebuffer framebuffer;
-
-	Image *multisampleImage = nullptr;
+	vk::Framebuffer framebuffer;  // Owning handle
+	std::unique_ptr<Image> multisampleImage;
 };
 
 static std::vector<uint32_t> compileGLSLtoSPIRV(const char *glslSource, EShLanguage glslLanguage)
@@ -764,8 +761,8 @@
 	TriangleBenchmark(bool multisample)
 	    : multisample(multisample)
 	{
-		window = new Window(instance, windowSize);
-		swapchain = new Swapchain(physicalDevice, device, window);
+		window.reset(new Window(instance, windowSize));
+		swapchain.reset(new Swapchain(physicalDevice, device, *window));
 
 		renderPass = createRenderPass(swapchain->colorFormat);
 		createFramebuffers(renderPass);
@@ -781,39 +778,37 @@
 
 	~TriangleBenchmark()
 	{
-		delete texture;
+		device.freeCommandBuffers(commandPool, commandBuffers);
 
-		device.destroyDescriptorSetLayout(descriptorSetLayout);
 		device.destroyDescriptorPool(descriptorPool);
-
 		device.destroySampler(sampler, nullptr);
-
-		device.destroyPipelineLayout(pipelineLayout, nullptr);
-		device.destroyPipelineCache(pipelineCache, nullptr);
-
-		device.destroyBuffer(vertices.buffer, nullptr);
-		device.freeMemory(vertices.memory, nullptr);
-
-		device.destroySemaphore(presentCompleteSemaphore, nullptr);
-		device.destroySemaphore(renderCompleteSemaphore, nullptr);
+		texture.reset();
+		device.destroyCommandPool(commandPool, nullptr);
 
 		for(auto &fence : waitFences)
 		{
 			device.destroyFence(fence, nullptr);
 		}
 
-		for(auto *framebuffer : framebuffers)
+		device.destroySemaphore(renderCompleteSemaphore, nullptr);
+		device.destroySemaphore(presentCompleteSemaphore, nullptr);
+
+		device.destroyPipeline(pipeline);
+		device.destroyPipelineLayout(pipelineLayout, nullptr);
+		device.destroyDescriptorSetLayout(descriptorSetLayout);
+
+		device.freeMemory(vertices.memory, nullptr);
+		device.destroyBuffer(vertices.buffer, nullptr);
+
+		for(auto &framebuffer : framebuffers)
 		{
-			delete framebuffer;
+			framebuffer.reset();
 		}
 
 		device.destroyRenderPass(renderPass, nullptr);
 
-		device.freeCommandBuffers(commandPool, commandBuffers);
-		device.destroyCommandPool(commandPool, nullptr);
-
-		delete swapchain;
-		delete window;
+		swapchain.reset();
+		window.reset();
 	}
 
 	void renderFrame()
@@ -867,7 +862,7 @@
 		commandPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
 		commandPool = device.createCommandPool(commandPoolCreateInfo);
 
-		texture = new Image(device, 16, 16, vk::Format::eR8G8B8A8Unorm);
+		texture.reset(new Image(device, 16, 16, vk::Format::eR8G8B8A8Unorm));
 
 		// Fill texture with white
 		vk::DeviceSize bufferSize = 16 * 16 * 4;
@@ -965,7 +960,7 @@
 			commandBuffers[i].bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, 1, &descriptorSets[0], 0, nullptr);
 
 			// Draw a triangle
-			commandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.get());
+			commandBuffers[i].bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
 			VULKAN_HPP_NAMESPACE::DeviceSize offset = 0;
 			commandBuffers[i].bindVertexBuffers(0, 1, &vertices.buffer, &offset);
 			commandBuffers[i].draw(3, 1, 0, 0);
@@ -1026,7 +1021,7 @@
 
 		for(size_t i = 0; i < framebuffers.size(); i++)
 		{
-			framebuffers[i] = new Framebuffer(device, swapchain->getImageView(i), swapchain->colorFormat, renderPass, swapchain->getExtent(), multisample);
+			framebuffers[i].reset(new Framebuffer(device, swapchain->getImageView(i), swapchain->colorFormat, renderPass, swapchain->getExtent(), multisample));
 		}
 	}
 
@@ -1111,7 +1106,7 @@
 		return device.createRenderPass(renderPassInfo);
 	}
 
-	vk::UniqueShaderModule createShaderModule(const char *glslSource, EShLanguage glslLanguage)
+	vk::ShaderModule createShaderModule(const char *glslSource, EShLanguage glslLanguage)
 	{
 		auto spirv = compileGLSLtoSPIRV(glslSource, glslLanguage);
 
@@ -1119,10 +1114,10 @@
 		moduleCreateInfo.codeSize = spirv.size() * sizeof(uint32_t);
 		moduleCreateInfo.pCode = (uint32_t *)spirv.data();
 
-		return device.createShaderModuleUnique(moduleCreateInfo);
+		return device.createShaderModule(moduleCreateInfo);
 	}
 
-	vk::UniquePipeline createGraphicsPipeline(vk::RenderPass renderPass)
+	vk::Pipeline createGraphicsPipeline(vk::RenderPass renderPass)
 	{
 		vk::DescriptorSetLayoutBinding samplerLayoutBinding;
 		samplerLayoutBinding.binding = 1;
@@ -1225,16 +1220,16 @@
 			}
 		)";
 
-		vk::UniqueShaderModule vertexModule = createShaderModule(vertexShader, EShLanguage::EShLangVertex);
-		vk::UniqueShaderModule fragmentModule = createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
+		vk::ShaderModule vertexModule = createShaderModule(vertexShader, EShLanguage::EShLangVertex);
+		vk::ShaderModule fragmentModule = createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
 
 		std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages;
 
-		shaderStages[0].module = vertexModule.get();
+		shaderStages[0].module = vertexModule;
 		shaderStages[0].stage = vk::ShaderStageFlagBits::eVertex;
 		shaderStages[0].pName = "main";
 
-		shaderStages[1].module = fragmentModule.get();
+		shaderStages[1].module = fragmentModule;
 		shaderStages[1].stage = vk::ShaderStageFlagBits::eFragment;
 		shaderStages[1].pName = "main";
 
@@ -1250,46 +1245,47 @@
 		pipelineCreateInfo.renderPass = renderPass;
 		pipelineCreateInfo.pDynamicState = &dynamicState;
 
-		return device.createGraphicsPipelineUnique(nullptr, pipelineCreateInfo).value;
+		auto pipeline = device.createGraphicsPipeline(nullptr, pipelineCreateInfo).value;
+
+		device.destroyShaderModule(fragmentModule);
+		device.destroyShaderModule(vertexModule);
+
+		return pipeline;
 	}
 
 	const vk::Extent2D windowSize = { 1280, 720 };
 	const bool multisample;
-	Window *window = nullptr;
 
-	Swapchain *swapchain = nullptr;
+	std::unique_ptr<Window> window;
+	std::unique_ptr<Swapchain> swapchain;
 
-	vk::RenderPass renderPass;
-	std::vector<Framebuffer *> framebuffers;
+	vk::RenderPass renderPass;  // Owning handle
+	std::vector<std::unique_ptr<Framebuffer>> framebuffers;
 	uint32_t currentFrameBuffer = 0;
 
 	struct VertexBuffer
 	{
-		vk::Buffer buffer;
-		vk::DeviceMemory memory;
+		vk::Buffer buffer;        // Owning handle
+		vk::DeviceMemory memory;  // Owning handle
 
-		vk::PipelineVertexInputStateCreateInfo inputState;
 		vk::VertexInputBindingDescription inputBinding;
 		std::vector<vk::VertexInputAttributeDescription> inputAttributes;
+		vk::PipelineVertexInputStateCreateInfo inputState;
 	} vertices;
 
-	vk::DescriptorPool descriptorPool;
-	vk::DescriptorSetLayout descriptorSetLayout;
-	vk::PipelineLayout pipelineLayout;
-	vk::PipelineCache pipelineCache;
-	vk::UniquePipeline pipeline;
+	vk::DescriptorSetLayout descriptorSetLayout;  // Owning handle
+	vk::PipelineLayout pipelineLayout;            // Owning handle
+	vk::Pipeline pipeline;                        // Owning handle
 
-	vk::Sampler sampler;
+	vk::Semaphore presentCompleteSemaphore;  // Owning handle
+	vk::Semaphore renderCompleteSemaphore;   // Owning handle
+	std::vector<vk::Fence> waitFences;       // Owning handles
 
-	vk::CommandPool commandPool;
-	std::vector<vk::CommandBuffer> commandBuffers;
-
-	vk::Semaphore presentCompleteSemaphore;
-	vk::Semaphore renderCompleteSemaphore;
-
-	std::vector<vk::Fence> waitFences;
-
-	Image *texture = nullptr;
+	vk::CommandPool commandPool;  // Owning handle
+	std::unique_ptr<Image> texture;
+	vk::Sampler sampler;                            // Owning handle
+	vk::DescriptorPool descriptorPool;              // Owning handle
+	std::vector<vk::CommandBuffer> commandBuffers;  // Owning handles
 };
 
 static void Triangle(benchmark::State &state, bool multisample)