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

This commit is contained in:
Philip Rebohle 2022-02-09 02:54:32 +01:00
parent 55a6b80919
commit d33dac569c
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
9 changed files with 168 additions and 15 deletions

View File

@ -1,5 +1,6 @@
#pragma once
#include "../dxvk/dxvk_cs.h"
#include "../dxvk/dxvk_device.h"
#include "../d3d10/d3d10_buffer.h"
@ -117,6 +118,21 @@ namespace dxvk {
return &m_d3d10;
}
bool HasSequenceNumber() const {
return m_mapMode != D3D11_COMMON_BUFFER_MAP_MODE_NONE
&& !(m_desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS)
&& !(m_desc.BindFlags);
}
void TrackSequenceNumber(uint64_t Seq) {
m_seq = Seq;
}
uint64_t GetSequenceNumber() {
return HasSequenceNumber() ? m_seq
: DxvkCsThread::SynchronizeAll;
}
/**
* \brief Normalizes buffer description
*
@ -134,6 +150,7 @@ namespace dxvk {
Rc<DxvkBuffer> m_buffer;
Rc<DxvkBuffer> m_soCounter;
DxvkBufferSliceHandle m_mapped;
uint64_t m_seq = 0ull;
D3D11DXGIResource m_resource;
D3D10Buffer m_d3d10;

View File

@ -473,6 +473,9 @@ namespace dxvk {
cSrcSlice.offset(),
sizeof(uint32_t));
});
if (buf->HasSequenceNumber())
TrackBufferSequenceNumber(buf);
}
@ -1003,8 +1006,8 @@ namespace dxvk {
return;
}
const D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource);
const D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource);
D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource);
D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource);
const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY);
const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY);
@ -1067,6 +1070,9 @@ namespace dxvk {
ctx->resolveImage(cDstImage, cSrcImage, region, cFormat);
});
}
if (dstTextureInfo->HasSequenceNumber())
TrackTextureSequenceNumber(dstTextureInfo, DstSubresource);
}
@ -3276,6 +3282,11 @@ namespace dxvk {
cSrcBuffer.length());
}
});
if (pDstBuffer->HasSequenceNumber())
TrackBufferSequenceNumber(pDstBuffer);
if (pSrcBuffer->HasSequenceNumber())
TrackBufferSequenceNumber(pSrcBuffer);
}
@ -3510,6 +3521,20 @@ namespace dxvk {
}
}
}
if (pDstTexture->HasSequenceNumber()) {
for (uint32_t i = 0; i < pDstLayers->layerCount; i++) {
TrackTextureSequenceNumber(pDstTexture, D3D11CalcSubresource(
pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels));
}
}
if (pSrcTexture->HasSequenceNumber()) {
for (uint32_t i = 0; i < pSrcLayers->layerCount; i++) {
TrackTextureSequenceNumber(pSrcTexture, D3D11CalcSubresource(
pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels));
}
}
}
@ -3580,6 +3605,9 @@ namespace dxvk {
cBufferSlice.length());
});
}
if (pDstBuffer->HasSequenceNumber())
TrackBufferSequenceNumber(pDstBuffer);
}
@ -3644,6 +3672,9 @@ namespace dxvk {
DxvkBufferSlice StagingBuffer) {
bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING;
uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel,
pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels);
if (dstIsImage) {
EmitCs([
cDstImage = pDstTexture->GetImage(),
@ -3675,9 +3706,6 @@ namespace dxvk {
// format metadata, so deal with it manually here.
VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel);
uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel,
pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels);
auto dstFormat = pDstTexture->GetPackedFormat();
auto dstFormatInfo = imageFormatInfo(dstFormat);
@ -3725,6 +3753,9 @@ namespace dxvk {
srcPlaneOffset += util::flattenImageExtent(blockCount) * elementSize;
}
}
if (pDstTexture->HasSequenceNumber())
TrackTextureSequenceNumber(pDstTexture, dstSubresource);
}

View File

@ -1070,6 +1070,13 @@ namespace dxvk {
virtual void EmitCsChunk(DxvkCsChunkRef&& chunk) = 0;
virtual void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource) = 0;
virtual void TrackBufferSequenceNumber(
D3D11Buffer* pResource) = 0;
};
}

View File

@ -420,6 +420,19 @@ namespace dxvk {
}
void D3D11DeferredContext::TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource) {
// TODO implement
}
void D3D11DeferredContext::TrackBufferSequenceNumber(
D3D11Buffer* pResource) {
// TODO implement
}
DxvkCsChunkFlags D3D11DeferredContext::GetCsChunkFlags(
D3D11Device* pDevice) {
return pDevice->GetOptions()->dcSingleUseMode

View File

@ -134,6 +134,13 @@ namespace dxvk {
void EmitCsChunk(DxvkCsChunkRef&& chunk);
void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource);
void TrackBufferSequenceNumber(
D3D11Buffer* pResource);
static DxvkCsChunkFlags GetCsChunkFlags(
D3D11Device* pDevice);

View File

@ -594,11 +594,24 @@ namespace dxvk {
void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_csThread.dispatchChunk(std::move(chunk));
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
m_csIsBusy = true;
}
void D3D11ImmediateContext::TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource) {
pResource->TrackSequenceNumber(Subresource, m_csSeqNum + 1);
}
void D3D11ImmediateContext::TrackBufferSequenceNumber(
D3D11Buffer* pResource) {
pResource->TrackSequenceNumber(m_csSeqNum + 1);
}
void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) {
// Flush only if the GPU is about to go idle, in
// order to keep the number of submissions low.

View File

@ -116,11 +116,13 @@ namespace dxvk {
private:
DxvkCsThread m_csThread;
bool m_csIsBusy = false;
DxvkCsThread m_csThread;
uint64_t m_csSeqNum = 0ull;
bool m_csIsBusy = false;
Rc<sync::CallbackFence> m_eventSignal;
uint64_t m_eventCount = 0;
uint64_t m_eventCount = 0ull;
dxvk::high_resolution_clock::time_point m_lastFlush
= dxvk::high_resolution_clock::now();
@ -161,6 +163,13 @@ namespace dxvk {
void EmitCsChunk(DxvkCsChunkRef&& chunk);
void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource);
void TrackBufferSequenceNumber(
D3D11Buffer* pResource);
void FlushImplicit(BOOL StrongHint);
void SignalEvent(HANDLE hEvent);

View File

@ -163,7 +163,7 @@ namespace dxvk {
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
m_buffers.push_back(CreateMappedBuffer(j));
m_mapTypes.push_back(D3D11_MAP(~0u));
m_mapInfo.push_back({ D3D11_MAP(~0u), 0ull });
}
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "../dxvk/dxvk_cs.h"
#include "../dxvk/dxvk_device.h"
#include "../d3d10/d3d10_texture.h"
@ -164,8 +165,8 @@ namespace dxvk {
* \returns Current map mode of that subresource
*/
D3D11_MAP GetMapType(UINT Subresource) const {
return Subresource < m_mapTypes.size()
? D3D11_MAP(m_mapTypes[Subresource])
return Subresource < m_mapInfo.size()
? D3D11_MAP(m_mapInfo[Subresource].mapType)
: D3D11_MAP(~0u);
}
@ -176,8 +177,8 @@ namespace dxvk {
* \param [in] MapType The map type
*/
void SetMapType(UINT Subresource, D3D11_MAP MapType) {
if (Subresource < m_mapTypes.size())
m_mapTypes[Subresource] = MapType;
if (Subresource < m_mapInfo.size())
m_mapInfo[Subresource].mapType = MapType;
}
/**
@ -240,6 +241,56 @@ namespace dxvk {
return m_packedFormat;
}
/**
* \brief Checks whether the resource is eligible for tracking
*
* Mapped resources with no bind flags can be tracked so that
* mapping them will not necessarily cause a CS thread sync.
* \returns \c true if tracking is supported for this resource
*/
bool HasSequenceNumber() const {
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)
return false;
// For buffer-mapped images we only need to track copies to
// and from that buffer, so we can safely ignore bind flags
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)
return true;
// Otherwise we can only do accurate tracking if the
// image cannot be used in the rendering pipeline.
return m_desc.BindFlags == 0;
}
/**
* \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 TrackSequenceNumber(UINT Subresource, uint64_t Seq) {
if (Subresource < m_mapInfo.size())
m_mapInfo[Subresource].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 GetSequenceNumber(UINT Subresource) {
if (HasSequenceNumber()) {
return Subresource < m_buffers.size()
? m_mapInfo[Subresource].seq
: 0ull;
} else {
return DxvkCsThread::SynchronizeAll;
}
}
/**
* \brief Computes pixel offset into mapped buffer
*
@ -327,6 +378,11 @@ namespace dxvk {
DxvkBufferSliceHandle slice;
};
struct MappedInfo {
D3D11_MAP mapType;
uint64_t seq;
};
ID3D11Resource* m_interface;
D3D11Device* m_device;
D3D11_RESOURCE_DIMENSION m_dimension;
@ -337,7 +393,7 @@ namespace dxvk {
Rc<DxvkImage> m_image;
std::vector<MappedBuffer> m_buffers;
std::vector<D3D11_MAP> m_mapTypes;
std::vector<MappedInfo> m_mapInfo;
MappedBuffer CreateMappedBuffer(
UINT MipLevel) const;