Commit 33ffed01 by Jamie Madill Committed by Commit Bot

Vulkan: Clean up garbage APIs.

Instead of dumping resources to a context, we use the release APIs consistently. Refactoring/cleanup change only. Should have very litte impact on runtime behaviour. Bug: angleproject:2464 Change-Id: I2dc7f8316c466f7ccfad50a7b792ba0ee7bc2e49 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1804883Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 2bdefbf8
...@@ -319,7 +319,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk, ...@@ -319,7 +319,7 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk,
VK_ACCESS_HOST_WRITE_BIT, copyRegion)); VK_ACCESS_HOST_WRITE_BIT, copyRegion));
// Immediately release staging buffer. We should probably be using a DynamicBuffer here. // Immediately release staging buffer. We should probably be using a DynamicBuffer here.
contextVk->addGarbage(&stagingBuffer); stagingBuffer.release(contextVk);
} }
else else
{ {
......
...@@ -1282,7 +1282,7 @@ void ContextVk::flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuT ...@@ -1282,7 +1282,7 @@ void ContextVk::flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuT
void ContextVk::clearAllGarbage() void ContextVk::clearAllGarbage()
{ {
VkDevice device = getDevice(); VkDevice device = getDevice();
for (vk::GarbageObjectBase &garbage : mCurrentGarbage) for (vk::GarbageObject &garbage : mCurrentGarbage)
{ {
garbage.destroy(device); garbage.destroy(device);
} }
...@@ -1290,7 +1290,7 @@ void ContextVk::clearAllGarbage() ...@@ -1290,7 +1290,7 @@ void ContextVk::clearAllGarbage()
for (vk::GarbageAndSerial &garbageList : mGarbageQueue) for (vk::GarbageAndSerial &garbageList : mGarbageQueue)
{ {
for (vk::GarbageObjectBase &garbage : garbageList.get()) for (vk::GarbageObject &garbage : garbageList.get())
{ {
garbage.destroy(device); garbage.destroy(device);
} }
...@@ -2731,7 +2731,7 @@ angle::Result ContextVk::checkCompletedCommands() ...@@ -2731,7 +2731,7 @@ angle::Result ContextVk::checkCompletedCommands()
vk::GarbageAndSerial &garbageList = mGarbageQueue[freeIndex]; vk::GarbageAndSerial &garbageList = mGarbageQueue[freeIndex];
if (garbageList.getSerial() < lastCompleted) if (garbageList.getSerial() < lastCompleted)
{ {
for (vk::GarbageObjectBase &garbage : garbageList.get()) for (vk::GarbageObject &garbage : garbageList.get())
{ {
garbage.destroy(device); garbage.destroy(device);
} }
......
...@@ -271,7 +271,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO ...@@ -271,7 +271,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
template <typename T> template <typename T>
void addGarbage(T *object) void addGarbage(T *object)
{ {
object->dumpResources(&mCurrentGarbage); mCurrentGarbage.emplace_back(vk::GetGarbage(object));
} }
// Check to see which batches have finished completion (forward progress for // Check to see which batches have finished completion (forward progress for
......
...@@ -32,7 +32,7 @@ void ImageVk::onDestroy(const egl::Display *display) ...@@ -32,7 +32,7 @@ void ImageVk::onDestroy(const egl::Display *display)
DisplayVk *displayVk = vk::GetImpl(display); DisplayVk *displayVk = vk::GetImpl(display);
RendererVk *renderer = displayVk->getRenderer(); RendererVk *renderer = displayVk->getRenderer();
std::vector<vk::GarbageObjectBase> garbage; std::vector<vk::GarbageObject> garbage;
if (mImage != nullptr && mOwnsImage) if (mImage != nullptr && mOwnsImage)
{ {
......
...@@ -24,7 +24,7 @@ class ExternalImageSiblingVk : public ExternalImageSiblingImpl ...@@ -24,7 +24,7 @@ class ExternalImageSiblingVk : public ExternalImageSiblingImpl
virtual vk::ImageHelper *getImage() const = 0; virtual vk::ImageHelper *getImage() const = 0;
virtual void release(DisplayVk *display, std::vector<vk::GarbageObjectBase> *garbageQueue) = 0; virtual void release(DisplayVk *display, std::vector<vk::GarbageObject> *garbageQueue) = 0;
}; };
class ImageVk : public ImageImpl class ImageVk : public ImageImpl
......
...@@ -151,7 +151,7 @@ angle::Result OverlayVk::cullWidgets(ContextVk *contextVk) ...@@ -151,7 +151,7 @@ angle::Result OverlayVk::cullWidgets(ContextVk *contextVk)
RendererVk *rendererVk = contextVk->getRenderer(); RendererVk *rendererVk = contextVk->getRenderer();
// Release old culledWidgets image // Release old culledWidgets image
contextVk->addGarbage(&mCulledWidgets); mCulledWidgets.releaseImage(contextVk);
contextVk->addGarbage(&mCulledWidgetsView); contextVk->addGarbage(&mCulledWidgetsView);
// Create a buffer to contain coordinates of enabled text and graph widgets. This buffer will // Create a buffer to contain coordinates of enabled text and graph widgets. This buffer will
......
...@@ -1616,8 +1616,7 @@ angle::Result RendererVk::newSharedFence(vk::Context *context, ...@@ -1616,8 +1616,7 @@ angle::Result RendererVk::newSharedFence(vk::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
void RendererVk::addGarbage(vk::Shared<vk::Fence> &&fence, void RendererVk::addGarbage(vk::Shared<vk::Fence> &&fence, std::vector<vk::GarbageObject> &&garbage)
std::vector<vk::GarbageObjectBase> &&garbage)
{ {
std::vector<vk::Shared<vk::Fence>> fences; std::vector<vk::Shared<vk::Fence>> fences;
fences.push_back(std::move(fence)); fences.push_back(std::move(fence));
...@@ -1625,7 +1624,7 @@ void RendererVk::addGarbage(vk::Shared<vk::Fence> &&fence, ...@@ -1625,7 +1624,7 @@ void RendererVk::addGarbage(vk::Shared<vk::Fence> &&fence,
} }
void RendererVk::addGarbage(std::vector<vk::Shared<vk::Fence>> &&fences, void RendererVk::addGarbage(std::vector<vk::Shared<vk::Fence>> &&fences,
std::vector<vk::GarbageObjectBase> &&garbage) std::vector<vk::GarbageObject> &&garbage)
{ {
std::lock_guard<decltype(mGarbageMutex)> lock(mGarbageMutex); std::lock_guard<decltype(mGarbageMutex)> lock(mGarbageMutex);
mFencedGarbage.emplace_back(std::move(fences), std::move(garbage)); mFencedGarbage.emplace_back(std::move(fences), std::move(garbage));
...@@ -1677,7 +1676,7 @@ angle::Result RendererVk::cleanupGarbage(vk::Context *context, bool block) ...@@ -1677,7 +1676,7 @@ angle::Result RendererVk::cleanupGarbage(vk::Context *context, bool block)
ANGLE_TRY(WaitFences(context, &garbageIter->first, block)); ANGLE_TRY(WaitFences(context, &garbageIter->first, block));
if (garbageIter->first.empty()) if (garbageIter->first.empty())
{ {
for (vk::GarbageObjectBase &garbageObject : garbageIter->second) for (vk::GarbageObject &garbageObject : garbageIter->second)
{ {
garbageObject.destroy(mDevice); garbageObject.destroy(mDevice);
} }
......
...@@ -150,9 +150,9 @@ class RendererVk : angle::NonCopyable ...@@ -150,9 +150,9 @@ class RendererVk : angle::NonCopyable
sharedFenceIn->resetAndRecycle(&mFenceRecycler); sharedFenceIn->resetAndRecycle(&mFenceRecycler);
} }
void addGarbage(vk::Shared<vk::Fence> &&fence, std::vector<vk::GarbageObjectBase> &&garbage); void addGarbage(vk::Shared<vk::Fence> &&fence, std::vector<vk::GarbageObject> &&garbage);
void addGarbage(std::vector<vk::Shared<vk::Fence>> &&fences, void addGarbage(std::vector<vk::Shared<vk::Fence>> &&fences,
std::vector<vk::GarbageObjectBase> &&garbage); std::vector<vk::GarbageObject> &&garbage);
static constexpr size_t kMaxExtensionNames = 200; static constexpr size_t kMaxExtensionNames = 200;
using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>; using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
...@@ -230,7 +230,7 @@ class RendererVk : angle::NonCopyable ...@@ -230,7 +230,7 @@ class RendererVk : angle::NonCopyable
std::mutex mGarbageMutex; std::mutex mGarbageMutex;
using FencedGarbage = using FencedGarbage =
std::pair<std::vector<vk::Shared<vk::Fence>>, std::vector<vk::GarbageObjectBase>>; std::pair<std::vector<vk::Shared<vk::Fence>>, std::vector<vk::GarbageObject>>;
std::vector<FencedGarbage> mFencedGarbage; std::vector<FencedGarbage> mFencedGarbage;
vk::MemoryProperties mMemoryProperties; vk::MemoryProperties mMemoryProperties;
......
...@@ -162,21 +162,13 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display ...@@ -162,21 +162,13 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display) void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display)
{ {
DisplayVk *displayVk = vk::GetImpl(display); DisplayVk *displayVk = vk::GetImpl(display);
VkDevice device = displayVk->getDevice();
std::vector<vk::GarbageObjectBase> garbageObjects;
image.releaseImage(displayVk, &garbageObjects);
image.releaseStagingBuffer(displayVk, &garbageObjects);
// It should be safe to immediately destroy the backing images of a surface on surface // It should be safe to immediately destroy the backing images of a surface on surface
// destruction. // destruction. If this assumption is incorrect, we could use the last submit serial
// If this assumption is broken, we could track the last submit fence for the last context that // to determine when to destroy the surface.
// used this surface to garbage collect the surfaces. image.destroy(device);
for (vk::GarbageObjectBase &garbage : garbageObjects) imageView.destroy(device);
{
garbage.destroy(displayVk->getDevice());
}
imageView.destroy(displayVk->getDevice());
} }
OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState, OffscreenSurfaceVk::OffscreenSurfaceVk(const egl::SurfaceState &surfaceState,
...@@ -936,49 +928,21 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk) ...@@ -936,49 +928,21 @@ void WindowSurfaceVk::releaseSwapchainImages(ContextVk *contextVk)
void WindowSurfaceVk::destroySwapChainImages(DisplayVk *displayVk) void WindowSurfaceVk::destroySwapChainImages(DisplayVk *displayVk)
{ {
std::vector<vk::GarbageObjectBase> garbageObjects;
if (mDepthStencilImage.valid())
{
mDepthStencilImage.releaseImage(displayVk, &garbageObjects);
mDepthStencilImage.releaseStagingBuffer(displayVk, &garbageObjects);
if (mDepthStencilImageView.valid())
{
mDepthStencilImageView.dumpResources(&garbageObjects);
}
}
if (mColorImageMS.valid())
{
mColorImageMS.releaseImage(displayVk, &garbageObjects);
mColorImageMS.releaseImage(displayVk, &garbageObjects);
mColorImageViewMS.dumpResources(&garbageObjects);
mFramebufferMS.dumpResources(&garbageObjects);
}
VkDevice device = displayVk->getDevice(); VkDevice device = displayVk->getDevice();
for (vk::GarbageObjectBase &garbage : garbageObjects) mDepthStencilImage.destroy(device);
{ mDepthStencilImageView.destroy(device);
garbage.destroy(device); mColorImageMS.destroy(device);
} mColorImageViewMS.destroy(device);
mFramebufferMS.destroy(device);
for (SwapchainImage &swapchainImage : mSwapchainImages) for (SwapchainImage &swapchainImage : mSwapchainImages)
{ {
// We don't own the swapchain image handles, so we just remove our reference to it. // We don't own the swapchain image handles, so we just remove our reference to it.
swapchainImage.image.resetImageWeakReference(); swapchainImage.image.resetImageWeakReference();
swapchainImage.image.destroy(device); swapchainImage.image.destroy(device);
swapchainImage.imageView.destroy(device);
if (swapchainImage.imageView.valid()) swapchainImage.framebuffer.destroy(device);
{
swapchainImage.imageView.destroy(device);
}
if (swapchainImage.framebuffer.valid())
{
swapchainImage.framebuffer.destroy(device);
}
for (ImagePresentHistory &presentHistory : swapchainImage.presentHistory) for (ImagePresentHistory &presentHistory : swapchainImage.presentHistory)
{ {
......
...@@ -36,8 +36,8 @@ void FenceSyncVk::onDestroy(ContextVk *contextVk) ...@@ -36,8 +36,8 @@ void FenceSyncVk::onDestroy(ContextVk *contextVk)
void FenceSyncVk::onDestroy(DisplayVk *display) void FenceSyncVk::onDestroy(DisplayVk *display)
{ {
std::vector<vk::GarbageObjectBase> garbage; std::vector<vk::GarbageObject> garbage;
mEvent.dumpResources(&garbage); garbage.emplace_back(vk::GetGarbage(&mEvent));
display->getRenderer()->addGarbage(std::move(mFences), std::move(garbage)); display->getRenderer()->addGarbage(std::move(mFences), std::move(garbage));
} }
......
...@@ -202,7 +202,7 @@ vk::ImageHelper *HardwareBufferImageSiblingVkAndroid::getImage() const ...@@ -202,7 +202,7 @@ vk::ImageHelper *HardwareBufferImageSiblingVkAndroid::getImage() const
} }
void HardwareBufferImageSiblingVkAndroid::release(DisplayVk *display, void HardwareBufferImageSiblingVkAndroid::release(DisplayVk *display,
std::vector<vk::GarbageObjectBase> *garbageQueue) std::vector<vk::GarbageObject> *garbageQueue)
{ {
if (mImage != nullptr) if (mImage != nullptr)
{ {
......
...@@ -36,7 +36,7 @@ class HardwareBufferImageSiblingVkAndroid : public ExternalImageSiblingVk ...@@ -36,7 +36,7 @@ class HardwareBufferImageSiblingVkAndroid : public ExternalImageSiblingVk
// ExternalImageSiblingVk interface // ExternalImageSiblingVk interface
vk::ImageHelper *getImage() const override; vk::ImageHelper *getImage() const override;
void release(DisplayVk *display, std::vector<vk::GarbageObjectBase> *garbageQueue) override; void release(DisplayVk *display, std::vector<vk::GarbageObject> *garbageQueue) override;
private: private:
angle::Result initImpl(DisplayVk *displayVk); angle::Result initImpl(DisplayVk *displayVk);
......
...@@ -457,7 +457,7 @@ void DynamicBuffer::releaseBufferListToContext(ContextVk *contextVk, ...@@ -457,7 +457,7 @@ void DynamicBuffer::releaseBufferListToContext(ContextVk *contextVk,
} }
void DynamicBuffer::releaseBufferListToDisplay(DisplayVk *display, void DynamicBuffer::releaseBufferListToDisplay(DisplayVk *display,
std::vector<GarbageObjectBase> *garbageQueue, std::vector<GarbageObject> *garbageQueue,
std::vector<BufferHelper *> *buffers) std::vector<BufferHelper *> *buffers)
{ {
for (BufferHelper *toFree : *buffers) for (BufferHelper *toFree : *buffers)
...@@ -501,7 +501,7 @@ void DynamicBuffer::release(ContextVk *contextVk) ...@@ -501,7 +501,7 @@ void DynamicBuffer::release(ContextVk *contextVk)
} }
} }
void DynamicBuffer::release(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue) void DynamicBuffer::release(DisplayVk *display, std::vector<GarbageObject> *garbageQueue)
{ {
reset(); reset();
...@@ -1310,15 +1310,15 @@ void BufferHelper::release(ContextVk *contextVk) ...@@ -1310,15 +1310,15 @@ void BufferHelper::release(ContextVk *contextVk)
contextVk->addGarbage(&mDeviceMemory); contextVk->addGarbage(&mDeviceMemory);
} }
void BufferHelper::release(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue) void BufferHelper::release(DisplayVk *display, std::vector<GarbageObject> *garbageQueue)
{ {
unmap(display->getDevice()); unmap(display->getDevice());
mSize = 0; mSize = 0;
mViewFormat = nullptr; mViewFormat = nullptr;
mBuffer.dumpResources(garbageQueue); garbageQueue->emplace_back(GetGarbage(&mBuffer));
mBufferView.dumpResources(garbageQueue); garbageQueue->emplace_back(GetGarbage(&mBufferView));
mDeviceMemory.dumpResources(garbageQueue); garbageQueue->emplace_back(GetGarbage(&mDeviceMemory));
} }
bool BufferHelper::needsOnWriteBarrier(VkAccessFlags readAccessType, bool BufferHelper::needsOnWriteBarrier(VkAccessFlags readAccessType,
...@@ -1571,10 +1571,10 @@ void ImageHelper::releaseImage(ContextVk *contextVk) ...@@ -1571,10 +1571,10 @@ void ImageHelper::releaseImage(ContextVk *contextVk)
contextVk->addGarbage(&mDeviceMemory); contextVk->addGarbage(&mDeviceMemory);
} }
void ImageHelper::releaseImage(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue) void ImageHelper::releaseImage(DisplayVk *display, std::vector<GarbageObject> *garbageQueue)
{ {
mImage.dumpResources(garbageQueue); garbageQueue->emplace_back(GetGarbage(&mImage));
mDeviceMemory.dumpResources(garbageQueue); garbageQueue->emplace_back(GetGarbage(&mDeviceMemory));
} }
void ImageHelper::releaseStagingBuffer(ContextVk *contextVk) void ImageHelper::releaseStagingBuffer(ContextVk *contextVk)
...@@ -1588,8 +1588,7 @@ void ImageHelper::releaseStagingBuffer(ContextVk *contextVk) ...@@ -1588,8 +1588,7 @@ void ImageHelper::releaseStagingBuffer(ContextVk *contextVk)
mSubresourceUpdates.clear(); mSubresourceUpdates.clear();
} }
void ImageHelper::releaseStagingBuffer(DisplayVk *display, void ImageHelper::releaseStagingBuffer(DisplayVk *display, std::vector<GarbageObject> *garbageQueue)
std::vector<GarbageObjectBase> *garbageQueue)
{ {
// Remove updates that never made it to the texture. // Remove updates that never made it to the texture.
for (SubresourceUpdate &update : mSubresourceUpdates) for (SubresourceUpdate &update : mSubresourceUpdates)
...@@ -1686,6 +1685,7 @@ void ImageHelper::destroy(VkDevice device) ...@@ -1686,6 +1685,7 @@ void ImageHelper::destroy(VkDevice device)
{ {
mImage.destroy(device); mImage.destroy(device);
mDeviceMemory.destroy(device); mDeviceMemory.destroy(device);
mStagingBuffer.destroy(device);
mCurrentLayout = ImageLayout::Undefined; mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 0; mLayerCount = 0;
mLevelCount = 0; mLevelCount = 0;
...@@ -1755,12 +1755,6 @@ VkImageAspectFlags ImageHelper::getAspectFlags() const ...@@ -1755,12 +1755,6 @@ VkImageAspectFlags ImageHelper::getAspectFlags() const
return GetFormatAspectFlags(mFormat->imageFormat()); return GetFormatAspectFlags(mFormat->imageFormat());
} }
void ImageHelper::dumpResources(GarbageList *garbageList)
{
mImage.dumpResources(garbageList);
mDeviceMemory.dumpResources(garbageList);
}
VkImageLayout ImageHelper::getCurrentLayout() const VkImageLayout ImageHelper::getCurrentLayout() const
{ {
return kImageMemoryBarrierData[mCurrentLayout].layout; return kImageMemoryBarrierData[mCurrentLayout].layout;
...@@ -2692,7 +2686,7 @@ void ImageHelper::SubresourceUpdate::release(ContextVk *contextVk) ...@@ -2692,7 +2686,7 @@ void ImageHelper::SubresourceUpdate::release(ContextVk *contextVk)
} }
void ImageHelper::SubresourceUpdate::release(DisplayVk *display, void ImageHelper::SubresourceUpdate::release(DisplayVk *display,
std::vector<GarbageObjectBase> *garbageQueue) std::vector<GarbageObject> *garbageQueue)
{ {
if (updateSource == UpdateSource::Image) if (updateSource == UpdateSource::Image)
{ {
......
...@@ -83,7 +83,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -83,7 +83,7 @@ class DynamicBuffer : angle::NonCopyable
// This releases resources when they might currently be in use. // This releases resources when they might currently be in use.
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
void release(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue); void release(DisplayVk *display, std::vector<GarbageObject> *garbageQueue);
// This releases all the buffers that have been allocated since this was last called. // This releases all the buffers that have been allocated since this was last called.
void releaseInFlightBuffers(ContextVk *contextVk); void releaseInFlightBuffers(ContextVk *contextVk);
...@@ -103,7 +103,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -103,7 +103,7 @@ class DynamicBuffer : angle::NonCopyable
angle::Result allocateNewBuffer(ContextVk *contextVk); angle::Result allocateNewBuffer(ContextVk *contextVk);
void releaseBufferListToContext(ContextVk *contextVk, std::vector<BufferHelper *> *buffers); void releaseBufferListToContext(ContextVk *contextVk, std::vector<BufferHelper *> *buffers);
void releaseBufferListToDisplay(DisplayVk *display, void releaseBufferListToDisplay(DisplayVk *display,
std::vector<GarbageObjectBase> *garbageQueue, std::vector<GarbageObject> *garbageQueue,
std::vector<BufferHelper *> *buffers); std::vector<BufferHelper *> *buffers);
void destroyBufferList(VkDevice device, std::vector<BufferHelper *> *buffers); void destroyBufferList(VkDevice device, std::vector<BufferHelper *> *buffers);
...@@ -449,7 +449,7 @@ class BufferHelper final : public CommandGraphResource ...@@ -449,7 +449,7 @@ class BufferHelper final : public CommandGraphResource
void destroy(VkDevice device); void destroy(VkDevice device);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
void release(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue); void release(DisplayVk *display, std::vector<GarbageObject> *garbageQueue);
bool valid() const { return mBuffer.valid(); } bool valid() const { return mBuffer.valid(); }
const Buffer &getBuffer() const { return mBuffer; } const Buffer &getBuffer() const { return mBuffer; }
...@@ -704,16 +704,15 @@ class ImageHelper final : public CommandGraphResource ...@@ -704,16 +704,15 @@ class ImageHelper final : public CommandGraphResource
uint32_t layerCount); uint32_t layerCount);
void releaseImage(ContextVk *contextVk); void releaseImage(ContextVk *contextVk);
void releaseImage(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue); void releaseImage(DisplayVk *display, std::vector<GarbageObject> *garbageQueue);
void releaseStagingBuffer(ContextVk *contextVk); void releaseStagingBuffer(ContextVk *contextVk);
void releaseStagingBuffer(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue); void releaseStagingBuffer(DisplayVk *display, std::vector<GarbageObject> *garbageQueue);
bool valid() const { return mImage.valid(); } bool valid() const { return mImage.valid(); }
VkImageAspectFlags getAspectFlags() const; VkImageAspectFlags getAspectFlags() const;
void destroy(VkDevice device); void destroy(VkDevice device);
void dumpResources(GarbageList *garbageList);
void init2DWeakReference(VkImage handle, void init2DWeakReference(VkImage handle,
const gl::Extents &glExtents, const gl::Extents &glExtents,
...@@ -885,7 +884,7 @@ class ImageHelper final : public CommandGraphResource ...@@ -885,7 +884,7 @@ class ImageHelper final : public CommandGraphResource
SubresourceUpdate(const SubresourceUpdate &other); SubresourceUpdate(const SubresourceUpdate &other);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
void release(DisplayVk *display, std::vector<GarbageObjectBase> *garbageQueue); void release(DisplayVk *display, std::vector<GarbageObject> *garbageQueue);
const VkImageSubresourceLayers &dstSubresource() const const VkImageSubresourceLayers &dstSubresource() const
{ {
......
...@@ -351,10 +351,10 @@ angle::Result StagingBuffer::init(Context *context, VkDeviceSize size, StagingUs ...@@ -351,10 +351,10 @@ angle::Result StagingBuffer::init(Context *context, VkDeviceSize size, StagingUs
return angle::Result::Continue; return angle::Result::Continue;
} }
void StagingBuffer::dumpResources(GarbageList *garbageList) void StagingBuffer::release(ContextVk *contextVk)
{ {
mBuffer.dumpResources(garbageList); contextVk->addGarbage(&mBuffer);
mDeviceMemory.dumpResources(garbageList); contextVk->addGarbage(&mDeviceMemory);
} }
angle::Result AllocateBufferMemory(vk::Context *context, angle::Result AllocateBufferMemory(vk::Context *context,
...@@ -435,23 +435,26 @@ gl::TextureType Get2DTextureType(uint32_t layerCount, GLint samples) ...@@ -435,23 +435,26 @@ gl::TextureType Get2DTextureType(uint32_t layerCount, GLint samples)
} }
} }
GarbageObjectBase::GarbageObjectBase() : mHandleType(HandleType::Invalid), mHandle(VK_NULL_HANDLE) GarbageObject::GarbageObject() : mHandleType(HandleType::Invalid), mHandle(VK_NULL_HANDLE) {}
GarbageObject::GarbageObject(HandleType handleType, GarbageHandle handle)
: mHandleType(handleType), mHandle(handle)
{} {}
GarbageObjectBase::GarbageObjectBase(GarbageObjectBase &&other) : GarbageObjectBase() GarbageObject::GarbageObject(GarbageObject &&other) : GarbageObject()
{ {
*this = std::move(other); *this = std::move(other);
} }
GarbageObjectBase &GarbageObjectBase::operator=(GarbageObjectBase &&rhs) GarbageObject &GarbageObject::operator=(GarbageObject &&rhs)
{ {
std::swap(mHandle, rhs.mHandle); std::swap(mHandle, rhs.mHandle);
std::swap(mHandleType, rhs.mHandleType); std::swap(mHandleType, rhs.mHandleType);
return *this; return *this;
} }
// GarbageObjectBase implementation // GarbageObject implementation
void GarbageObjectBase::destroy(VkDevice device) void GarbageObject::destroy(VkDevice device)
{ {
switch (mHandleType) switch (mHandleType)
{ {
......
...@@ -226,27 +226,38 @@ class ObjectAndSerial final : angle::NonCopyable ...@@ -226,27 +226,38 @@ class ObjectAndSerial final : angle::NonCopyable
// Reference to a deleted object. The object is due to be destroyed at some point in the future. // Reference to a deleted object. The object is due to be destroyed at some point in the future.
// |mHandleType| determines the type of the object and which destroy function should be called. // |mHandleType| determines the type of the object and which destroy function should be called.
class GarbageObjectBase class GarbageObject
{ {
public: public:
template <typename ObjectT> GarbageObject();
GarbageObjectBase(const ObjectT &object) GarbageObject(GarbageObject &&other);
: mHandleType(HandleTypeHelper<ObjectT>::kHandleType), GarbageObject &operator=(GarbageObject &&rhs);
mHandle(reinterpret_cast<VkDevice>(object.getHandle()))
{}
GarbageObjectBase();
GarbageObjectBase(GarbageObjectBase &&other);
GarbageObjectBase &operator=(GarbageObjectBase &&rhs);
void destroy(VkDevice device); void destroy(VkDevice device);
template <typename DerivedT, typename HandleT>
static GarbageObject Get(WrappedObject<DerivedT, HandleT> *object)
{
return GarbageObject(HandleTypeHelper<DerivedT>::kHandleType,
reinterpret_cast<GarbageHandle>(object->release()));
}
private: private:
VK_DEFINE_HANDLE(GarbageHandle)
GarbageObject(HandleType handleType, GarbageHandle handle);
HandleType mHandleType; HandleType mHandleType;
VkDevice mHandle; GarbageHandle mHandle;
}; };
template <typename T>
GarbageObject GetGarbage(T *obj)
{
return GarbageObject::Get(obj);
}
// A list of garbage objects. Has no object lifetime information. // A list of garbage objects. Has no object lifetime information.
using GarbageList = std::vector<GarbageObjectBase>; using GarbageList = std::vector<GarbageObject>;
// A list of garbage objects and the associated serial after which the objects can be destroyed. // A list of garbage objects and the associated serial after which the objects can be destroyed.
using GarbageAndSerial = ObjectAndSerial<GarbageList>; using GarbageAndSerial = ObjectAndSerial<GarbageList>;
...@@ -277,6 +288,7 @@ class StagingBuffer final : angle::NonCopyable ...@@ -277,6 +288,7 @@ class StagingBuffer final : angle::NonCopyable
{ {
public: public:
StagingBuffer(); StagingBuffer();
void release(ContextVk *contextVk);
void destroy(VkDevice device); void destroy(VkDevice device);
angle::Result init(Context *context, VkDeviceSize size, StagingUsage usage); angle::Result init(Context *context, VkDeviceSize size, StagingUsage usage);
...@@ -287,8 +299,6 @@ class StagingBuffer final : angle::NonCopyable ...@@ -287,8 +299,6 @@ class StagingBuffer final : angle::NonCopyable
const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; } const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
size_t getSize() const { return mSize; } size_t getSize() const { return mSize; }
void dumpResources(GarbageList *garbageList);
private: private:
Buffer mBuffer; Buffer mBuffer;
DeviceMemory mDeviceMemory; DeviceMemory mDeviceMemory;
......
...@@ -19,46 +19,6 @@ namespace rx ...@@ -19,46 +19,6 @@ namespace rx
{ {
namespace vk namespace vk
{ {
// Base class for all wrapped vulkan objects. Implements several common helper routines.
template <typename DerivedT, typename HandleT>
class WrappedObject : angle::NonCopyable
{
public:
HandleT getHandle() const { return mHandle; }
bool valid() const { return (mHandle != VK_NULL_HANDLE); }
const HandleT *ptr() const { return &mHandle; }
template <typename ResourceOutType>
void dumpResources(std::vector<ResourceOutType> *outQueue)
{
if (valid())
{
outQueue->emplace_back(*static_cast<DerivedT *>(this));
mHandle = VK_NULL_HANDLE;
}
}
protected:
WrappedObject() : mHandle(VK_NULL_HANDLE) {}
~WrappedObject() { ASSERT(!valid()); }
WrappedObject(WrappedObject &&other) : mHandle(other.mHandle)
{
other.mHandle = VK_NULL_HANDLE;
}
// Only works to initialize empty objects, since we don't have the device handle.
WrappedObject &operator=(WrappedObject &&other)
{
ASSERT(!valid());
std::swap(mHandle, other.mHandle);
return *this;
}
HandleT mHandle;
};
// Helper macros that apply to all the wrapped object types. // Helper macros that apply to all the wrapped object types.
// Unimplemented handle types: // Unimplemented handle types:
// Instance // Instance
...@@ -127,6 +87,43 @@ struct HandleTypeHelper<priv::CommandBuffer> ...@@ -127,6 +87,43 @@ struct HandleTypeHelper<priv::CommandBuffer>
#undef ANGLE_HANDLE_TYPE_HELPER_FUNC #undef ANGLE_HANDLE_TYPE_HELPER_FUNC
// Base class for all wrapped vulkan objects. Implements several common helper routines.
template <typename DerivedT, typename HandleT>
class WrappedObject : angle::NonCopyable
{
public:
HandleT getHandle() const { return mHandle; }
bool valid() const { return (mHandle != VK_NULL_HANDLE); }
const HandleT *ptr() const { return &mHandle; }
HandleT release()
{
HandleT handle = mHandle;
mHandle = VK_NULL_HANDLE;
return handle;
}
protected:
WrappedObject() : mHandle(VK_NULL_HANDLE) {}
~WrappedObject() { ASSERT(!valid()); }
WrappedObject(WrappedObject &&other) : mHandle(other.mHandle)
{
other.mHandle = VK_NULL_HANDLE;
}
// Only works to initialize empty objects, since we don't have the device handle.
WrappedObject &operator=(WrappedObject &&other)
{
ASSERT(!valid());
std::swap(mHandle, other.mHandle);
return *this;
}
HandleT mHandle;
};
class CommandPool final : public WrappedObject<CommandPool, VkCommandPool> class CommandPool final : public WrappedObject<CommandPool, VkCommandPool>
{ {
public: public:
......
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