1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-01 16:24:12 +01:00

[dxvk] Add command list tracking to resource

This commit is contained in:
Philip Rebohle 2024-10-28 01:52:33 +01:00
parent 9aed82c00a
commit 06280a2ce5
4 changed files with 60 additions and 6 deletions

View File

@ -287,17 +287,17 @@ namespace dxvk {
*/
template<typename T>
void track(Rc<T>&& object, DxvkAccess access) {
m_objectTracker.track<DxvkResourceRef>(std::move(object), access);
m_objectTracker.track<DxvkResourceRef>(std::move(object), access, m_trackingId);
}
template<typename T>
void track(const Rc<T>& object, DxvkAccess access) {
m_objectTracker.track<DxvkResourceRef>(object.ptr(), access);
m_objectTracker.track<DxvkResourceRef>(object.ptr(), access, m_trackingId);
}
template<typename T>
void track(T* object, DxvkAccess access) {
m_objectTracker.track<DxvkResourceRef>(object, access);
m_objectTracker.track<DxvkResourceRef>(object, access, m_trackingId);
}
/**
@ -1061,6 +1061,11 @@ namespace dxvk {
m_descriptorPools.push_back({ pool, manager });
}
void setTrackingId(uint64_t id) {
m_trackingId = id;
}
private:
DxvkDevice* m_device;
@ -1073,6 +1078,7 @@ namespace dxvk {
DxvkCommandSubmissionInfo m_cmd;
PresenterSync m_wsiSemaphores = { };
uint64_t m_trackingId = 0u;
DxvkObjectTracker m_objectTracker;
DxvkSignalTracker m_signalTracker;

View File

@ -1383,6 +1383,8 @@ namespace dxvk {
Rc<DxvkResourceAllocation> prevAllocation = buffer->assignStorage(std::move(slice));
m_cmd->track(std::move(prevAllocation));
buffer->resetTracking();
// We also need to update all bindings that the buffer
// may be bound to either directly or through views.
VkBufferUsageFlags usage = buffer->info().usage &
@ -1475,6 +1477,8 @@ namespace dxvk {
if (usageInfo.stableGpuAddress)
m_common->memoryManager().lockResourceGpuAddress(image->storage());
image->resetTracking();
}
@ -6712,6 +6716,8 @@ namespace dxvk {
m_state.gp.pipeline = nullptr;
m_state.cp.pipeline = nullptr;
m_cmd->setTrackingId(++m_trackingId);
}

View File

@ -1383,6 +1383,8 @@ namespace dxvk {
Rc<DxvkDevice> m_device;
DxvkObjects* m_common;
uint64_t m_trackingId = 0u;
Rc<DxvkCommandList> m_cmd;
Rc<DxvkBuffer> m_zeroBuffer;

View File

@ -512,7 +512,7 @@ namespace dxvk {
force_inline bool isInUse(DxvkAccess access) const {
return m_useCount.load(std::memory_order_acquire) >= getIncrement(access);
}
/**
* \brief Tries to acquire reference
*
@ -535,6 +535,43 @@ namespace dxvk {
return Rc<DxvkPagedResource>::unsafeCreate(this);
}
/**
* \brief Sets tracked command list ID
*
* Used to work out if a resource has been used in the current
* command list and optimize certain transfer operations.
* \param [in] trackingId Tracking ID
* \param [in] access Tracked access
*/
void trackId(uint64_t trackingId, DxvkAccess access) {
// Encode write access in the least significant bit
m_trackId = (trackingId << 1u) + uint64_t(access == DxvkAccess::Write);
}
/**
* \brief Checks whether a resource has been tracked
*
* \param [in] trackingId Current tracking ID
* \param [in] access Destination access
* \returns \c true if the resource has been used in a way that
* prevents recordering commands with the given resource access.
*/
bool isTracked(uint64_t trackingId, DxvkAccess access) const {
// We actually want to check for read access here so that this check only
// fails if the resource hasn't been used or if both accesses are read-only.
return m_trackId >= (trackingId << 1u) + uint64_t(access != DxvkAccess::Write);
}
/**
* \brief Resets tracking
*
* Marks the resource as unused in the current command list.
* Should be done when assigning new backing storage.
*/
void resetTracking() {
m_trackId = 0u;
}
/**
* \brief Queries sparse page table
*
@ -562,6 +599,7 @@ namespace dxvk {
private:
std::atomic<uint64_t> m_useCount = { 0u };
uint64_t m_trackId = { 0u };
uint64_t m_cookie = { 0u };
static constexpr uint64_t getIncrement(DxvkAccess access) {
@ -585,13 +623,15 @@ namespace dxvk {
public:
template<typename T>
explicit DxvkResourceRef(Rc<T>&& object, DxvkAccess access)
explicit DxvkResourceRef(Rc<T>&& object, DxvkAccess access, uint64_t trackingId)
: m_ptr(reinterpret_cast<uintptr_t>(static_cast<DxvkPagedResource*>(object.ptr())) | uintptr_t(access)) {
object->trackId(trackingId, access);
object.unsafeExtract()->convertRef(DxvkAccess::None, access);
}
explicit DxvkResourceRef(DxvkPagedResource* object, DxvkAccess access)
explicit DxvkResourceRef(DxvkPagedResource* object, DxvkAccess access, uint64_t trackingId)
: m_ptr(reinterpret_cast<uintptr_t>(object) | uintptr_t(access)) {
object->trackId(trackingId, access);
object->acquire(access);
}