Commit 3ad285a6 by Trevor David Black Committed by Trevor Black

Added reference counting for PipelineLayout objects

Bug: b/155664177 Change-Id: I9322be202434908dfd652980f50e1024cf2efa2d Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45368 Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Tested-by: 's avatarTrevor Black <vantablack@google.com> Presubmit-Ready: Trevor Black <vantablack@google.com>
parent e817aaa4
......@@ -65,4 +65,22 @@ inline void destroy(VkT vkObject, const VkAllocationCallbacks *pAllocator)
}
}
template<typename VkT>
inline void release(VkT vkObject, const VkAllocationCallbacks *pAllocator)
{
auto object = Cast(vkObject);
if(object)
{
using T = typename std::remove_pointer<decltype(object)>::type;
if(object->release(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
vk::deallocate(vkObject, pAllocator);
}
}
}
} // namespace vk
......@@ -14,6 +14,7 @@
#include "VkPipeline.hpp"
#include "VkDestroy.hpp"
#include "VkDevice.hpp"
#include "VkPipelineCache.hpp"
#include "VkPipelineLayout.hpp"
......@@ -137,11 +138,19 @@ std::shared_ptr<sw::ComputeProgram> createProgram(const vk::PipelineCache::Compu
namespace vk {
Pipeline::Pipeline(PipelineLayout const *layout, const Device *device)
Pipeline::Pipeline(PipelineLayout *layout, const Device *device)
: layout(layout)
, device(device)
, robustBufferAccess(device->getEnabledFeatures().robustBufferAccess)
{
layout->incRefCount();
}
void Pipeline::destroy(const VkAllocationCallbacks *pAllocator)
{
destroyPipeline(pAllocator);
vk::release(static_cast<VkPipelineLayout>(*layout), pAllocator);
}
GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo, void *mem, const Device *device)
......
......@@ -42,7 +42,7 @@ class Device;
class Pipeline
{
public:
Pipeline(PipelineLayout const *layout, const Device *device);
Pipeline(PipelineLayout *layout, const Device *device);
virtual ~Pipeline() = default;
operator VkPipeline()
......@@ -55,23 +55,20 @@ public:
return vk::VkTtoT<Pipeline, VkPipeline>(object);
}
void destroy(const VkAllocationCallbacks *pAllocator)
{
destroyPipeline(pAllocator);
}
void destroy(const VkAllocationCallbacks *pAllocator);
virtual void destroyPipeline(const VkAllocationCallbacks *pAllocator) = 0;
#ifndef NDEBUG
virtual VkPipelineBindPoint bindPoint() const = 0;
#endif
PipelineLayout const *getLayout() const
PipelineLayout *getLayout() const
{
return layout;
}
protected:
PipelineLayout const *layout = nullptr;
PipelineLayout *layout = nullptr;
Device const *const device;
const bool robustBufferAccess = true;
......
......@@ -55,6 +55,8 @@ PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, vo
size_t pushConstantRangesSize = pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange);
pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage);
memcpy(pushConstantRanges, pCreateInfo->pPushConstantRanges, pushConstantRangesSize);
incRefCount();
}
void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator)
......@@ -62,6 +64,16 @@ void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator)
vk::deallocate(descriptorSets[0].bindings, pAllocator); // pushConstantRanges are in the same allocation
}
bool PipelineLayout::release(const VkAllocationCallbacks *pAllocator)
{
if(decRefCount() == 0)
{
vk::deallocate(descriptorSets[0].bindings, pAllocator); // pushConstantRanges are in the same allocation
return true;
}
return false;
}
size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo)
{
uint32_t bindingsCount = 0;
......@@ -107,4 +119,14 @@ bool PipelineLayout::isDescriptorDynamic(uint32_t setNumber, uint32_t bindingNum
return DescriptorSetLayout::IsDescriptorDynamic(getDescriptorType(setNumber, bindingNumber));
}
uint32_t PipelineLayout::incRefCount()
{
return ++refCount;
}
uint32_t PipelineLayout::decRefCount()
{
return --refCount;
}
} // namespace vk
......@@ -25,6 +25,7 @@ class PipelineLayout : public Object<PipelineLayout, VkPipelineLayout>
public:
PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, void *mem);
void destroy(const VkAllocationCallbacks *pAllocator);
bool release(const VkAllocationCallbacks *pAllocator);
static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo);
......@@ -41,6 +42,9 @@ public:
const uint32_t identifier;
uint32_t incRefCount();
uint32_t decRefCount();
private:
struct Binding
{
......@@ -60,6 +64,8 @@ private:
const uint32_t descriptorSetCount = 0;
const uint32_t pushConstantRangeCount = 0;
VkPushConstantRange *pushConstantRanges = nullptr;
std::atomic<uint32_t> refCount{ 0 };
};
static inline PipelineLayout *Cast(VkPipelineLayout object)
......
......@@ -1909,7 +1909,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLa
TRACE("(VkDevice device = %p, VkPipelineLayout pipelineLayout = %p, const VkAllocationCallbacks* pAllocator = %p)",
device, static_cast<void *>(pipelineLayout), pAllocator);
vk::destroy(pipelineLayout, pAllocator);
vk::release(pipelineLayout, pAllocator);
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler)
......
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