1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 20:52:10 +01:00

[d3d9] Track last staging resource usage with a sequence number

This commit is contained in:
Robin Kertels 2022-02-12 21:25:29 +01:00 committed by Joshie
parent c12cd1952c
commit 917a8d00a2
4 changed files with 86 additions and 1 deletions

View File

@ -187,6 +187,28 @@ namespace dxvk {
void PreLoad();
/**
* \brief Tracks sequence number
*
* Stores which CS chunk the resource was last used on.
* \param [in] Seq Sequence number
*/
void TrackMappingBufferSequenceNumber(uint64_t Seq) {
m_seq = Seq;
}
/**
* \brief Queries sequence number for a given subresource
*
* Returns which CS chunk the resource was last used on.
* \param [in] Subresource Subresource index
* \returns Sequence number for the given subresource
*/
uint64_t GetMappingBufferSequenceNumber() const {
return m_seq;
}
private:
Rc<DxvkBuffer> CreateBuffer() const;
@ -220,6 +242,8 @@ namespace dxvk {
uint32_t m_lockCount = 0;
uint64_t m_seq = 0ull;
};
}

View File

@ -435,6 +435,31 @@ namespace dxvk {
static VkImageType GetImageTypeFromResourceType(
D3DRESOURCETYPE Dimension);
/**
* \brief Tracks sequence number for a given subresource
*
* Stores which CS chunk the resource was last used on.
* \param [in] Subresource Subresource index
* \param [in] Seq Sequence number
*/
void TrackMappingBufferSequenceNumber(UINT Subresource, uint64_t Seq) {
if (Subresource < m_seqs.size())
m_seqs[Subresource] = Seq;
}
/**
* \brief Queries sequence number for a given subresource
*
* Returns which CS chunk the resource was last used on.
* \param [in] Subresource Subresource index
* \returns Sequence number for the given subresource
*/
uint64_t GetMappingBufferSequenceNumber(UINT Subresource) {
return Subresource < m_seqs.size()
? m_seqs[Subresource]
: 0ull;
}
private:
D3D9DeviceEx* m_device;
@ -448,6 +473,8 @@ namespace dxvk {
Rc<DxvkBuffer>> m_buffers;
D3D9SubresourceArray<
DxvkBufferSliceHandle> m_mappedSlices;
D3D9SubresourceArray<
uint64_t> m_seqs = { };
D3D9_VK_FORMAT_MAPPING m_mapping;

View File

@ -926,6 +926,7 @@ namespace dxvk {
});
dstTexInfo->SetWrittenByGPU(dst->GetSubresource(), true);
TrackTextureMappingBufferSequenceNumber(dstTexInfo, dst->GetSubresource());
return D3D_OK;
}
@ -2694,6 +2695,7 @@ namespace dxvk {
}
dst->SetWrittenByGPU(true);
TrackBufferMappingBufferSequenceNumber(dst);
return D3D_OK;
}
@ -4545,6 +4547,8 @@ namespace dxvk {
if (pResource->IsAutomaticMip())
MarkTextureMipsDirty(pResource);
TrackTextureMappingBufferSequenceNumber(pResource, Subresource);
return D3D_OK;
}
@ -4745,7 +4749,7 @@ namespace dxvk {
void D3D9DeviceEx::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_csThread.dispatchChunk(std::move(chunk));
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
m_csIsBusy = true;
}
@ -7349,4 +7353,24 @@ namespace dxvk {
return D3D_OK;
}
void D3D9DeviceEx::TrackBufferMappingBufferSequenceNumber(
D3D9CommonBuffer* pResource) {
uint64_t sequenceNumber = GetCurrentSequenceNumber();
pResource->TrackMappingBufferSequenceNumber(sequenceNumber);
}
void D3D9DeviceEx::TrackTextureMappingBufferSequenceNumber(
D3D9CommonTexture* pResource,
UINT Subresource) {
uint64_t sequenceNumber = GetCurrentSequenceNumber();
pResource->TrackMappingBufferSequenceNumber(Subresource, sequenceNumber);
}
uint64_t D3D9DeviceEx::GetCurrentSequenceNumber() {
// We do not flush empty chunks, so if we are tracking a resource
// immediately after a flush, we need to use the sequence number
// of the previously submitted chunk to prevent deadlocks.
return m_csChunk->empty() ? m_csSeqNum : m_csSeqNum + 1;
}
}

View File

@ -1120,6 +1120,15 @@ namespace dxvk {
void UpdateSamplerDepthModeSpecConstant(uint32_t value);
void TrackBufferMappingBufferSequenceNumber(
D3D9CommonBuffer* pResource);
void TrackTextureMappingBufferSequenceNumber(
D3D9CommonTexture* pResource,
UINT Subresource);
uint64_t GetCurrentSequenceNumber();
Com<D3D9InterfaceEx> m_parent;
D3DDEVTYPE m_deviceType;
HWND m_window;
@ -1242,6 +1251,7 @@ namespace dxvk {
= dxvk::high_resolution_clock::now();
DxvkCsThread m_csThread;
DxvkCsChunkRef m_csChunk;
uint64_t m_csSeqNum = 0ull;
bool m_csIsBusy = false;
std::atomic<int64_t> m_availableMemory = { 0 };