Commit caf60317 by Ben Clayton

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/+/31813Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent b7814894
......@@ -44,6 +44,9 @@ public:
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
......
......@@ -24,7 +24,6 @@ class Buffer : public Object<Buffer, VkBuffer>
{
public:
Buffer(const VkBufferCreateInfo* pCreateInfo, void* mem);
~Buffer() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkBufferCreateInfo* pCreateInfo);
......
......@@ -26,7 +26,6 @@ class BufferView : public Object<BufferView, VkBufferView>
{
public:
BufferView(const VkBufferViewCreateInfo* pCreateInfo, void* mem);
~BufferView() = delete;
static size_t ComputeRequiredAllocationSize(const VkBufferViewCreateInfo* pCreateInfo)
{
......
......@@ -25,7 +25,6 @@ class CommandPool : public Object<CommandPool, VkCommandPool>
{
public:
CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem);
~CommandPool() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo);
......
......@@ -24,7 +24,6 @@ namespace vk
{
public:
DescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, void* mem);
~DescriptorPool() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkDescriptorPoolCreateInfo* pCreateInfo);
......
......@@ -73,7 +73,6 @@ class DescriptorSetLayout : public Object<DescriptorSetLayout, VkDescriptorSetLa
{
public:
DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo* pCreateInfo, void* mem);
~DescriptorSetLayout() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
......
......@@ -25,7 +25,6 @@ namespace vk
{
public:
DescriptorUpdateTemplate(const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, void* mem);
~DescriptorUpdateTemplate() = delete;
static size_t ComputeRequiredAllocationSize(const VkDescriptorUpdateTemplateCreateInfo* info);
......
......@@ -37,6 +37,8 @@
#include "WSI/VkSurfaceKHR.hpp"
#include "WSI/VkSwapchainKHR.hpp"
#include <type_traits>
namespace vk
{
......@@ -45,15 +47,18 @@ namespace vk
// 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
......
......@@ -24,7 +24,6 @@ class DeviceMemory : public Object<DeviceMemory, VkDeviceMemory>
{
public:
DeviceMemory(const VkMemoryAllocateInfo* pCreateInfo, void* mem);
~DeviceMemory() = delete;
static size_t ComputeRequiredAllocationSize(const VkMemoryAllocateInfo* pCreateInfo);
......
......@@ -29,8 +29,6 @@ public:
{
}
~Event() = delete;
static size_t ComputeRequiredAllocationSize(const VkEventCreateInfo* pCreateInfo)
{
return 0;
......
......@@ -75,8 +75,6 @@ public:
private:
Fence(const Fence&) = delete;
~Fence() = delete;
Fence& operator = (const Fence&) = delete;
sw::WaitGroup wg;
sw::Event signaled;
......
......@@ -27,7 +27,6 @@ class Framebuffer : public Object<Framebuffer, VkFramebuffer>
{
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);
......
......@@ -34,7 +34,6 @@ public:
};
Image(const CreateInfo* pCreateInfo, void* mem);
~Image() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const CreateInfo* pCreateInfo);
......
......@@ -34,7 +34,6 @@ public:
enum Usage { RAW, SAMPLING };
ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem);
~ImageView() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
......
......@@ -72,12 +72,6 @@ public:
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 @@ public:
}
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 @@ public:
{
}
~DispatchableObject() = delete;
void destroy(const VkAllocationCallbacks* pAllocator)
{
object.destroy(pAllocator);
......
......@@ -34,6 +34,7 @@ class Pipeline
{
public:
Pipeline(PipelineLayout const *layout);
virtual ~Pipeline() = default;
operator VkPipeline()
{
......@@ -60,7 +61,6 @@ class GraphicsPipeline : public Pipeline, public ObjectBase<GraphicsPipeline, Vk
{
public:
GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem);
~GraphicsPipeline() = delete;
void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
#ifndef NDEBUG
......@@ -98,7 +98,6 @@ class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPi
{
public:
ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem);
~ComputePipeline() = delete;
void destroyPipeline(const VkAllocationCallbacks* pAllocator) override;
#ifndef NDEBUG
......
......@@ -24,7 +24,6 @@ class PipelineCache : public Object<PipelineCache, VkPipelineCache>
{
public:
PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem);
~PipelineCache() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo);
......
......@@ -24,7 +24,6 @@ class PipelineLayout : public Object<PipelineLayout, VkPipelineLayout>
{
public:
PipelineLayout(const VkPipelineLayoutCreateInfo* pCreateInfo, void* mem);
~PipelineLayout() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo* pCreateInfo);
......
......@@ -18,7 +18,7 @@
#include "VkObject.hpp"
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <mutex>
namespace vk
{
......@@ -32,7 +32,7 @@ struct Query
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 @@ class QueryPool : public Object<QueryPool, VkQueryPool>
{
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 @@ public:
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]); }
......
......@@ -26,7 +26,6 @@ class RenderPass : public Object<RenderPass, VkRenderPass>
{
public:
RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem);
~RenderPass() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo);
......
......@@ -46,8 +46,6 @@ public:
{
}
~Sampler() = delete;
static size_t ComputeRequiredAllocationSize(const VkSamplerCreateInfo* pCreateInfo)
{
return 0;
......
......@@ -25,8 +25,6 @@ class Semaphore : public Object<Semaphore, VkSemaphore>
public:
Semaphore(const VkSemaphoreCreateInfo* pCreateInfo, void* mem) {}
~Semaphore() = delete;
static size_t ComputeRequiredAllocationSize(const VkSemaphoreCreateInfo* pCreateInfo)
{
return 0;
......
......@@ -30,7 +30,6 @@ class ShaderModule : public Object<ShaderModule, VkShaderModule>
{
public:
ShaderModule(const VkShaderModuleCreateInfo* pCreateInfo, void* mem);
~ShaderModule() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkShaderModuleCreateInfo* pCreateInfo);
......
......@@ -40,6 +40,8 @@ struct PresentImage
class SurfaceKHR
{
public:
virtual ~SurfaceKHR() = default;
operator VkSurfaceKHR()
{
return reinterpret_cast<VkSurfaceKHR::HandleType>(this);
......
......@@ -29,7 +29,6 @@ class SwapchainKHR : public Object<SwapchainKHR, VkSwapchainKHR>
{
public:
SwapchainKHR(const VkSwapchainCreateInfoKHR* pCreateInfo, void* mem);
~SwapchainKHR() = delete;
void destroy(const VkAllocationCallbacks* pAllocator);
......
......@@ -29,8 +29,6 @@ class XlibSurfaceKHR : public SurfaceKHR, public ObjectBase<XlibSurfaceKHR, VkSu
public:
XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem);
~XlibSurfaceKHR() = delete;
void destroySurface(const VkAllocationCallbacks *pAllocator) override;
static size_t ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment