[idd] transport: add frame sink boundary

This commit is contained in:
Geoffrey McRae
2026-08-12 16:45:01 +10:00
parent 801a1e58f8
commit bd4d31f0bd
21 changed files with 634 additions and 81 deletions

View File

@@ -39,11 +39,11 @@ void CFrameBufferPool::Reset()
CFrameBufferResource * CFrameBufferPool::Get(
const PreparedFrameBuffer& buffer, size_t minSize)
{
if (buffer.frameIndex > ARRAYSIZE(m_buffers) - 1)
if (buffer.resourceSlot > ARRAYSIZE(m_buffers) - 1)
return nullptr;
CFrameBufferResource * fbr = &m_buffers[buffer.frameIndex];
if (!fbr->Init(m_dx12, buffer.frameIndex, buffer.mem,
CFrameBufferResource * fbr = &m_buffers[buffer.resourceSlot];
if (!fbr->Init(m_dx12, buffer.token, buffer.mem,
buffer.heapOffset, minSize, m_transport->GetMaxFrameSize()))
return nullptr;

View File

@@ -25,11 +25,9 @@
#include <cstring>
bool CFrameBufferResource::Init(CD3D12Device * dx12,
unsigned frameIndex, uint8_t * base, uint64_t heapOffset, size_t size,
const FrameToken& token, uint8_t * base, uint64_t heapOffset, size_t size,
size_t maxFrameSize)
{
m_frameIndex = frameIndex;
if (size > maxFrameSize)
{
DEBUG_ERROR("Frame size of %llu is too large for transport memory",
@@ -59,6 +57,7 @@ bool CFrameBufferResource::Init(CD3D12Device * dx12,
// Nothing to do if the resource already represents this allocation.
if (m_base == base && m_size >= size)
{
m_token = token;
m_frameSize = size;
return true;
}
@@ -137,6 +136,7 @@ bool CFrameBufferResource::Init(CD3D12Device * dx12,
m_res->SetName(resName);
m_token = token;
m_base = base;
m_size = size;
m_frameSize = size;
@@ -151,6 +151,7 @@ void CFrameBufferResource::Reset()
m_map = NULL;
}
m_token = {};
m_base = nullptr;
m_size = 0;
m_frameSize = 0;

View File

@@ -29,6 +29,7 @@
#include "capture/CFrameScheduler.h"
#include "d3d/CInteropResource.h"
#include "transport/PreparedFrameBuffer.h"
struct CD3D12Device;
@@ -37,7 +38,7 @@ using namespace Microsoft::WRL;
class CFrameBufferResource
{
private:
unsigned m_frameIndex = 0;
FrameToken m_token = {};
uint8_t * m_base = nullptr;
size_t m_size = 0;
size_t m_frameSize = 0;
@@ -60,13 +61,13 @@ class CFrameBufferResource
void * m_map = nullptr;
public:
bool Init(CD3D12Device * dx12, unsigned frameIndex, uint8_t * base,
bool Init(CD3D12Device * dx12, const FrameToken& token, uint8_t * base,
uint64_t heapOffset, size_t size, size_t maxFrameSize);
void Reset();
unsigned GetFrameIndex() { return m_frameIndex; }
size_t GetFrameSize() { return m_frameSize; }
void * GetMap() { return m_map; }
const FrameToken& GetToken() const { return m_token; }
size_t GetFrameSize() { return m_frameSize; }
void * GetMap() { return m_map; }
void SetTiming(uint64_t captureTime, uint64_t postProcessStart,
uint64_t copyStart)

View File

@@ -346,7 +346,7 @@ void CHardwareFrameProcessor::CompletionFunction(
if (!result)
{
processor->m_transport->FailFrameBuffer(fbRes->GetFrameIndex());
processor->m_transport->FailFrameBuffer(fbRes->GetToken());
processor->SetFullDamage();
processor->m_transport->ForceFrame();
processor->ReleaseCandidate(candidateIndex);
@@ -379,7 +379,7 @@ void CHardwareFrameProcessor::CompletionFunction(
{
const uint64_t indirectCopyStart = CFrameScheduler::Nanotime();
processor->m_transport->WriteFrameBuffer(
fbRes->GetFrameIndex(), fbRes->GetMap(), 0,
fbRes->GetToken(), fbRes->GetMap(), 0,
fbRes->GetFrameSize(), false);
indirectCopyTime = CFrameScheduler::Nanotime() - indirectCopyStart;
}
@@ -405,7 +405,7 @@ void CHardwareFrameProcessor::CompletionFunction(
const uint64_t copyTime = prepareCopyTime + publishCopyTime;
processor->m_transport->FinalizeFrameBuffer(fbRes->GetFrameIndex());
processor->m_transport->FinalizeFrameBuffer(fbRes->GetToken());
const uint64_t publishedAt = CFrameScheduler::Nanotime();
const uint64_t prepareElapsed = prepareReady >= postProcessStart ?
prepareReady - postProcessStart : 0;
@@ -420,10 +420,11 @@ void CHardwareFrameProcessor::CompletionFunction(
const uint64_t holdTime = publishStart >= prepareReady ?
publishStart - prepareReady : 0;
processor->m_transport->SetFrameTiming(fbRes->GetFrameIndex(),
processor->m_transport->SetFrameTiming(fbRes->GetToken(),
fbRes->GetCaptureTime(), postProcessTime, copyTime, readyTime, holdTime,
fbRes->GetSchedule(), publishedAt);
processor->m_transport->TryRecordFrameTiming(publishedAt - publishStart);
processor->m_transport->TryRecordFrameTiming(
fbRes->GetToken(), publishedAt - publishStart);
const uint64_t timingToken = fbRes->GetTimingToken();
if (timingToken && timingStart && prepareReady >= timingStart &&
@@ -436,7 +437,7 @@ void CHardwareFrameProcessor::CompletionFunction(
fbRes->IsFullCopy(), totalTime);
}
processor->m_transport->CompleteFrameBuffer(fbRes->GetFrameIndex(), true);
processor->m_transport->CompleteFrameBuffer(fbRes->GetToken(), true);
processor->ReleaseCandidate(candidateIndex);
}
@@ -512,7 +513,7 @@ bool CHardwareFrameProcessor::Publish(
m_frameBuffers.Get(buffer, candidate.frameSize);
if (!fbRes)
{
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
restoreCandidate();
DEBUG_ERROR("Failed to get a CFrameBufferResource from the pool");
SetFullDamage();
@@ -522,7 +523,7 @@ bool CHardwareFrameProcessor::Publish(
CD3D12CommandSlot * copySlot = m_dx12->GetCopySlot(candidateIndex);
if (!copySlot)
{
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
restoreCandidate();
DEBUG_ERROR("Failed to get a copy CommandSlot for publication");
SetFullDamage();
@@ -557,16 +558,16 @@ bool CHardwareFrameProcessor::Publish(
bool deliveredToOwner;
if (!m_transport->PublishFrameBuffer(
buffer.frameIndex, schedule, deliveredToOwner))
buffer.token, schedule, deliveredToOwner))
{
copySlot->Cancel();
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
restoreCandidate();
return false;
}
CFrameScheduler::Schedule frameSchedule = schedule;
if (!deliveredToOwner ||
!m_transport->TryFrameSubmitted(buffer.frameIndex, schedule))
!m_transport->TryFrameSubmitted(buffer.token, schedule))
frameSchedule.phaseEligible = false;
fbRes->SetSchedule(frameSchedule);
@@ -601,7 +602,7 @@ bool CHardwareFrameProcessor::Publish(
}
if (callbackPending && !copySlot->HasSubmittedWork())
{
m_transport->FailFrameBuffer(buffer.frameIndex);
m_transport->FailFrameBuffer(buffer.token);
ReleaseCandidate(candidateIndex);
}
m_transport->ForceFrame();
@@ -610,7 +611,7 @@ bool CHardwareFrameProcessor::Publish(
}
m_transport->CommitFrameBuffer(
buffer.frameIndex, schedule, periodic, deliveredToOwner);
buffer.token, schedule, periodic, deliveredToOwner);
unsigned superseded = 0;
{

View File

@@ -45,7 +45,7 @@ void CSoftwareFrameProcessor::CompletionFunction(
if (!result)
{
processor->m_transport->FailFrameBuffer(fbRes->GetFrameIndex());
processor->m_transport->FailFrameBuffer(fbRes->GetToken());
processor->SetFullDamage();
processor->m_transport->ForceFrame();
return;
@@ -56,7 +56,7 @@ void CSoftwareFrameProcessor::CompletionFunction(
{
const uint64_t indirectCopyStart = CFrameScheduler::Nanotime();
if (fbRes->IsFullCopy())
processor->m_transport->WriteFrameBuffer(fbRes->GetFrameIndex(),
processor->m_transport->WriteFrameBuffer(fbRes->GetToken(),
fbRes->GetMap(), 0, fbRes->GetFrameSize(), false);
else
{
@@ -71,7 +71,7 @@ void CSoftwareFrameProcessor::CompletionFunction(
(size_t)rect->left * bytesPerPixel;
const size_t rowBytes =
(size_t)(rect->right - rect->left) * bytesPerPixel;
processor->m_transport->WriteFrameBufferRows(fbRes->GetFrameIndex(),
processor->m_transport->WriteFrameBufferRows(fbRes->GetToken(),
fbRes->GetMap(), rowOffset, rowBytes, pitch,
(unsigned)(rect->bottom - rect->top));
}
@@ -84,7 +84,7 @@ void CSoftwareFrameProcessor::CompletionFunction(
const uint64_t copyReady = CFrameScheduler::Nanotime();
const bool gpuTimingValid = slot->GetGPUTimes(gpuStart, gpuEnd);
processor->m_transport->FinalizeFrameBuffer(fbRes->GetFrameIndex());
processor->m_transport->FinalizeFrameBuffer(fbRes->GetToken());
const uint64_t publishedAt = CFrameScheduler::Nanotime();
const uint64_t postProcessStart = fbRes->GetPostProcessStart();
const uint64_t copyStart = fbRes->GetCopyStart();
@@ -104,10 +104,10 @@ void CSoftwareFrameProcessor::CompletionFunction(
const uint64_t measured = postProcessTime + copyTime;
const uint64_t readyTime = elapsed > measured ? elapsed - measured : 0;
processor->m_transport->SetFrameTiming(fbRes->GetFrameIndex(),
processor->m_transport->SetFrameTiming(fbRes->GetToken(),
fbRes->GetCaptureTime(), postProcessTime, copyTime, readyTime, 0,
fbRes->GetSchedule(), publishedAt);
processor->m_transport->CompleteFrameBuffer(fbRes->GetFrameIndex(), true);
processor->m_transport->CompleteFrameBuffer(fbRes->GetToken(), true);
}
bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
@@ -209,7 +209,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
if (!fbRes)
{
copySlot->Cancel();
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
RestorePendingDamage(
currentDirtyRects, nbDirtyRects, hasDamage);
DEBUG_ERROR("Failed to get a framebuffer for software capture");
@@ -221,7 +221,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
!submission.source->Sync(*copySlot))
{
copySlot->Cancel();
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
RestorePendingDamage(
currentDirtyRects, nbDirtyRects, hasDamage);
SetFullDamage();
@@ -260,10 +260,10 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
bool deliveredToOwner;
if (!m_transport->PublishFrameBuffer(
buffer.frameIndex, deliverySchedule, deliveredToOwner))
buffer.token, deliverySchedule, deliveredToOwner))
{
copySlot->Cancel();
m_transport->AbortFrameBuffer(buffer.frameIndex);
m_transport->AbortFrameBuffer(buffer.token);
RestorePendingDamage(
currentDirtyRects, nbDirtyRects, hasDamage);
if (!submission.noImageUpdate)
@@ -283,7 +283,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
const bool submittedWork = copySlot->HasSubmittedWork();
const bool completionHandled = fbRes->CompletionHandled();
if (!submittedWork && !completionHandled)
m_transport->FailFrameBuffer(buffer.frameIndex);
m_transport->FailFrameBuffer(buffer.token);
RestorePendingDamage(
currentDirtyRects, nbDirtyRects, hasDamage);
if (!submittedWork && !completionHandled)
@@ -295,7 +295,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
}
m_transport->CommitFrameBuffer(
buffer.frameIndex, commitSchedule, false, deliveredToOwner);
buffer.token, commitSchedule, false, deliveredToOwner);
return true;
}
}