Vulkan: Always call the object's destructor before deallocation.

We call the constructor, so make sure we also call the destructor.
Prevents non-POD inner fields from being deallocated without a destructor call before being freed.

Change-Id: Ibf1291619f0ab4c7f7761a80a045d605fa9cbd53
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31813
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/System/Synchronization.hpp b/src/System/Synchronization.hpp
index eb212aa..3d2fc49 100644
--- a/src/System/Synchronization.hpp
+++ b/src/System/Synchronization.hpp
@@ -44,6 +44,9 @@
 	virtual void finish() = 0;
 	// complete() is a helper for calling start() followed by finish().
 	inline void complete() { start(); finish(); }
+
+protected:
+	virtual ~TaskEvents() = default;
 };
 
 // WaitGroup is a synchronization primitive that allows you to wait for
diff --git a/src/Vulkan/VkBuffer.hpp b/src/Vulkan/VkBuffer.hpp
index 46a0017..26520c7 100644
--- a/src/Vulkan/VkBuffer.hpp
+++ b/src/Vulkan/VkBuffer.hpp
@@ -24,7 +24,6 @@
 {
 public:
 	Buffer(const VkBufferCreateInfo* pCreateInfo, void* mem);
-	~Buffer() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkBufferCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkBufferView.hpp b/src/Vulkan/VkBufferView.hpp
index 02e7044..8564274 100644
--- a/src/Vulkan/VkBufferView.hpp
+++ b/src/Vulkan/VkBufferView.hpp
@@ -26,7 +26,6 @@
 {
 public:
 	BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem);
-	~BufferView() = delete;
 
 	static size_t ComputeRequiredAllocationSize(const VkBufferViewCreateInfo* pCreateInfo)
 	{
diff --git a/src/Vulkan/VkCommandPool.hpp b/src/Vulkan/VkCommandPool.hpp
index f50cdae..69479a0 100644
--- a/src/Vulkan/VkCommandPool.hpp
+++ b/src/Vulkan/VkCommandPool.hpp
@@ -25,7 +25,6 @@
 {
 public:
 	CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem);
-	~CommandPool() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkDescriptorPool.hpp b/src/Vulkan/VkDescriptorPool.hpp
index 7462de0..8926467 100644
--- a/src/Vulkan/VkDescriptorPool.hpp
+++ b/src/Vulkan/VkDescriptorPool.hpp
@@ -24,7 +24,6 @@
 	{
 	public:
 		DescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, void* mem);
-		~DescriptorPool() = delete;
 		void destroy(const VkAllocationCallbacks* pAllocator);
 
 		static size_t ComputeRequiredAllocationSize(const VkDescriptorPoolCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index ccf9f9f..a67b261 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -73,7 +73,6 @@
 {
 public:
 	DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo* pCreateInfo, void* mem);
-	~DescriptorSetLayout() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkDescriptorUpdateTemplate.hpp b/src/Vulkan/VkDescriptorUpdateTemplate.hpp
index 16ae9d0..90ea650 100644
--- a/src/Vulkan/VkDescriptorUpdateTemplate.hpp
+++ b/src/Vulkan/VkDescriptorUpdateTemplate.hpp
@@ -25,7 +25,6 @@
 	{

 	public:

 		DescriptorUpdateTemplate(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, void* mem);

-		~DescriptorUpdateTemplate() = delete;

 

 		static size_t ComputeRequiredAllocationSize(const VkDescriptorUpdateTemplateCreateInfo* info);

 

diff --git a/src/Vulkan/VkDestroy.h b/src/Vulkan/VkDestroy.h
index a8367c6..114e2d0 100644
--- a/src/Vulkan/VkDestroy.h
+++ b/src/Vulkan/VkDestroy.h
@@ -37,6 +37,8 @@
 #include "WSI/VkSurfaceKHR.hpp"
 #include "WSI/VkSwapchainKHR.hpp"
 
+#include <type_traits>
+
 namespace vk
 {
 
@@ -45,15 +47,18 @@
 // Unfortunately, since we use a placement new to allocate VkObjectBase derived
 // classes objects, the corresponding deletion operator is a placement delete,
 // which does nothing. In order to properly dispose of these objects' memory,
-// we use this function, which calls the proper T:destroy() function
-// prior to releasing the object (by default, VkObjectBase::destroy does nothing).
+// we use this function, which calls the T:destroy() function then the T
+// destructor prior to releasing the object (by default,
+// VkObjectBase::destroy does nothing).
 template<typename VkT>
 inline void destroy(VkT vkObject, const VkAllocationCallbacks* pAllocator)
 {
 	auto object = Cast(vkObject);
 	if(object)
 	{
+		using T = typename std::remove_pointer<decltype(object)>::type;
 		object->destroy(pAllocator);
+		object->~T();
 		// object may not point to the same pointer as vkObject, for dispatchable objects,
 		// for example, so make sure to deallocate based on the vkObject pointer, which
 		// should always point to the beginning of the allocated memory
diff --git a/src/Vulkan/VkDeviceMemory.hpp b/src/Vulkan/VkDeviceMemory.hpp
index a117a84..88f71cb 100644
--- a/src/Vulkan/VkDeviceMemory.hpp
+++ b/src/Vulkan/VkDeviceMemory.hpp
@@ -24,7 +24,6 @@
 {
 public:
 	DeviceMemory(const VkMemoryAllocateInfo* pCreateInfo, void* mem);
-	~DeviceMemory() = delete;
 
 	static size_t ComputeRequiredAllocationSize(const VkMemoryAllocateInfo* pCreateInfo);
 
diff --git a/src/Vulkan/VkEvent.hpp b/src/Vulkan/VkEvent.hpp
index 34309e6..62eb47a 100644
--- a/src/Vulkan/VkEvent.hpp
+++ b/src/Vulkan/VkEvent.hpp
@@ -29,8 +29,6 @@
 	{
 	}
 
-	~Event() = delete;
-
 	static size_t ComputeRequiredAllocationSize(const VkEventCreateInfo* pCreateInfo)
 	{
 		return 0;
diff --git a/src/Vulkan/VkFence.hpp b/src/Vulkan/VkFence.hpp
index 5fe3e85..7b990ef 100644
--- a/src/Vulkan/VkFence.hpp
+++ b/src/Vulkan/VkFence.hpp
@@ -75,8 +75,6 @@
 
 private:
 	Fence(const Fence&) = delete;
-	~Fence() = delete;
-	Fence& operator = (const Fence&) = delete;
 
 	sw::WaitGroup wg;
 	sw::Event signaled;
diff --git a/src/Vulkan/VkFramebuffer.hpp b/src/Vulkan/VkFramebuffer.hpp
index bc9ea38..9dab4b4 100644
--- a/src/Vulkan/VkFramebuffer.hpp
+++ b/src/Vulkan/VkFramebuffer.hpp
@@ -27,7 +27,6 @@
 {
 public:
 	Framebuffer(const VkFramebufferCreateInfo* pCreateInfo, void* mem);
-	~Framebuffer() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	void clear(const RenderPass* renderPass, uint32_t clearValueCount, const VkClearValue* pClearValues, const VkRect2D& renderArea);
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index b44332e..ac37f1e 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -34,7 +34,6 @@
 	};
 
 	Image(const CreateInfo* pCreateInfo, void* mem);
-	~Image() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const CreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index e741c16..718ebd2 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -34,7 +34,6 @@
 	enum Usage { RAW, SAMPLING };
 
 	ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem);
-	~ImageView() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkObject.hpp b/src/Vulkan/VkObject.hpp
index cefca04..2b6a7ab 100644
--- a/src/Vulkan/VkObject.hpp
+++ b/src/Vulkan/VkObject.hpp
@@ -72,12 +72,6 @@
 
 	void destroy(const VkAllocationCallbacks* pAllocator) {} // Method defined by objects to delete their content, if necessary
 
-	void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
-	{
-		// Should never happen
-		ASSERT(false);
-	}
-
 	template<typename CreateInfo>
 	static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo* pCreateInfo, VkT* outObject)
 	{
@@ -85,10 +79,6 @@
 	}
 
 	static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
-
-protected:
-	// All derived classes should have deleted destructors
-	~ObjectBase() {}
 };
 
 template<typename T, typename VkT>
@@ -115,8 +105,6 @@
 	{
 	}
 
-	~DispatchableObject() = delete;
-
 	void destroy(const VkAllocationCallbacks* pAllocator)
 	{
 		object.destroy(pAllocator);
diff --git a/src/Vulkan/VkPipeline.hpp b/src/Vulkan/VkPipeline.hpp
index 63bbeaa..0a11eb1 100644
--- a/src/Vulkan/VkPipeline.hpp
+++ b/src/Vulkan/VkPipeline.hpp
@@ -34,6 +34,7 @@
 {
 public:
 	Pipeline(PipelineLayout const *layout);
+	virtual ~Pipeline() = default;
 
 	operator VkPipeline()
 	{
@@ -60,7 +61,6 @@
 {
 public:
 	GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem);
-	~GraphicsPipeline() = delete;
 	void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
 
 #ifndef NDEBUG
@@ -98,7 +98,6 @@
 {
 public:
 	ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem);
-	~ComputePipeline() = delete;
 	void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
 
 #ifndef NDEBUG
diff --git a/src/Vulkan/VkPipelineCache.hpp b/src/Vulkan/VkPipelineCache.hpp
index ab5e2b2..c75510b 100644
--- a/src/Vulkan/VkPipelineCache.hpp
+++ b/src/Vulkan/VkPipelineCache.hpp
@@ -24,7 +24,6 @@
 {
 public:
 	PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem);
-	~PipelineCache() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkPipelineLayout.hpp b/src/Vulkan/VkPipelineLayout.hpp
index ebd9295..ef1f9a4 100644
--- a/src/Vulkan/VkPipelineLayout.hpp
+++ b/src/Vulkan/VkPipelineLayout.hpp
@@ -24,7 +24,6 @@
 {
 public:
 	PipelineLayout(const VkPipelineLayoutCreateInfo* pCreateInfo, void* mem);
-	~PipelineLayout() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkQueryPool.hpp b/src/Vulkan/VkQueryPool.hpp
index ec2ba71..d85bf85 100644
--- a/src/Vulkan/VkQueryPool.hpp
+++ b/src/Vulkan/VkQueryPool.hpp
@@ -18,7 +18,7 @@
 #include "VkObject.hpp"
 #include <atomic>
 #include <condition_variable>
-#include <mutex>

+#include <mutex>
 
 namespace vk
 {
@@ -32,7 +32,7 @@
 		FINISHED
 	};
 
-	std::mutex mutex;

+	std::mutex mutex;
 	std::condition_variable condition;
 	State state;  // guarded by mutex
 	int64_t data; // guarded by mutex
@@ -44,7 +44,6 @@
 {
 public:
 	QueryPool(const VkQueryPoolCreateInfo* pCreateInfo, void* mem);
-	~QueryPool() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkQueryPoolCreateInfo* pCreateInfo);
@@ -54,7 +53,7 @@
 	void begin(uint32_t query, VkQueryControlFlags flags);
 	void end(uint32_t query);
 	void reset(uint32_t firstQuery, uint32_t queryCount);
-	
+
 	void writeTimestamp(uint32_t query);
 
 	inline Query* getQuery(uint32_t query) const { return &(pool[query]); }
diff --git a/src/Vulkan/VkRenderPass.hpp b/src/Vulkan/VkRenderPass.hpp
index b70ec8d..b111066 100644
--- a/src/Vulkan/VkRenderPass.hpp
+++ b/src/Vulkan/VkRenderPass.hpp
@@ -26,7 +26,6 @@
 {
 public:
 	RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem);
-	~RenderPass() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo);
diff --git a/src/Vulkan/VkSampler.hpp b/src/Vulkan/VkSampler.hpp
index bdf7b49..97a7190 100644
--- a/src/Vulkan/VkSampler.hpp
+++ b/src/Vulkan/VkSampler.hpp
@@ -46,8 +46,6 @@
 	{
 	}
 
-	~Sampler() = delete;
-
 	static size_t ComputeRequiredAllocationSize(const VkSamplerCreateInfo* pCreateInfo)
 	{
 		return 0;
diff --git a/src/Vulkan/VkSemaphore.hpp b/src/Vulkan/VkSemaphore.hpp
index 91597de..5ebad95 100644
--- a/src/Vulkan/VkSemaphore.hpp
+++ b/src/Vulkan/VkSemaphore.hpp
@@ -25,8 +25,6 @@
 public:
 	Semaphore(const VkSemaphoreCreateInfo* pCreateInfo, void* mem) {}
 
-	~Semaphore() = delete;
-
 	static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo* pCreateInfo)
 	{
 		return 0;
diff --git a/src/Vulkan/VkShaderModule.hpp b/src/Vulkan/VkShaderModule.hpp
index 3d9c4cc..18b9a60 100644
--- a/src/Vulkan/VkShaderModule.hpp
+++ b/src/Vulkan/VkShaderModule.hpp
@@ -30,7 +30,6 @@
 {
 public:
 	ShaderModule(const VkShaderModuleCreateInfo* pCreateInfo, void* mem);
-	~ShaderModule() = delete;
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
 	static size_t ComputeRequiredAllocationSize(const VkShaderModuleCreateInfo* pCreateInfo);
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index 23a8ee0..616cbcc 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -40,6 +40,8 @@
 class SurfaceKHR
 {
 public:
+	virtual ~SurfaceKHR() = default;
+
 	operator VkSurfaceKHR()
 	{
 		return reinterpret_cast<VkSurfaceKHR::HandleType>(this);
diff --git a/src/WSI/VkSwapchainKHR.hpp b/src/WSI/VkSwapchainKHR.hpp
index 8ba649c..c5b0166 100644
--- a/src/WSI/VkSwapchainKHR.hpp
+++ b/src/WSI/VkSwapchainKHR.hpp
@@ -29,7 +29,6 @@
 {
 public:
 	SwapchainKHR(const VkSwapchainCreateInfoKHR* pCreateInfo, void* mem);
-	~SwapchainKHR() = delete;
 
 	void destroy(const VkAllocationCallbacks* pAllocator);
 
diff --git a/src/WSI/XlibSurfaceKHR.hpp b/src/WSI/XlibSurfaceKHR.hpp
index 10be5ab..dd07ea2 100644
--- a/src/WSI/XlibSurfaceKHR.hpp
+++ b/src/WSI/XlibSurfaceKHR.hpp
@@ -29,8 +29,6 @@
 public:
 	XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem);
 
-	~XlibSurfaceKHR() = delete;
-
 	void destroySurface(const VkAllocationCallbacks *pAllocator) override;
 
 	static size_t ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo);