mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[d3d11] Track last staging resource usage with a sequence number
This commit is contained in:
parent
55a6b80919
commit
d33dac569c
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user