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);