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:
parent
9aed82c00a
commit
06280a2ce5
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user