mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-14 09:23:53 +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
|
#pragma once
|
||||||
|
|
||||||
|
#include "../dxvk/dxvk_cs.h"
|
||||||
#include "../dxvk/dxvk_device.h"
|
#include "../dxvk/dxvk_device.h"
|
||||||
|
|
||||||
#include "../d3d10/d3d10_buffer.h"
|
#include "../d3d10/d3d10_buffer.h"
|
||||||
@ -117,6 +118,21 @@ namespace dxvk {
|
|||||||
return &m_d3d10;
|
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
|
* \brief Normalizes buffer description
|
||||||
*
|
*
|
||||||
@ -134,6 +150,7 @@ namespace dxvk {
|
|||||||
Rc<DxvkBuffer> m_buffer;
|
Rc<DxvkBuffer> m_buffer;
|
||||||
Rc<DxvkBuffer> m_soCounter;
|
Rc<DxvkBuffer> m_soCounter;
|
||||||
DxvkBufferSliceHandle m_mapped;
|
DxvkBufferSliceHandle m_mapped;
|
||||||
|
uint64_t m_seq = 0ull;
|
||||||
|
|
||||||
D3D11DXGIResource m_resource;
|
D3D11DXGIResource m_resource;
|
||||||
D3D10Buffer m_d3d10;
|
D3D10Buffer m_d3d10;
|
||||||
|
@ -473,6 +473,9 @@ namespace dxvk {
|
|||||||
cSrcSlice.offset(),
|
cSrcSlice.offset(),
|
||||||
sizeof(uint32_t));
|
sizeof(uint32_t));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (buf->HasSequenceNumber())
|
||||||
|
TrackBufferSequenceNumber(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1003,8 +1006,8 @@ namespace dxvk {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource);
|
D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource);
|
||||||
const D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource);
|
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 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);
|
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);
|
ctx->resolveImage(cDstImage, cSrcImage, region, cFormat);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dstTextureInfo->HasSequenceNumber())
|
||||||
|
TrackTextureSequenceNumber(dstTextureInfo, DstSubresource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3276,6 +3282,11 @@ namespace dxvk {
|
|||||||
cSrcBuffer.length());
|
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());
|
cBufferSlice.length());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pDstBuffer->HasSequenceNumber())
|
||||||
|
TrackBufferSequenceNumber(pDstBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3644,6 +3672,9 @@ namespace dxvk {
|
|||||||
DxvkBufferSlice StagingBuffer) {
|
DxvkBufferSlice StagingBuffer) {
|
||||||
bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING;
|
bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING;
|
||||||
|
|
||||||
|
uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel,
|
||||||
|
pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels);
|
||||||
|
|
||||||
if (dstIsImage) {
|
if (dstIsImage) {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstImage = pDstTexture->GetImage(),
|
cDstImage = pDstTexture->GetImage(),
|
||||||
@ -3675,9 +3706,6 @@ namespace dxvk {
|
|||||||
// format metadata, so deal with it manually here.
|
// format metadata, so deal with it manually here.
|
||||||
VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel);
|
VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel);
|
||||||
|
|
||||||
uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel,
|
|
||||||
pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels);
|
|
||||||
|
|
||||||
auto dstFormat = pDstTexture->GetPackedFormat();
|
auto dstFormat = pDstTexture->GetPackedFormat();
|
||||||
auto dstFormatInfo = imageFormatInfo(dstFormat);
|
auto dstFormatInfo = imageFormatInfo(dstFormat);
|
||||||
|
|
||||||
@ -3725,6 +3753,9 @@ namespace dxvk {
|
|||||||
srcPlaneOffset += util::flattenImageExtent(blockCount) * elementSize;
|
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 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(
|
DxvkCsChunkFlags D3D11DeferredContext::GetCsChunkFlags(
|
||||||
D3D11Device* pDevice) {
|
D3D11Device* pDevice) {
|
||||||
return pDevice->GetOptions()->dcSingleUseMode
|
return pDevice->GetOptions()->dcSingleUseMode
|
||||||
|
@ -134,6 +134,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
||||||
|
|
||||||
|
void TrackTextureSequenceNumber(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource);
|
||||||
|
|
||||||
|
void TrackBufferSequenceNumber(
|
||||||
|
D3D11Buffer* pResource);
|
||||||
|
|
||||||
static DxvkCsChunkFlags GetCsChunkFlags(
|
static DxvkCsChunkFlags GetCsChunkFlags(
|
||||||
D3D11Device* pDevice);
|
D3D11Device* pDevice);
|
||||||
|
|
||||||
|
@ -594,11 +594,24 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
||||||
m_csThread.dispatchChunk(std::move(chunk));
|
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
|
||||||
m_csIsBusy = true;
|
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) {
|
void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) {
|
||||||
// Flush only if the GPU is about to go idle, in
|
// Flush only if the GPU is about to go idle, in
|
||||||
// order to keep the number of submissions low.
|
// order to keep the number of submissions low.
|
||||||
|
@ -116,11 +116,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DxvkCsThread m_csThread;
|
DxvkCsThread m_csThread;
|
||||||
bool m_csIsBusy = false;
|
uint64_t m_csSeqNum = 0ull;
|
||||||
|
bool m_csIsBusy = false;
|
||||||
|
|
||||||
Rc<sync::CallbackFence> m_eventSignal;
|
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::time_point m_lastFlush
|
||||||
= dxvk::high_resolution_clock::now();
|
= dxvk::high_resolution_clock::now();
|
||||||
@ -161,6 +163,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
||||||
|
|
||||||
|
void TrackTextureSequenceNumber(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource);
|
||||||
|
|
||||||
|
void TrackBufferSequenceNumber(
|
||||||
|
D3D11Buffer* pResource);
|
||||||
|
|
||||||
void FlushImplicit(BOOL StrongHint);
|
void FlushImplicit(BOOL StrongHint);
|
||||||
|
|
||||||
void SignalEvent(HANDLE hEvent);
|
void SignalEvent(HANDLE hEvent);
|
||||||
|
@ -163,7 +163,7 @@ namespace dxvk {
|
|||||||
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
||||||
m_buffers.push_back(CreateMappedBuffer(j));
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include "../dxvk/dxvk_cs.h"
|
||||||
#include "../dxvk/dxvk_device.h"
|
#include "../dxvk/dxvk_device.h"
|
||||||
|
|
||||||
#include "../d3d10/d3d10_texture.h"
|
#include "../d3d10/d3d10_texture.h"
|
||||||
@ -164,8 +165,8 @@ namespace dxvk {
|
|||||||
* \returns Current map mode of that subresource
|
* \returns Current map mode of that subresource
|
||||||
*/
|
*/
|
||||||
D3D11_MAP GetMapType(UINT Subresource) const {
|
D3D11_MAP GetMapType(UINT Subresource) const {
|
||||||
return Subresource < m_mapTypes.size()
|
return Subresource < m_mapInfo.size()
|
||||||
? D3D11_MAP(m_mapTypes[Subresource])
|
? D3D11_MAP(m_mapInfo[Subresource].mapType)
|
||||||
: D3D11_MAP(~0u);
|
: D3D11_MAP(~0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +177,8 @@ namespace dxvk {
|
|||||||
* \param [in] MapType The map type
|
* \param [in] MapType The map type
|
||||||
*/
|
*/
|
||||||
void SetMapType(UINT Subresource, D3D11_MAP MapType) {
|
void SetMapType(UINT Subresource, D3D11_MAP MapType) {
|
||||||
if (Subresource < m_mapTypes.size())
|
if (Subresource < m_mapInfo.size())
|
||||||
m_mapTypes[Subresource] = MapType;
|
m_mapInfo[Subresource].mapType = MapType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -240,6 +241,56 @@ namespace dxvk {
|
|||||||
return m_packedFormat;
|
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
|
* \brief Computes pixel offset into mapped buffer
|
||||||
*
|
*
|
||||||
@ -327,6 +378,11 @@ namespace dxvk {
|
|||||||
DxvkBufferSliceHandle slice;
|
DxvkBufferSliceHandle slice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MappedInfo {
|
||||||
|
D3D11_MAP mapType;
|
||||||
|
uint64_t seq;
|
||||||
|
};
|
||||||
|
|
||||||
ID3D11Resource* m_interface;
|
ID3D11Resource* m_interface;
|
||||||
D3D11Device* m_device;
|
D3D11Device* m_device;
|
||||||
D3D11_RESOURCE_DIMENSION m_dimension;
|
D3D11_RESOURCE_DIMENSION m_dimension;
|
||||||
@ -337,7 +393,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkImage> m_image;
|
Rc<DxvkImage> m_image;
|
||||||
std::vector<MappedBuffer> m_buffers;
|
std::vector<MappedBuffer> m_buffers;
|
||||||
std::vector<D3D11_MAP> m_mapTypes;
|
std::vector<MappedInfo> m_mapInfo;
|
||||||
|
|
||||||
MappedBuffer CreateMappedBuffer(
|
MappedBuffer CreateMappedBuffer(
|
||||||
UINT MipLevel) const;
|
UINT MipLevel) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user