mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 08:41:31 +00:00
[idd] transport: abstract LGMP implementation
Introduce transport, frame, and control interfaces with an LGMP factory backend. Move LGMP and IVSHMEM implementation details under transport/lgmp and expose direct frame-buffer memory through a neutral capability.
This commit is contained in:
@@ -19,11 +19,12 @@
|
||||
*/
|
||||
|
||||
#include "capture/CFrameBufferPool.h"
|
||||
#include "transport/IFrameTransport.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void CFrameBufferPool::Init(
|
||||
CFrameTransport * transport, CD3D12Device * dx12)
|
||||
IFrameTransport * transport, CD3D12Device * dx12)
|
||||
{
|
||||
m_transport = transport;
|
||||
m_dx12 = dx12;
|
||||
@@ -43,8 +44,9 @@ CFrameBufferResource * CFrameBufferPool::Get(
|
||||
return nullptr;
|
||||
|
||||
CFrameBufferResource * fbr = &m_buffers[buffer.frameIndex];
|
||||
if (!fbr->Init(m_transport, m_dx12, buffer.frameIndex, buffer.mem,
|
||||
minSize, textureDesc))
|
||||
if (!fbr->Init(m_dx12, buffer.frameIndex, buffer.mem,
|
||||
buffer.heapOffset, minSize, m_transport->GetMaxFrameSize(),
|
||||
textureDesc))
|
||||
return nullptr;
|
||||
|
||||
return fbr;
|
||||
|
||||
@@ -21,22 +21,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "capture/CFrameBufferResource.h"
|
||||
#include "capture/FrameBufferTypes.h"
|
||||
#include "common/KVMFR.h"
|
||||
#include "transport/FrameBufferTypes.h"
|
||||
#include "transport/TransportTypes.h"
|
||||
|
||||
struct CD3D12Device;
|
||||
class CFrameTransport;
|
||||
class IFrameTransport;
|
||||
|
||||
class CFrameBufferPool
|
||||
{
|
||||
private:
|
||||
CFrameTransport * m_transport = nullptr;
|
||||
IFrameTransport * m_transport = nullptr;
|
||||
CD3D12Device * m_dx12 = nullptr;
|
||||
|
||||
CFrameBufferResource m_buffers[LGMP_Q_FRAME_BUFFER_LEN];
|
||||
CFrameBufferResource m_buffers[TRANSPORT_FRAME_BUFFER_COUNT];
|
||||
|
||||
public:
|
||||
void Init(CFrameTransport * transport, CD3D12Device * dx12);
|
||||
void Init(IFrameTransport * transport, CD3D12Device * dx12);
|
||||
void Reset();
|
||||
|
||||
CFrameBufferResource * Get(const PreparedFrameBuffer& buffer,
|
||||
|
||||
@@ -21,21 +21,19 @@
|
||||
#include "capture/CFrameBufferResource.h"
|
||||
#include "capture/CFrameProcessorUtil.h"
|
||||
#include "d3d/CD3D12Device.h"
|
||||
#include "transport/CFrameTransport.h"
|
||||
#include "transport/CIVSHMEM.h"
|
||||
#include "CDebug.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
bool CFrameBufferResource::Init(CFrameTransport * transport,
|
||||
CD3D12Device * dx12, unsigned frameIndex, uint8_t * base, size_t size,
|
||||
const D3D12_RESOURCE_DESC * textureDesc)
|
||||
bool CFrameBufferResource::Init(CD3D12Device * dx12,
|
||||
unsigned frameIndex, uint8_t * base, uint64_t heapOffset, size_t size,
|
||||
size_t maxFrameSize, const D3D12_RESOURCE_DESC * textureDesc)
|
||||
{
|
||||
m_frameIndex = frameIndex;
|
||||
|
||||
if (size > transport->GetMaxFrameSize())
|
||||
if (size > maxFrameSize)
|
||||
{
|
||||
DEBUG_ERROR("Frame size of %llu is too large to fit in shared ram",
|
||||
DEBUG_ERROR("Frame size of %llu is too large for transport memory",
|
||||
(unsigned long long)size);
|
||||
return false;
|
||||
}
|
||||
@@ -47,7 +45,7 @@ bool CFrameBufferResource::Init(CFrameTransport * transport,
|
||||
D3D12_RESOURCE_DESC desc = {};
|
||||
if (textureDesc)
|
||||
{
|
||||
if (indirect || !dx12->CanUseIVSHMEMTexture())
|
||||
if (indirect || !dx12->CanUseDirectTexture())
|
||||
return false;
|
||||
desc = *textureDesc;
|
||||
if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D ||
|
||||
@@ -130,20 +128,19 @@ bool CFrameBufferResource::Init(CFrameTransport * transport,
|
||||
}
|
||||
else
|
||||
{
|
||||
const UINT64 heapOffset =
|
||||
(uintptr_t)base -
|
||||
(uintptr_t)transport->GetIVSHMEM().GetMem();
|
||||
const D3D12_RESOURCE_ALLOCATION_INFO allocation =
|
||||
dx12->GetDevice()->GetResourceAllocationInfo(0, 1, &desc);
|
||||
allocationSize = allocation.SizeInBytes;
|
||||
const D3D12_HEAP_DESC heapDesc = dx12->GetHeap()->GetDesc();
|
||||
const D3D12_HEAP_DESC heapDesc =
|
||||
dx12->GetTransportHeap()->GetDesc();
|
||||
if (!allocation.Alignment ||
|
||||
heapOffset % allocation.Alignment ||
|
||||
allocation.SizeInBytes > transport->GetMaxFrameSize() ||
|
||||
allocation.SizeInBytes > maxFrameSize ||
|
||||
heapOffset > heapDesc.SizeInBytes ||
|
||||
allocation.SizeInBytes > heapDesc.SizeInBytes - heapOffset)
|
||||
{
|
||||
DEBUG_ERROR("IVSHMEM resource does not fit its framebuffer allocation");
|
||||
DEBUG_ERROR(
|
||||
"Transport resource does not fit its framebuffer allocation");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,20 +153,20 @@ bool CFrameBufferResource::Init(CFrameTransport * transport,
|
||||
if (FAILED(hr) ||
|
||||
!(support.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D))
|
||||
{
|
||||
DEBUG_ERROR("IVSHMEM texture format is unsupported");
|
||||
DEBUG_ERROR("Transport texture format is unsupported");
|
||||
return false;
|
||||
}
|
||||
DEBUG_TRACE("Creating IVSHMEM texture for %p", base);
|
||||
resName = L"IVSHMEM Texture";
|
||||
DEBUG_TRACE("Creating transport texture for %p", base);
|
||||
resName = L"Transport Texture";
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_TRACE("Creating IVSHMEM buffer for %p", base);
|
||||
resName = L"IVSHMEM";
|
||||
DEBUG_TRACE("Creating transport buffer for %p", base);
|
||||
resName = L"Transport Buffer";
|
||||
}
|
||||
|
||||
hr = dx12->GetDevice()->CreatePlacedResource(
|
||||
dx12->GetHeap().Get(),
|
||||
dx12->GetTransportHeap().Get(),
|
||||
heapOffset,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "capture/CFrameScheduler.h"
|
||||
#include "transport/CFrameScheduler.h"
|
||||
#include "d3d/CInteropResource.h"
|
||||
|
||||
struct CD3D12Device;
|
||||
class CFrameTransport;
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
@@ -70,8 +69,8 @@ class CFrameBufferResource
|
||||
void * m_map = nullptr;
|
||||
|
||||
public:
|
||||
bool Init(CFrameTransport * transport, CD3D12Device * dx12,
|
||||
unsigned frameIndex, uint8_t * base, size_t size,
|
||||
bool Init(CD3D12Device * dx12, unsigned frameIndex, uint8_t * base,
|
||||
uint64_t heapOffset, size_t size, size_t maxFrameSize,
|
||||
const D3D12_RESOURCE_DESC * textureDesc = nullptr);
|
||||
void Reset();
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
CFrameProcessor::CFrameProcessor(CFrameTransport * transport,
|
||||
CFrameProcessor::CFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
m_transport(transport),
|
||||
m_dx12(std::move(dx12)),
|
||||
@@ -154,9 +154,9 @@ void CFrameProcessor::GetPreviousDamage(
|
||||
}
|
||||
|
||||
std::unique_ptr<CFrameProcessor> CreateFrameProcessor(
|
||||
bool software, CFrameTransport * transport,
|
||||
bool software, IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent)
|
||||
{
|
||||
std::unique_ptr<CFrameProcessor> processor;
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
#include "capture/CFrameBufferPool.h"
|
||||
#include "d3d/CInteropResource.h"
|
||||
#include "postprocess/CPostProcessor.h"
|
||||
#include "transport/CFrameScheduler.h"
|
||||
#include "transport/TransportTypes.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <memory>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
class CFrameTransport;
|
||||
class IFrameTransport;
|
||||
|
||||
struct FrameSubmission
|
||||
{
|
||||
@@ -46,7 +48,7 @@ struct FrameSubmission
|
||||
class CFrameProcessor
|
||||
{
|
||||
protected:
|
||||
CFrameTransport * m_transport;
|
||||
IFrameTransport * m_transport;
|
||||
std::shared_ptr<CD3D12Device> m_dx12;
|
||||
CPostProcessor * m_postProcessors;
|
||||
SRWLOCK * m_pipelineLock;
|
||||
@@ -72,9 +74,9 @@ protected:
|
||||
virtual void SetFullDamageLocked();
|
||||
|
||||
public:
|
||||
CFrameProcessor(CFrameTransport * transport,
|
||||
CFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
virtual ~CFrameProcessor() = default;
|
||||
|
||||
@@ -94,7 +96,7 @@ public:
|
||||
};
|
||||
|
||||
std::unique_ptr<CFrameProcessor> CreateFrameProcessor(
|
||||
bool software, CFrameTransport * transport,
|
||||
bool software, IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
#include <lgmp/lgmp.h>
|
||||
}
|
||||
|
||||
#include "common/KVMFR.h"
|
||||
|
||||
class CFrameScheduler
|
||||
{
|
||||
public:
|
||||
struct Schedule
|
||||
{
|
||||
uint32_t clientID;
|
||||
uint32_t generation;
|
||||
uint32_t epoch;
|
||||
uint64_t period;
|
||||
uint64_t targetSlack;
|
||||
uint64_t deadline;
|
||||
uint64_t forceTicket;
|
||||
uint64_t republishTicket;
|
||||
uint32_t deadlineSerial;
|
||||
uint32_t deliveryDeadlineSerial;
|
||||
bool phaseEligible;
|
||||
};
|
||||
|
||||
private:
|
||||
struct Client
|
||||
{
|
||||
uint32_t clientID;
|
||||
uint32_t generation;
|
||||
uint64_t period;
|
||||
uint64_t targetSlack;
|
||||
uint64_t expiry;
|
||||
uint64_t nextDelivery;
|
||||
uint32_t lastFeedbackDeadlineSerial;
|
||||
uint32_t lastDeliveredFrameSerial;
|
||||
bool subscribed;
|
||||
bool ownerCapable;
|
||||
bool subscriptionSeen;
|
||||
bool active;
|
||||
bool immediate;
|
||||
bool deliveredFrameValid;
|
||||
};
|
||||
|
||||
struct Publication
|
||||
{
|
||||
uint32_t generation;
|
||||
uint32_t epoch;
|
||||
uint32_t deadlineSerial;
|
||||
uint32_t frameSerial;
|
||||
uint64_t deadline;
|
||||
bool committed;
|
||||
bool completed;
|
||||
bool phaseValid;
|
||||
bool accepted;
|
||||
};
|
||||
|
||||
static const unsigned PUBLICATION_HISTORY_SIZE = 128;
|
||||
static const unsigned WORK_TIMING_HISTORY_SIZE = 32;
|
||||
|
||||
mutable SRWLOCK m_lock = SRWLOCK_INIT;
|
||||
HANDLE m_wakeEvent = nullptr;
|
||||
Client m_clients[LGMP_MAX_CLIENTS] = {};
|
||||
Schedule m_schedule = {};
|
||||
bool m_scheduling = false;
|
||||
uint32_t m_epoch = 0;
|
||||
|
||||
// A result acknowledges only the request tickets captured by its attempt.
|
||||
uint64_t m_forceRequestTicket = 0;
|
||||
uint64_t m_forceAckTicket = 0;
|
||||
uint64_t m_republishRequestTicket = 0;
|
||||
uint64_t m_republishAckTicket = 0;
|
||||
|
||||
uint64_t m_lastArrival = 0;
|
||||
uint64_t m_guestPeriod = 0;
|
||||
uint64_t m_workEstimate = 0;
|
||||
uint64_t m_workTiming[WORK_TIMING_HISTORY_SIZE] = {};
|
||||
unsigned m_workTimingCount = 0;
|
||||
unsigned m_workTimingIndex = 0;
|
||||
uint64_t m_nextDeadline = 0;
|
||||
uint32_t m_deadlineSerial = 0;
|
||||
int64_t m_pendingCorrection = 0;
|
||||
|
||||
Publication m_publications[PUBLICATION_HISTORY_SIZE] = {};
|
||||
unsigned m_publicationIndex = 0;
|
||||
|
||||
int64_t m_lastPhaseError = 0;
|
||||
uint64_t m_acquiredFrames = 0;
|
||||
uint64_t m_skippedFrames = 0;
|
||||
uint64_t m_publishedFrames = 0;
|
||||
uint64_t m_lastLog = 0;
|
||||
uint64_t m_lastLogAcquired = 0;
|
||||
uint64_t m_lastLogSkipped = 0;
|
||||
uint64_t m_lastLogPublished = 0;
|
||||
|
||||
Client * FindClient(uint32_t clientID);
|
||||
Client * FindOrAllocateClient(uint32_t clientID);
|
||||
Publication * FindPublication(const Schedule& schedule,
|
||||
uint32_t frameSerial);
|
||||
bool ElectOwner(uint64_t now, uint32_t resetClientID = 0);
|
||||
bool ApplyFeedback(Client& client, const KVMFRFrameSchedule& schedule);
|
||||
void AdvanceCurrentDeadline();
|
||||
void AdvanceDeadlineSerial(uint64_t count);
|
||||
void AdvanceDeadline(uint64_t now);
|
||||
static void AdvanceDelivery(Client& client, uint64_t now);
|
||||
void WakePublisher() const;
|
||||
|
||||
public:
|
||||
CFrameScheduler();
|
||||
~CFrameScheduler();
|
||||
|
||||
static uint64_t Nanotime();
|
||||
|
||||
void Reset();
|
||||
void UpdateSubscribers(const uint32_t * clientIDs, unsigned count,
|
||||
const uint32_t * ownerClientIDs, unsigned ownerCount, uint64_t now);
|
||||
bool UpdateSchedule(uint32_t sourceClientID,
|
||||
const KVMFRFrameSchedule& schedule, uint64_t now);
|
||||
bool GetSchedule(Schedule& schedule) const;
|
||||
HANDLE GetWakeEvent() const { return m_wakeEvent; }
|
||||
void ObserveFrame(uint64_t now);
|
||||
void ForceFrame();
|
||||
bool GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
Schedule& schedule, bool& periodic, bool& republish);
|
||||
void FrameMissed(const Schedule& schedule, uint64_t now, bool periodic);
|
||||
void FrameSuperseded();
|
||||
bool TryFrameSubmitted(const Schedule& schedule, uint32_t frameSerial);
|
||||
void FramePublished(const Schedule& schedule, uint32_t frameSerial,
|
||||
uint64_t now, bool periodic);
|
||||
void FrameRetained(const Schedule& schedule, uint64_t now,
|
||||
bool periodic);
|
||||
void FrameRepublished(const Schedule& schedule, uint32_t frameSerial);
|
||||
bool TryFrameCompleted(const Schedule& schedule, uint32_t frameSerial,
|
||||
uint64_t completedAt);
|
||||
unsigned GetSecondaryRecipients(const uint32_t * clientIDs,
|
||||
unsigned count, uint32_t frameSerial, uint64_t now,
|
||||
uint32_t * recipients) const;
|
||||
bool GetSecondaryTarget(uint32_t frameSerial, uint64_t now,
|
||||
const uint32_t * blockedClientIDs, unsigned blockedCount,
|
||||
uint64_t& target) const;
|
||||
void FrameDelivered(const uint32_t * clientIDs, unsigned count,
|
||||
uint32_t frameSerial, uint64_t now);
|
||||
void RequestRepublish();
|
||||
void NotifyPublisher() const { WakePublisher(); }
|
||||
void TryRecordFrameTiming(uint64_t duration);
|
||||
void LogStatistics(uint64_t now);
|
||||
};
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "capture/CHardwareFrameProcessor.h"
|
||||
#include "capture/CFrameProcessorUtil.h"
|
||||
#include "transport/CFrameTransport.h"
|
||||
#include "transport/IFrameTransport.h"
|
||||
#include "util/CSRWLock.h"
|
||||
#include "CDebug.h"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static_assert(LGMP_Q_FRAME_LEN == 2,
|
||||
static_assert(TRANSPORT_FRAME_QUEUE_LENGTH == 2,
|
||||
"IDD candidate pipeline assumes two slots");
|
||||
|
||||
class CPublishPending
|
||||
@@ -71,8 +71,8 @@ public:
|
||||
};
|
||||
|
||||
CHardwareFrameProcessor::CHardwareFrameProcessor(
|
||||
CFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
IFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
CFrameProcessor(transport, std::move(dx12), postProcessors,
|
||||
pipelineLock, terminateEvent)
|
||||
|
||||
@@ -65,8 +65,8 @@ private:
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
FrameCandidate m_candidates[LGMP_Q_FRAME_LEN];
|
||||
CandidateDamageTail m_candidateDamageTail[LGMP_Q_FRAME_LEN];
|
||||
FrameCandidate m_candidates[TRANSPORT_FRAME_QUEUE_LENGTH];
|
||||
CandidateDamageTail m_candidateDamageTail[TRANSPORT_FRAME_QUEUE_LENGTH];
|
||||
mutable SRWLOCK m_candidateLock = SRWLOCK_INIT;
|
||||
SRWLOCK m_copySubmitLock = SRWLOCK_INIT;
|
||||
uint64_t m_candidateSequence = 0;
|
||||
@@ -89,9 +89,9 @@ private:
|
||||
void SetFullDamageLocked() override;
|
||||
|
||||
public:
|
||||
CHardwareFrameProcessor(CFrameTransport * transport,
|
||||
CHardwareFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
bool IsValid() const override;
|
||||
|
||||
@@ -20,21 +20,21 @@
|
||||
|
||||
#include "capture/CSoftwareFrameProcessor.h"
|
||||
#include "capture/CFrameProcessorUtil.h"
|
||||
#include "capture/FrameBufferTypes.h"
|
||||
#include "transport/CFrameTransport.h"
|
||||
#include "transport/TransportTypes.h"
|
||||
#include "transport/IFrameTransport.h"
|
||||
#include "util/CSRWLock.h"
|
||||
#include "CDebug.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
CSoftwareFrameProcessor::CSoftwareFrameProcessor(
|
||||
CFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
IFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
CFrameProcessor(transport, std::move(dx12), postProcessors,
|
||||
pipelineLock, terminateEvent),
|
||||
m_directTexture(
|
||||
!m_dx12->IsIndirectCopy() && m_dx12->CanUseIVSHMEMTexture())
|
||||
!m_dx12->IsIndirectCopy() && m_dx12->CanUseDirectTexture())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -152,18 +152,18 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
else
|
||||
{
|
||||
m_directTexture = false;
|
||||
DEBUG_WARN("IVSHMEM texture layout does not fit the framebuffer");
|
||||
DEBUG_WARN("Transport texture layout does not fit the framebuffer");
|
||||
}
|
||||
}
|
||||
else if (m_directTexture)
|
||||
{
|
||||
m_directTexture = false;
|
||||
DEBUG_WARN("Post-processor output cannot use an IVSHMEM texture");
|
||||
DEBUG_WARN("Post-processor output cannot use a transport texture");
|
||||
}
|
||||
|
||||
if (!pitch || !frameSize || frameSize > m_transport->GetMaxFrameSize())
|
||||
{
|
||||
DEBUG_ERROR("Software frame does not fit in shared memory");
|
||||
DEBUG_ERROR("Software frame does not fit in transport memory");
|
||||
SetFullDamage();
|
||||
return false;
|
||||
}
|
||||
@@ -190,7 +190,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
deliverySchedule.deliveryDeadlineSerial = 0;
|
||||
deliverySchedule.phaseEligible = false;
|
||||
|
||||
m_transport->ProcessFrameQueue();
|
||||
m_transport->ProcessDeliveries();
|
||||
if (!m_transport->FrameBufferAvailable(
|
||||
deliverySchedule, submission.noImageUpdate))
|
||||
{
|
||||
@@ -258,7 +258,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
RestorePendingDamage(
|
||||
currentDirtyRects, nbDirtyRects, hasDamage);
|
||||
DEBUG_ERROR_HR(deviceStatus,
|
||||
"D3D12 device removed while creating an IVSHMEM texture");
|
||||
"D3D12 device removed while creating a transport texture");
|
||||
SetFullDamage();
|
||||
return false;
|
||||
}
|
||||
@@ -266,7 +266,7 @@ bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
m_directTexture = false;
|
||||
textureDescPtr = nullptr;
|
||||
DEBUG_WARN(
|
||||
"IVSHMEM textures unavailable; using a direct buffer copy");
|
||||
"Transport textures unavailable; using a direct buffer copy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ private:
|
||||
CD3D12CommandSlot * slot, bool result, void * param1, void * param2);
|
||||
|
||||
public:
|
||||
CSoftwareFrameProcessor(CFrameTransport * transport,
|
||||
CSoftwareFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[LGMP_Q_FRAME_LEN],
|
||||
CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
bool Submit(const FrameSubmission& submission) override;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "display/IddCxCompat.h"
|
||||
#include "display/device/CDeviceContext.h"
|
||||
#include "transport/CLGMPControl.h"
|
||||
#include "transport/IControlTransport.h"
|
||||
|
||||
#include "CDebug.h"
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "display/device/CDeviceContext.h"
|
||||
#include "display/monitor/Context.h"
|
||||
#include "platform/CPlatformInfo.h"
|
||||
#include "transport/CFrameTransport.h"
|
||||
#include "transport/CLGMPControl.h"
|
||||
#include "transport/IFrameTransport.h"
|
||||
#include "transport/IControlTransport.h"
|
||||
#include "util/CSRWLock.h"
|
||||
|
||||
#include <avrt.h>
|
||||
@@ -49,8 +49,8 @@ CSwapChainProcessor::CSwapChainProcessor(CMonitorContext * monitorContext,
|
||||
m_assignmentGeneration(assignmentGeneration),
|
||||
m_monitor(monitor),
|
||||
m_devContext(devContext),
|
||||
m_transport(devContext->GetFrameTransport()),
|
||||
m_control(devContext->GetLGMPControl()),
|
||||
m_transport(devContext->GetTransport().Frames()),
|
||||
m_control(devContext->GetTransport().Control()),
|
||||
m_hSwapChain(hSwapChain),
|
||||
m_renderAdapter(renderAdapter),
|
||||
m_dx11Device(dx11Device),
|
||||
@@ -99,7 +99,8 @@ bool CSwapChainProcessor::InitializePipeline()
|
||||
UINT64 alignSize = CPlatformInfo::GetPageSize();
|
||||
auto dx12Device = std::make_shared<CD3D12Device>(m_renderAdapter);
|
||||
const CD3D12Device::InitResult result = dx12Device->Init(
|
||||
m_transport.GetIVSHMEM(), alignSize, !m_dx11Device->IsSoftware());
|
||||
m_devContext->GetTransport().GetDirectMemory(), alignSize,
|
||||
!m_dx11Device->IsSoftware());
|
||||
if (result == CD3D12Device::RETRY)
|
||||
{
|
||||
const HRESULT deviceStatus =
|
||||
@@ -115,9 +116,9 @@ bool CSwapChainProcessor::InitializePipeline()
|
||||
if (result == CD3D12Device::FAILURE)
|
||||
return false;
|
||||
|
||||
if (!m_devContext->SetupLGMP(alignSize))
|
||||
if (!m_devContext->SetupTransport(alignSize))
|
||||
{
|
||||
DEBUG_ERROR("SetupLGMP failed");
|
||||
DEBUG_ERROR("Transport setup failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -333,7 +334,7 @@ void CSwapChainProcessor::SwapChainThreadCore()
|
||||
// Only the buffer2 acquisition path (IddCx 1.10+) reports it; on the legacy
|
||||
// path HDR is not available, so default to SDR.
|
||||
DXGI_COLOR_SPACE_TYPE colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
UINT sdrWhiteLevel = KVMFR_SDR_WHITE_LEVEL_DEFAULT;
|
||||
UINT sdrWhiteLevel = LG_SDR_WHITE_LEVEL_DEFAULT;
|
||||
const uint64_t captureStart = CFrameScheduler::Nanotime();
|
||||
|
||||
#ifdef HAS_IDDCX_110
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "display/IddCxCompat.h"
|
||||
#include "d3d/CInteropResourcePool.h"
|
||||
#include "capture/CFrameProcessor.h"
|
||||
#include "common/KVMFR.h"
|
||||
#include "postprocess/D12FrameFormat.h"
|
||||
#include "postprocess/CPostProcessor.h"
|
||||
|
||||
#include <Windows.h>
|
||||
@@ -37,8 +37,8 @@ using namespace Microsoft::WRL;
|
||||
|
||||
class CMonitorContext;
|
||||
class CDeviceContext;
|
||||
class CFrameTransport;
|
||||
class CLGMPControl;
|
||||
class IFrameTransport;
|
||||
class IControlTransport;
|
||||
|
||||
class CSwapChainProcessor
|
||||
{
|
||||
@@ -47,8 +47,8 @@ private:
|
||||
UINT64 m_assignmentGeneration;
|
||||
IDDCX_MONITOR m_monitor;
|
||||
CDeviceContext * m_devContext;
|
||||
CFrameTransport & m_transport;
|
||||
CLGMPControl & m_control;
|
||||
IFrameTransport & m_transport;
|
||||
IControlTransport & m_control;
|
||||
IDDCX_SWAPCHAIN m_hSwapChain;
|
||||
LUID m_renderAdapter;
|
||||
std::shared_ptr<CD3D11Device> m_dx11Device;
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
HANDLE m_newFrameEvent;
|
||||
|
||||
CInteropResourcePool m_resPool;
|
||||
CPostProcessor m_postProcessors[LGMP_Q_FRAME_LEN];
|
||||
CPostProcessor m_postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH];
|
||||
std::unique_ptr<CFrameProcessor> m_frameProcessor;
|
||||
// Reconfiguration is exclusive while per-candidate recording is shared.
|
||||
SRWLOCK m_pipelineLock = SRWLOCK_INIT;
|
||||
@@ -68,7 +68,7 @@ private:
|
||||
Wrappers::Event m_cursorDataEvent;
|
||||
BYTE* m_shapeBuffer;
|
||||
DWORD m_lastShapeId = 0;
|
||||
std::atomic<UINT> m_sdrWhiteLevel { KVMFR_SDR_WHITE_LEVEL_DEFAULT };
|
||||
std::atomic<UINT> m_sdrWhiteLevel { LG_SDR_WHITE_LEVEL_DEFAULT };
|
||||
|
||||
#ifdef HAS_IDDCX_110
|
||||
// The per-frame metadata stream can select the monitor default, provide a
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "capture/CSwapChainProcessor.h"
|
||||
|
||||
#include "transport/CFrameTransport.h"
|
||||
#include "transport/IFrameTransport.h"
|
||||
|
||||
#include <avrt.h>
|
||||
#include "CDebug.h"
|
||||
@@ -83,7 +83,7 @@ void CSwapChainProcessor::PublisherThread()
|
||||
const bool ready = m_frameProcessor->HasReadyFrame();
|
||||
if (!ready)
|
||||
{
|
||||
m_transport.ProcessFrameQueue();
|
||||
m_transport.ProcessDeliveries();
|
||||
if (m_frameProcessor->HasReadyFrame())
|
||||
continue;
|
||||
|
||||
@@ -123,12 +123,12 @@ void CSwapChainProcessor::PublisherThread()
|
||||
}
|
||||
|
||||
uint64_t replayTarget;
|
||||
if (m_transport.GetSharedFrameTarget(current, replayTarget))
|
||||
if (m_transport.GetPendingDeliveryTarget(current, replayTarget))
|
||||
{
|
||||
bool retry = false;
|
||||
if (replayTarget <= current)
|
||||
{
|
||||
if (m_transport.ReplaySharedFrame(current, retry))
|
||||
if (m_transport.RetryPendingDelivery(current, retry))
|
||||
continue;
|
||||
|
||||
current = CFrameScheduler::Nanotime();
|
||||
@@ -205,15 +205,15 @@ void CSwapChainProcessor::PublisherThread()
|
||||
|
||||
uint64_t current = CFrameScheduler::Nanotime();
|
||||
uint64_t replayTarget;
|
||||
if (m_transport.GetSharedFrameTarget(current, replayTarget) &&
|
||||
if (m_transport.GetPendingDeliveryTarget(current, replayTarget) &&
|
||||
replayTarget < target)
|
||||
{
|
||||
if (replayTarget <= current)
|
||||
{
|
||||
m_transport.ProcessFrameQueue();
|
||||
m_transport.ProcessDeliveries();
|
||||
current = CFrameScheduler::Nanotime();
|
||||
bool retry = false;
|
||||
if (m_transport.ReplaySharedFrame(current, retry))
|
||||
if (m_transport.RetryPendingDelivery(current, retry))
|
||||
continue;
|
||||
|
||||
current = CFrameScheduler::Nanotime();
|
||||
@@ -251,7 +251,7 @@ void CSwapChainProcessor::PublisherThread()
|
||||
}
|
||||
|
||||
const uint64_t publishStart = CFrameScheduler::Nanotime();
|
||||
m_transport.ProcessFrameQueue();
|
||||
m_transport.ProcessDeliveries();
|
||||
if (!m_transport.FrameBufferAvailable(schedule) ||
|
||||
!m_frameProcessor->Publish(schedule, periodic, publishStart))
|
||||
{
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2026 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// FrameBuffer overlays LGMP shared memory and has a variable-length payload.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
struct FrameBuffer
|
||||
{
|
||||
volatile uint32_t wp;
|
||||
uint8_t data[0];
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
struct PreparedFrameBuffer
|
||||
{
|
||||
unsigned frameIndex;
|
||||
uint8_t * mem;
|
||||
bool fullCopy;
|
||||
};
|
||||
Reference in New Issue
Block a user