-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vk: add resource ref-counting alternative (#8220)
We add a set of classes to the vk backend that will enable cleaner ref-counting. In particular, all allocation from the HandleAllocator will be wrapped within a resource_ptr<> smart pointer. This struct will maintain a count that will increment/decrement with respect to references (similar to std::shared_ptr). This commit only introduces the new classes/structs and does not actually make any functional difference. A follow-up commit will make the switch to use the smart pointer. We also put VulkanFence and VulkanTimerQuery in a different header because we will need to depend on them separately in the follow-up (reason: they are accessed on the backend thread but allocated on "sync"/filament thread).
- Loading branch information
Showing
13 changed files
with
872 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (C) 2024 The Android Open Source Project | ||
* | ||
* 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 | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "VulkanAsyncHandles.h" | ||
|
||
namespace filament::backend { | ||
|
||
VulkanTimerQuery::VulkanTimerQuery(std::tuple<uint32_t, uint32_t> indices) | ||
: VulkanThreadSafeResource(VulkanResourceType::TIMER_QUERY), | ||
mStartingQueryIndex(std::get<0>(indices)), | ||
mStoppingQueryIndex(std::get<1>(indices)) {} | ||
|
||
void VulkanTimerQuery::setFence(std::shared_ptr<VulkanCmdFence> fence) noexcept { | ||
std::unique_lock<utils::Mutex> lock(mFenceMutex); | ||
mFence = fence; | ||
} | ||
|
||
bool VulkanTimerQuery::isCompleted() noexcept { | ||
std::unique_lock<utils::Mutex> lock(mFenceMutex); | ||
// QueryValue is a synchronous call and might occur before beginTimerQuery has written anything | ||
// into the command buffer, which is an error according to the validation layer that ships in | ||
// the Android NDK. Even when AVAILABILITY_BIT is set, validation seems to require that the | ||
// timestamp has at least been written into a processed command buffer. | ||
|
||
// This fence indicates that the corresponding buffer has been completed. | ||
return mFence && mFence->getStatus() == VK_SUCCESS; | ||
} | ||
|
||
VulkanTimerQuery::~VulkanTimerQuery() = default; | ||
|
||
} // namespace filament::backend |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright (C) 2024 The Android Open Source Project | ||
* | ||
* 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 | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef TNT_FILAMENT_BACKEND_VULKANASYNCHANDLES_H | ||
#define TNT_FILAMENT_BACKEND_VULKANASYNCHANDLES_H | ||
|
||
#include <bluevk/BlueVK.h> | ||
|
||
#include "DriverBase.h" | ||
|
||
#include "VulkanResources.h" | ||
|
||
#include <utils/Mutex.h> | ||
#include <utils/Condition.h> | ||
|
||
namespace filament::backend { | ||
|
||
// Wrapper to enable use of shared_ptr for implementing shared ownership of low-level Vulkan fences. | ||
struct VulkanCmdFence { | ||
struct SetValueScope { | ||
public: | ||
~SetValueScope() { | ||
mHolder->mutex.unlock(); | ||
mHolder->condition.notify_all(); | ||
} | ||
|
||
private: | ||
SetValueScope(VulkanCmdFence* fenceHolder, VkResult result) : | ||
mHolder(fenceHolder) { | ||
mHolder->mutex.lock(); | ||
mHolder->status.store(result); | ||
} | ||
VulkanCmdFence* mHolder; | ||
friend struct VulkanCmdFence; | ||
}; | ||
|
||
VulkanCmdFence(VkFence ifence); | ||
~VulkanCmdFence() = default; | ||
|
||
SetValueScope setValue(VkResult value) { | ||
return {this, value}; | ||
} | ||
|
||
VkFence& getFence() { | ||
return fence; | ||
} | ||
|
||
VkResult getStatus() { | ||
std::unique_lock<utils::Mutex> lock(mutex); | ||
return status.load(std::memory_order_acquire); | ||
} | ||
|
||
private: | ||
VkFence fence; | ||
utils::Condition condition; | ||
utils::Mutex mutex; | ||
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) {} | ||
|
||
std::shared_ptr<VulkanCmdFence> fence; | ||
}; | ||
|
||
struct VulkanTimerQuery : public HwTimerQuery, VulkanThreadSafeResource { | ||
explicit VulkanTimerQuery(std::tuple<uint32_t, uint32_t> indices); | ||
~VulkanTimerQuery(); | ||
|
||
void setFence(std::shared_ptr<VulkanCmdFence> fence) noexcept; | ||
|
||
bool isCompleted() noexcept; | ||
|
||
uint32_t getStartingQueryIndex() const { | ||
return mStartingQueryIndex; | ||
} | ||
|
||
uint32_t getStoppingQueryIndex() const { | ||
return mStoppingQueryIndex; | ||
} | ||
|
||
private: | ||
uint32_t mStartingQueryIndex; | ||
uint32_t mStoppingQueryIndex; | ||
|
||
std::shared_ptr<VulkanCmdFence> mFence; | ||
utils::Mutex mFenceMutex; | ||
}; | ||
|
||
} // namespace filament::backend | ||
|
||
#endif // TNT_FILAMENT_BACKEND_VULKANHASYNCANDLES_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.