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) ...@@ -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 } // namespace vk
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "VkPipeline.hpp" #include "VkPipeline.hpp"
#include "VkDestroy.hpp"
#include "VkDevice.hpp" #include "VkDevice.hpp"
#include "VkPipelineCache.hpp" #include "VkPipelineCache.hpp"
#include "VkPipelineLayout.hpp" #include "VkPipelineLayout.hpp"
...@@ -137,11 +138,19 @@ std::shared_ptr<sw::ComputeProgram> createProgram(const vk::PipelineCache::Compu ...@@ -137,11 +138,19 @@ std::shared_ptr<sw::ComputeProgram> createProgram(const vk::PipelineCache::Compu
namespace vk { namespace vk {
Pipeline::Pipeline(PipelineLayout const *layout, const Device *device) Pipeline::Pipeline(PipelineLayout *layout, const Device *device)
: layout(layout) : layout(layout)
, device(device) , device(device)
, robustBufferAccess(device->getEnabledFeatures().robustBufferAccess) , 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) GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo, void *mem, const Device *device)
......
...@@ -42,7 +42,7 @@ class Device; ...@@ -42,7 +42,7 @@ class Device;
class Pipeline class Pipeline
{ {
public: public:
Pipeline(PipelineLayout const *layout, const Device *device); Pipeline(PipelineLayout *layout, const Device *device);
virtual ~Pipeline() = default; virtual ~Pipeline() = default;
operator VkPipeline() operator VkPipeline()
...@@ -55,23 +55,20 @@ public: ...@@ -55,23 +55,20 @@ public:
return vk::VkTtoT<Pipeline, VkPipeline>(object); return vk::VkTtoT<Pipeline, VkPipeline>(object);
} }
void destroy(const VkAllocationCallbacks *pAllocator) void destroy(const VkAllocationCallbacks *pAllocator);
{
destroyPipeline(pAllocator);
}
virtual void destroyPipeline(const VkAllocationCallbacks *pAllocator) = 0; virtual void destroyPipeline(const VkAllocationCallbacks *pAllocator) = 0;
#ifndef NDEBUG #ifndef NDEBUG
virtual VkPipelineBindPoint bindPoint() const = 0; virtual VkPipelineBindPoint bindPoint() const = 0;
#endif #endif
PipelineLayout const *getLayout() const PipelineLayout *getLayout() const
{ {
return layout; return layout;
} }
protected: protected:
PipelineLayout const *layout = nullptr; PipelineLayout *layout = nullptr;
Device const *const device; Device const *const device;
const bool robustBufferAccess = true; const bool robustBufferAccess = true;
......
...@@ -55,6 +55,8 @@ PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, vo ...@@ -55,6 +55,8 @@ PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, vo
size_t pushConstantRangesSize = pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange); size_t pushConstantRangesSize = pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange);
pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage); pushConstantRanges = reinterpret_cast<VkPushConstantRange *>(bindingStorage);
memcpy(pushConstantRanges, pCreateInfo->pPushConstantRanges, pushConstantRangesSize); memcpy(pushConstantRanges, pCreateInfo->pPushConstantRanges, pushConstantRangesSize);
incRefCount();
} }
void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator) void PipelineLayout::destroy(const VkAllocationCallbacks *pAllocator)
...@@ -62,6 +64,16 @@ 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 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) size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo)
{ {
uint32_t bindingsCount = 0; uint32_t bindingsCount = 0;
...@@ -107,4 +119,14 @@ bool PipelineLayout::isDescriptorDynamic(uint32_t setNumber, uint32_t bindingNum ...@@ -107,4 +119,14 @@ bool PipelineLayout::isDescriptorDynamic(uint32_t setNumber, uint32_t bindingNum
return DescriptorSetLayout::IsDescriptorDynamic(getDescriptorType(setNumber, bindingNumber)); return DescriptorSetLayout::IsDescriptorDynamic(getDescriptorType(setNumber, bindingNumber));
} }
uint32_t PipelineLayout::incRefCount()
{
return ++refCount;
}
uint32_t PipelineLayout::decRefCount()
{
return --refCount;
}
} // namespace vk } // namespace vk
...@@ -25,6 +25,7 @@ class PipelineLayout : public Object<PipelineLayout, VkPipelineLayout> ...@@ -25,6 +25,7 @@ class PipelineLayout : public Object<PipelineLayout, VkPipelineLayout>
public: public:
PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, void *mem); PipelineLayout(const VkPipelineLayoutCreateInfo *pCreateInfo, void *mem);
void destroy(const VkAllocationCallbacks *pAllocator); void destroy(const VkAllocationCallbacks *pAllocator);
bool release(const VkAllocationCallbacks *pAllocator);
static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo); static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo *pCreateInfo);
...@@ -41,6 +42,9 @@ public: ...@@ -41,6 +42,9 @@ public:
const uint32_t identifier; const uint32_t identifier;
uint32_t incRefCount();
uint32_t decRefCount();
private: private:
struct Binding struct Binding
{ {
...@@ -60,6 +64,8 @@ private: ...@@ -60,6 +64,8 @@ private:
const uint32_t descriptorSetCount = 0; const uint32_t descriptorSetCount = 0;
const uint32_t pushConstantRangeCount = 0; const uint32_t pushConstantRangeCount = 0;
VkPushConstantRange *pushConstantRanges = nullptr; VkPushConstantRange *pushConstantRanges = nullptr;
std::atomic<uint32_t> refCount{ 0 };
}; };
static inline PipelineLayout *Cast(VkPipelineLayout object) static inline PipelineLayout *Cast(VkPipelineLayout object)
......
...@@ -1909,7 +1909,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLa ...@@ -1909,7 +1909,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLa
TRACE("(VkDevice device = %p, VkPipelineLayout pipelineLayout = %p, const VkAllocationCallbacks* pAllocator = %p)", TRACE("(VkDevice device = %p, VkPipelineLayout pipelineLayout = %p, const VkAllocationCallbacks* pAllocator = %p)",
device, static_cast<void *>(pipelineLayout), pAllocator); 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) 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