diff --git a/idd/LGIdd/CPostProcessor.cpp b/idd/LGIdd/CPostProcessor.cpp index 3d7f4eaf..9b61aa7d 100644 --- a/idd/LGIdd/CPostProcessor.cpp +++ b/idd/LGIdd/CPostProcessor.cpp @@ -351,15 +351,14 @@ bool CPostProcessor::ShouldCopyFully( m_copyEffect->ShouldCopyFully(dirtyRects, nbDirtyRects); } -void CPostProcessor::CopyFrame( +void CPostProcessor::CopyToCandidate( const ComPtr& commandList, - ID3D12Resource * dst, ID3D12Resource * src, - const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const + ID3D12Resource * dst, ID3D12Resource * src) const { if (m_copyEffect) { m_copyEffect->CopyFrame( - commandList, dst, src, dirtyRects, nbDirtyRects, fullCopy); + commandList, dst, src, nullptr, 0, true); return; } @@ -373,10 +372,36 @@ void CPostProcessor::CopyFrame( dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; dstLoc.PlacedFootprint = m_copyLayout; + commandList->CopyTextureRegion( + &dstLoc, 0, 0, 0, &srcLoc, nullptr); +} + +void CPostProcessor::CopyFromCandidate( + const ComPtr& commandList, + ID3D12Resource * dst, ID3D12Resource * src, + const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const +{ + if (m_copyEffect) + { + m_copyEffect->CopyFrame( + commandList, dst, src, dirtyRects, nbDirtyRects, fullCopy); + return; + } + + D3D12_TEXTURE_COPY_LOCATION srcLoc = {}; + srcLoc.pResource = src; + srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLoc.PlacedFootprint = m_copyLayout; + + D3D12_TEXTURE_COPY_LOCATION dstLoc = {}; + dstLoc.pResource = dst; + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dstLoc.PlacedFootprint = m_copyLayout; + if (fullCopy) { - commandList->CopyTextureRegion( - &dstLoc, 0, 0, 0, &srcLoc, nullptr); + commandList->CopyBufferRegion( + dst, 0, src, 0, m_frameSize); return; } diff --git a/idd/LGIdd/CPostProcessor.h b/idd/LGIdd/CPostProcessor.h index 2ad57778..52e933fa 100644 --- a/idd/LGIdd/CPostProcessor.h +++ b/idd/LGIdd/CPostProcessor.h @@ -183,7 +183,10 @@ public: size_t GetOutputSize () const { return m_frameSize; } bool ShouldCopyFully( const RECT dirtyRects[], unsigned nbDirtyRects) const; - void CopyFrame( + void CopyToCandidate( + const ComPtr& commandList, + ID3D12Resource * dst, ID3D12Resource * src) const; + void CopyFromCandidate( const ComPtr& commandList, ID3D12Resource * dst, ID3D12Resource * src, const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const; diff --git a/idd/LGIdd/CSwapChainProcessor.cpp b/idd/LGIdd/CSwapChainProcessor.cpp index a6dbd59a..7eadb79e 100644 --- a/idd/LGIdd/CSwapChainProcessor.cpp +++ b/idd/LGIdd/CSwapChainProcessor.cpp @@ -970,14 +970,23 @@ static bool ResourceDescMatches( } bool CSwapChainProcessor::EnsureCandidateResource( - unsigned candidateIndex, ID3D12Resource * source) + unsigned candidateIndex, size_t frameSize) { FrameCandidate& candidate = m_candidates[candidateIndex]; - D3D12_RESOURCE_DESC desc = source->GetDesc(); - desc.Alignment = 0; - desc.Flags = static_cast( - static_cast(desc.Flags) & - ~static_cast(D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER)); + + // Keep the transport layout in local GPU memory so publication does not + // combine texture detiling with the IVSHMEM or readback transfer. + D3D12_RESOURCE_DESC desc = {}; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Width = frameSize; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; if (candidate.resource && ResourceDescMatches(candidate.resource->GetDesc(), desc)) @@ -1178,7 +1187,7 @@ bool CSwapChainProcessor::PublishNewestCandidate( copySlot->SetCompletionCallback(&CompletionFunction, this, fbRes); copySlot->BeginTiming(); - postProcessor.CopyFrame( + postProcessor.CopyFromCandidate( copySlot->GetGfxList(), fbRes->Get().Get(), candidate.resource.Get(), copyDirtyRects, nbCopyDirtyRects, fullCopy); copySlot->EndTiming(); @@ -1682,7 +1691,8 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer ClipDirtyRects(currentDirtyRects, &nbDirtyRects, dstFormat.width, dstFormat.height); - if (!EnsureCandidateResource(candidateIndex, copySrcResource.Get())) + const size_t frameSize = postProcessor.GetOutputSize(); + if (!EnsureCandidateResource(candidateIndex, frameSize)) { copySlot->Cancel(); if (computeSlot) @@ -1696,7 +1706,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer candidate.dstFormat = dstFormat; candidate.nbDirtyRects = nbDirtyRects; candidate.pitch = postProcessor.GetOutputPitch(); - candidate.frameSize = postProcessor.GetOutputSize(); + candidate.frameSize = frameSize; candidate.captureTime = captureTime; candidate.postProcessStart = postProcessStart; candidate.prepareCopyStart = CFrameScheduler::Nanotime(); @@ -1714,26 +1724,9 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer copySlot->SetCompletionCallback( &CandidateCompletionFunction, this, &candidate); copySlot->BeginTiming(); - const D3D12_RESOURCE_DESC copySrcDesc = copySrcResource->GetDesc(); - if (copySrcDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - copySlot->GetGfxList()->CopyBufferRegion( - candidate.resource.Get(), 0, copySrcResource.Get(), 0, - copySrcDesc.Width); - else - { - D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; - srcLocation.pResource = copySrcResource.Get(); - srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - srcLocation.SubresourceIndex = 0; - - D3D12_TEXTURE_COPY_LOCATION dstLocation = {}; - dstLocation.pResource = candidate.resource.Get(); - dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLocation.SubresourceIndex = 0; - - copySlot->GetGfxList()->CopyTextureRegion( - &dstLocation, 0, 0, 0, &srcLocation, nullptr); - } + postProcessor.CopyToCandidate( + copySlot->GetGfxList(), candidate.resource.Get(), + copySrcResource.Get()); copySlot->EndTiming(); if (!copySlot->Execute()) diff --git a/idd/LGIdd/CSwapChainProcessor.h b/idd/LGIdd/CSwapChainProcessor.h index 18b4c659..45a44600 100644 --- a/idd/LGIdd/CSwapChainProcessor.h +++ b/idd/LGIdd/CSwapChainProcessor.h @@ -149,8 +149,8 @@ private: bool HasReadyCandidate(); int AcquireCandidate(bool exclusiveSample); void ReleaseCandidate(unsigned candidateIndex); - bool EnsureCandidateResource(unsigned candidateIndex, - ID3D12Resource * source); + bool EnsureCandidateResource( + unsigned candidateIndex, size_t frameSize); void ResetCandidates(); void SignalCandidateState();