mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Implement read/write tracking in lifetime tracker
This way we will be able to more accurately determine how a resource is going to be used by the GPU, and we can also cut unnecessary atomic operations for non-resource objects.
This commit is contained in:
parent
136ad3e4c9
commit
63183141bc
@ -147,7 +147,7 @@ namespace dxvk {
|
||||
* completed.
|
||||
*/
|
||||
void trackResource(Rc<DxvkResource> rc) {
|
||||
m_resources.trackResource(std::move(rc));
|
||||
m_resources.trackResource<DxvkAccess::Write>(std::move(rc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,7 @@ namespace dxvk {
|
||||
|
||||
void DxvkLifetimeTracker::reset() {
|
||||
for (const auto& resource : m_resources)
|
||||
resource->release();
|
||||
resource.first->release(resource.second);
|
||||
m_resources.clear();
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,10 @@ namespace dxvk {
|
||||
* \brief Adds a resource to track
|
||||
* \param [in] rc The resource to track
|
||||
*/
|
||||
template<DxvkAccess Access>
|
||||
void trackResource(Rc<DxvkResource>&& rc) {
|
||||
rc->acquire();
|
||||
m_resources.emplace_back(std::move(rc));
|
||||
rc->acquire(Access);
|
||||
m_resources.emplace_back(std::move(rc), Access);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,7 +41,7 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Rc<DxvkResource>> m_resources;
|
||||
std::vector<std::pair<Rc<DxvkResource>, DxvkAccess>> m_resources;
|
||||
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@ namespace dxvk {
|
||||
enum class DxvkAccess {
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
None = 2,
|
||||
};
|
||||
|
||||
using DxvkAccessFlags = Flags<DxvkAccess>;
|
||||
@ -19,22 +20,63 @@ namespace dxvk {
|
||||
* is recorded, it will be marked as 'in use'.
|
||||
*/
|
||||
class DxvkResource : public RcObject {
|
||||
|
||||
constexpr static uint32_t UseCountIncrementW = 1 << 18;
|
||||
constexpr static uint32_t UseCountIncrementR = 1;
|
||||
constexpr static uint32_t UseCountMaskW = ~(UseCountIncrementW - 1);
|
||||
constexpr static uint32_t UseCountMaskR = ~(UseCountIncrementR - 1);
|
||||
public:
|
||||
|
||||
virtual ~DxvkResource();
|
||||
|
||||
bool isInUse() const {
|
||||
return m_useCount.load() != 0;
|
||||
/**
|
||||
* \brief Checks whether resource is in use
|
||||
*
|
||||
* Returns \c true if there are pending accesses to
|
||||
* the resource by the GPU matching the given access
|
||||
* type. Note that checking for reads will also return
|
||||
* \c true if the resource is being written to.
|
||||
* \param [in] access Access type to check for
|
||||
* \returns \c true if the resource is in use
|
||||
*/
|
||||
bool isInUse(DxvkAccess access = DxvkAccess::Read) const {
|
||||
uint32_t mask = access == DxvkAccess::Write
|
||||
? UseCountMaskW
|
||||
: UseCountMaskR;
|
||||
return m_useCount.load() & mask;
|
||||
}
|
||||
|
||||
void acquire() { m_useCount += 1; }
|
||||
void release() { m_useCount -= 1; }
|
||||
/**
|
||||
* \brief Acquires resource
|
||||
*
|
||||
* Increments use count for the given access type.
|
||||
* \param Access Resource access type
|
||||
*/
|
||||
void acquire(DxvkAccess access) {
|
||||
if (access != DxvkAccess::None)
|
||||
m_useCount += getIncrement(access);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Releases resource
|
||||
*
|
||||
* Decrements use count for the given access type.
|
||||
* \param Access Resource access type
|
||||
*/
|
||||
void release(DxvkAccess access) {
|
||||
if (access != DxvkAccess::None)
|
||||
m_useCount -= getIncrement(access);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<uint32_t> m_useCount = { 0u };
|
||||
|
||||
|
||||
static constexpr uint32_t getIncrement(DxvkAccess access) {
|
||||
return access == DxvkAccess::Write
|
||||
? UseCountIncrementW
|
||||
: UseCountIncrementR;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user