Skip to content

Commit

Permalink
vk: refactor resource ref-counting (#8254)
Browse files Browse the repository at this point in the history
Continuing from PR #8220.

Here we change all of the references from the old ref-counting ways
to the new ref-counting structs and mechanisms. There should be no
functional change.
  • Loading branch information
poweifeng authored Nov 12, 2024
1 parent 0108d66 commit bc65135
Show file tree
Hide file tree
Showing 32 changed files with 649 additions and 1,298 deletions.
3 changes: 0 additions & 3 deletions filament/backend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
src/vulkan/VulkanSwapChain.h
src/vulkan/VulkanReadPixels.cpp
src/vulkan/VulkanReadPixels.h
src/vulkan/VulkanResourceAllocator.h
src/vulkan/VulkanResources.cpp
src/vulkan/VulkanResources.h
src/vulkan/VulkanTexture.cpp
src/vulkan/VulkanTexture.h
src/vulkan/VulkanUtility.cpp
Expand Down
3 changes: 1 addition & 2 deletions filament/backend/src/vulkan/VulkanAsyncHandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
namespace filament::backend {

VulkanTimerQuery::VulkanTimerQuery(std::tuple<uint32_t, uint32_t> indices)
: VulkanThreadSafeResource(VulkanResourceType::TIMER_QUERY),
mStartingQueryIndex(std::get<0>(indices)),
: mStartingQueryIndex(std::get<0>(indices)),
mStoppingQueryIndex(std::get<1>(indices)) {}

void VulkanTimerQuery::setFence(std::shared_ptr<VulkanCmdFence> fence) noexcept {
Expand Down
13 changes: 4 additions & 9 deletions filament/backend/src/vulkan/VulkanAsyncHandles.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#include "DriverBase.h"

#include "VulkanResources.h"
#include "vulkan/memory/Resource.h"

#include <utils/Mutex.h>
#include <utils/Condition.h>
Expand All @@ -47,17 +47,12 @@ struct VulkanCmdFence {
std::atomic<VkResult> status;
};

struct VulkanFence : public HwFence, VulkanResource {
VulkanFence() : VulkanResource(VulkanResourceType::FENCE) {}

explicit VulkanFence(std::shared_ptr<VulkanCmdFence> fence)
: VulkanResource(VulkanResourceType::FENCE),
fence(fence) {}

struct VulkanFence : public HwFence, fvkmemory::ThreadSafeResource {
VulkanFence() {}
std::shared_ptr<VulkanCmdFence> fence;
};

struct VulkanTimerQuery : public HwTimerQuery, VulkanThreadSafeResource {
struct VulkanTimerQuery : public HwTimerQuery, fvkmemory::ThreadSafeResource {
explicit VulkanTimerQuery(std::tuple<uint32_t, uint32_t> indices);
~VulkanTimerQuery();

Expand Down
4 changes: 2 additions & 2 deletions filament/backend/src/vulkan/VulkanBlitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void VulkanBlitter::resolve(VulkanAttachment dst, VulkanAttachment src) {
#endif

VulkanCommandBuffer& commands = dst.texture->getIsProtected() ?
mCommands->getProtected() : mCommands->get();
mCommands->getProtected() : mCommands->get();
commands.acquire(src.texture);
commands.acquire(dst.texture);
resolveFast(&commands, aspect, src, dst);
Expand All @@ -177,7 +177,7 @@ void VulkanBlitter::blit(VkFilter filter,
// src and dst should have the same aspect here
VkImageAspectFlags const aspect = src.texture->getImageAspect();
VulkanCommandBuffer& commands = dst.texture->getIsProtected() ?
mCommands->getProtected() : mCommands->get();
mCommands->getProtected() : mCommands->get();
commands.acquire(src.texture);
commands.acquire(dst.texture);
blitFast(&commands, aspect, filter, src, dst, srcRectPair, dstRectPair);
Expand Down
37 changes: 21 additions & 16 deletions filament/backend/src/vulkan/VulkanCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,13 @@ bool VulkanGroupMarkers::empty() const noexcept {

#endif // FVK_DEBUG_GROUP_MARKERS

VulkanCommandBuffer::VulkanCommandBuffer(VulkanContext* context, VulkanResourceAllocator* allocator,
VkDevice device, VkQueue queue, VkCommandPool pool, bool isProtected)
VulkanCommandBuffer::VulkanCommandBuffer(VulkanContext* context, VkDevice device, VkQueue queue,
VkCommandPool pool, bool isProtected)
: mContext(context),
mMarkerCount(0),
isProtected(isProtected),
mDevice(device),
mQueue(queue),
mResourceManager(allocator),
mBuffer(createCommandBuffer(device, pool)),
mFenceStatus(std::make_shared<VulkanCmdFence>(VK_INCOMPLETE)) {
VkSemaphoreCreateInfo sci{.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
Expand All @@ -134,7 +133,7 @@ VulkanCommandBuffer::~VulkanCommandBuffer() {

void VulkanCommandBuffer::reset() noexcept {
mMarkerCount = 0;
mResourceManager.clear();
mResources.clear();
mWaitSemaphores.clear();

// Internally we use the VK_INCOMPLETE status to mean "not yet submitted". When this fence
Expand Down Expand Up @@ -257,8 +256,8 @@ VkSemaphore VulkanCommandBuffer::submit() {
return mSubmission;
}

CommandBufferPool::CommandBufferPool(VulkanContext* context, VulkanResourceAllocator* allocator,
VkDevice device, VkQueue queue, uint8_t queueFamilyIndex, bool isProtected)
CommandBufferPool::CommandBufferPool(VulkanContext* context, VkDevice device, VkQueue queue,
uint8_t queueFamilyIndex, bool isProtected)
: mDevice(device),
mRecording(INVALID) {
VkCommandPoolCreateInfo createInfo = {
Expand All @@ -271,8 +270,8 @@ CommandBufferPool::CommandBufferPool(VulkanContext* context, VulkanResourceAlloc
vkCreateCommandPool(device, &createInfo, VKALLOC, &mPool);

for (size_t i = 0; i < CAPACITY; ++i) {
mBuffers.emplace_back(std::make_unique<VulkanCommandBuffer>(context, allocator, device,
queue, mPool, isProtected));
mBuffers.emplace_back(
std::make_unique<VulkanCommandBuffer>(context, device, queue, mPool, isProtected));
}
}

Expand Down Expand Up @@ -370,16 +369,12 @@ void CommandBufferPool::insertEvent(char const* marker) {
}

VulkanCommands::VulkanCommands(VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
VkQueue protectedQueue, uint32_t protectedQueueFamilyIndex, VulkanContext* context,
VulkanResourceAllocator* allocator)
VkQueue protectedQueue, uint32_t protectedQueueFamilyIndex, VulkanContext* context)
: mDevice(device),
mProtectedQueue(protectedQueue),
mProtectedQueueFamilyIndex(protectedQueueFamilyIndex),
mAllocator(allocator),
mContext(context),
mPool(std::make_unique<CommandBufferPool>(context, allocator, device, queue, queueFamilyIndex,
false)) {
}
mPool(std::make_unique<CommandBufferPool>(context, device, queue, queueFamilyIndex, false)) {}

void VulkanCommands::terminate() {
mPool.reset();
Expand All @@ -395,14 +390,19 @@ VulkanCommandBuffer& VulkanCommands::getProtected() {
assert_invariant(mProtectedQueue != VK_NULL_HANDLE);

if (!mProtectedPool) {
mProtectedPool = std::make_unique<CommandBufferPool>(mContext, mAllocator, mDevice,
mProtectedQueue, mProtectedQueueFamilyIndex, true);
mProtectedPool = std::make_unique<CommandBufferPool>(mContext, mDevice, mProtectedQueue,
mProtectedQueueFamilyIndex, true);
}
auto& ret = mProtectedPool->getRecording();
return ret;
}

bool VulkanCommands::flush() {
// It's possible to call flush and wait at "terminate", in which case, we'll just return.
if (!mPool && !mProtectedPool) {
return false;
}

VkSemaphore dependency = mInjectedDependency;
VkSemaphore lastSubmit = mLastSubmit;
bool hasFlushed = false;
Expand Down Expand Up @@ -434,6 +434,11 @@ bool VulkanCommands::flush() {
}

void VulkanCommands::wait() {
// It's possible to call flush and wait at "terminate", in which case, we'll just return.
if (!mPool && !mProtectedPool) {
return;
}

FVK_SYSTRACE_CONTEXT();
FVK_SYSTRACE_START("commands::wait");

Expand Down
24 changes: 10 additions & 14 deletions filament/backend/src/vulkan/VulkanCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

#include "VulkanAsyncHandles.h"
#include "VulkanConstants.h"
#include "VulkanResources.h"
#include "VulkanUtility.h"
#include "vulkan/memory/ResourcePointer.h"

#include <utils/Condition.h>
#include <utils/FixedCapacityVector.h>
Expand All @@ -39,6 +39,8 @@

namespace filament::backend {

using namespace fvkmemory;

struct VulkanContext;

#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS)
Expand All @@ -65,21 +67,18 @@ class VulkanGroupMarkers {
// DriverApi fence object and should not be destroyed until both the DriverApi object is freed and
// we're done waiting on the most recent submission of the given command buffer.
struct VulkanCommandBuffer {
VulkanCommandBuffer(VulkanContext* mContext, VulkanResourceAllocator* allocator,
VulkanCommandBuffer(VulkanContext* mContext,
VkDevice device, VkQueue queue, VkCommandPool pool, bool isProtected);

VulkanCommandBuffer(VulkanCommandBuffer const&) = delete;
VulkanCommandBuffer& operator=(VulkanCommandBuffer const&) = delete;

~VulkanCommandBuffer();

inline void acquire(VulkanResource* resource) {
mResourceManager.acquire(resource);
inline void acquire(fvkmemory::resource_ptr<fvkmemory::Resource> resource) {
mResources.push_back(resource);
}

inline void acquire(VulkanAcquireOnlyResourceManager* srcResources) {
mResourceManager.acquireAll(srcResources);
}
void reset() noexcept;

inline void insertWait(VkSemaphore sem) {
Expand Down Expand Up @@ -119,21 +118,20 @@ struct VulkanCommandBuffer {
bool const isProtected;
VkDevice mDevice;
VkQueue mQueue;
VulkanAcquireOnlyResourceManager mResourceManager;
CappedArray<VkSemaphore, 2> mWaitSemaphores;
VkCommandBuffer mBuffer;
VkSemaphore mSubmission;
VkFence mFence;
std::shared_ptr<VulkanCmdFence> mFenceStatus;

std::vector<fvkmemory::resource_ptr<Resource>> mResources;
};

struct CommandBufferPool {
using ActiveBuffers = utils::bitset32;
static constexpr int8_t INVALID = -1;

CommandBufferPool(VulkanContext* context, VulkanResourceAllocator* allocator, VkDevice device,
VkQueue queue, uint8_t queueFamilyIndex, bool isProtected);
CommandBufferPool(VulkanContext* context, VkDevice device, VkQueue queue,
uint8_t queueFamilyIndex, bool isProtected);
~CommandBufferPool();

VulkanCommandBuffer& getRecording();
Expand Down Expand Up @@ -189,8 +187,7 @@ struct CommandBufferPool {
class VulkanCommands {
public:
VulkanCommands(VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
VkQueue protectedQueue, uint32_t protectedQueueFamilyIndex, VulkanContext* context,
VulkanResourceAllocator* allocator);
VkQueue protectedQueue, uint32_t protectedQueueFamilyIndex, VulkanContext* context);

void terminate();

Expand Down Expand Up @@ -241,7 +238,6 @@ class VulkanCommands {
VkQueue const mProtectedQueue;
// For defered initialization if/when we need protected content
uint32_t const mProtectedQueueFamilyIndex;
VulkanResourceAllocator* mAllocator;
VulkanContext* mContext;

std::unique_ptr<CommandBufferPool> mPool;
Expand Down
4 changes: 2 additions & 2 deletions filament/backend/src/vulkan/VulkanConstants.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
Expand Down Expand Up @@ -63,7 +63,7 @@
#define FVK_DEBUG_SHADER_MODULE 0x00000800
#define FVK_DEBUG_READ_PIXELS 0x00001000
#define FVK_DEBUG_PIPELINE_CACHE 0x00002000
#define FVK_DEBUG_ALLOCATION 0x00004000
#define FVK_DEBUG_STAGING_ALLOCATION 0x00004000

// Enable the debug utils extension if it is available.
#define FVK_DEBUG_DEBUG_UTILS 0x00008000
Expand Down
15 changes: 6 additions & 9 deletions filament/backend/src/vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@
#include <backend/PixelBufferDescriptor.h>

#include <utils/Panic.h>
#include <utils/FixedCapacityVector.h>

#include <algorithm> // for std::max

using namespace bluevk;

using utils::FixedCapacityVector;


namespace {

} // end anonymous namespace
Expand Down Expand Up @@ -113,7 +109,7 @@ void VulkanTimestamps::clearQuery(uint32_t queryIndex) {
}

void VulkanTimestamps::beginQuery(VulkanCommandBuffer const* commands,
VulkanTimerQuery* query) {
fvkmemory::resource_ptr<VulkanTimerQuery> query) {
uint32_t const index = query->getStartingQueryIndex();

auto const cmdbuffer = commands->buffer();
Expand All @@ -125,19 +121,20 @@ void VulkanTimestamps::beginQuery(VulkanCommandBuffer const* commands,
}

void VulkanTimestamps::endQuery(VulkanCommandBuffer const* commands,
VulkanTimerQuery const* query) {
fvkmemory::resource_ptr<VulkanTimerQuery> query) {
uint32_t const index = query->getStoppingQueryIndex();
vkCmdWriteTimestamp(commands->buffer(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, mPool, index);
}

VulkanTimestamps::QueryResult VulkanTimestamps::getResult(VulkanTimerQuery const* query) {
VulkanTimestamps::QueryResult VulkanTimestamps::getResult(
fvkmemory::resource_ptr<VulkanTimerQuery> query) {
uint32_t const index = query->getStartingQueryIndex();
QueryResult result;
size_t const dataSize = result.size() * sizeof(uint64_t);
VkDeviceSize const stride = sizeof(uint64_t) * 2;
VkResult vkresult =
vkGetQueryPoolResults(mDevice, mPool, index, 2, dataSize, (void*) result.data(),
stride, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
vkGetQueryPoolResults(mDevice, mPool, index, 2, dataSize, (void*) result.data(), stride,
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
FILAMENT_CHECK_POSTCONDITION(vkresult == VK_SUCCESS || vkresult == VK_NOT_READY)
<< "vkGetQueryPoolResults error: " << static_cast<int32_t>(vkresult);
if (vkresult == VK_NOT_READY) {
Expand Down
16 changes: 10 additions & 6 deletions filament/backend/src/vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "VulkanImageUtility.h"
#include "VulkanUtility.h"

#include "vulkan/memory/ResourcePointer.h"

#include <utils/bitset.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Mutex.h>
Expand All @@ -41,10 +43,10 @@ struct VulkanTimerQuery;
struct VulkanCommandBuffer;

struct VulkanAttachment {
VulkanTexture* texture = nullptr;
fvkmemory::resource_ptr<VulkanTexture> texture;
uint8_t level = 0;
uint8_t layerCount = 1;
uint16_t layer = 0;
uint8_t layer = 0;

bool isDepth() const;
VkImage getImage() const;
Expand All @@ -70,9 +72,11 @@ class VulkanTimestamps {
std::tuple<uint32_t, uint32_t> getNextQuery();
void clearQuery(uint32_t queryIndex);

void beginQuery(VulkanCommandBuffer const* commands, VulkanTimerQuery* query);
void endQuery(VulkanCommandBuffer const* commands, VulkanTimerQuery const* query);
QueryResult getResult(VulkanTimerQuery const* query);
void beginQuery(VulkanCommandBuffer const* commands,
fvkmemory::resource_ptr<VulkanTimerQuery> query);
void endQuery(VulkanCommandBuffer const* commands,
fvkmemory::resource_ptr<VulkanTimerQuery> query);
QueryResult getResult(fvkmemory::resource_ptr<VulkanTimerQuery> query);

private:
VkDevice mDevice;
Expand All @@ -84,7 +88,7 @@ class VulkanTimestamps {
struct VulkanRenderPass {
// Between the begin and end command render pass we cache the command buffer
VulkanCommandBuffer* commandBuffer;
VulkanRenderTarget* renderTarget;
fvkmemory::resource_ptr<VulkanRenderTarget> renderTarget;
VkRenderPass renderPass;
RenderPassParams params;
int currentSubpass;
Expand Down
Loading

0 comments on commit bc65135

Please sign in to comment.