From f4df3f0ec781bd3f41178784639b4204eaf04cee Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sun, 30 Mar 2025 22:58:12 +0000 Subject: [PATCH] [idd] driver: pre-calculae addresses of structs and offsets --- idd/LGIdd/CIndirectDeviceContext.cpp | 57 ++++++++++++++-------------- idd/LGIdd/CIndirectDeviceContext.h | 12 ++++++ idd/LGIdd/CSwapChainProcessor.cpp | 11 ++---- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/idd/LGIdd/CIndirectDeviceContext.cpp b/idd/LGIdd/CIndirectDeviceContext.cpp index 9c425bf3..a912a753 100644 --- a/idd/LGIdd/CIndirectDeviceContext.cpp +++ b/idd/LGIdd/CIndirectDeviceContext.cpp @@ -547,6 +547,7 @@ bool CIndirectDeviceContext::SetupLGMP(size_t alignSize) DEBUG_INFO("Max Frame Size: %u MiB", (unsigned int)(m_maxFrameSize / 1048576LL)); for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i) + { if ((status = lgmpHostMemAllocAligned(m_lgmp, (uint32_t)m_maxFrameSize, (uint32_t)m_alignSize, &m_frameMemory[i])) != LGMP_OK) { @@ -554,6 +555,16 @@ bool CIndirectDeviceContext::SetupLGMP(size_t alignSize) return false; } + m_frame[i] = (KVMFRFrame *)lgmpHostMemPtr(m_frameMemory[i]); + + /** + * put the framebuffer on the border of the next page, this is to allow for + * aligned DMA tranfers by the reciever */ + const size_t alignOffset = alignSize - sizeof(FrameBuffer); + m_frame[i]->offset = (uint32_t)alignOffset; + m_frameBuffer[i] = (FrameBuffer*)(((uint8_t*)m_frame[i]) + alignOffset); + } + WDF_TIMER_CONFIG config; WDF_TIMER_CONFIG_INIT_PERIODIC(&config, [](WDFTIMER timer) -> void @@ -658,16 +669,6 @@ void CIndirectDeviceContext::LGMPTimer() ResendCursor(); } -//FIXME: this should not really be done here, this is a hack -#pragma warning(push) -#pragma warning(disable: 4200) -struct FrameBuffer -{ - volatile uint32_t wp; - uint8_t data[0]; -}; -#pragma warning(pop) - CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrameBuffer(int width, int height, int pitch, DXGI_FORMAT format) { PreparedFrameBuffer result = {}; @@ -687,7 +688,7 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame if (++m_frameIndex == LGMP_Q_FRAME_LEN) m_frameIndex = 0; - KVMFRFrame * fi = (KVMFRFrame *)lgmpHostMemPtr(m_frameMemory[m_frameIndex]); + KVMFRFrame * fi = m_frame[m_frameIndex]; // wait until there is room in the queue while (lgmpHostQueuePending(m_frameQueue) == LGMP_Q_FRAME_LEN) @@ -710,22 +711,22 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame return result; } - fi->formatVer = m_formatVer; - fi->frameSerial = m_frameSerial++; - fi->screenWidth = width; - fi->screenHeight = height; - fi->dataWidth = width; - fi->dataHeight = height; - fi->frameWidth = width; - fi->frameHeight = height; - fi->stride = width * bpp; - fi->pitch = pitch; - fi->offset = (uint32_t)(m_alignSize - sizeof(FrameBuffer)); - fi->flags = 0; - fi->rotation = FRAME_ROT_0; + fi->formatVer = m_formatVer; + fi->frameSerial = m_frameSerial++; + fi->screenWidth = width; + fi->screenHeight = height; + fi->dataWidth = width; + fi->dataHeight = height; + fi->frameWidth = width; + fi->frameHeight = height; + fi->stride = width * bpp; + fi->pitch = pitch; + // fi->offset is initialized at startup + fi->flags = 0; + fi->rotation = FRAME_ROT_0; fi->damageRectsCount = 0; - FrameBuffer* fb = (FrameBuffer*)(((uint8_t*)fi) + fi->offset); + FrameBuffer* fb = m_frameBuffer[m_frameIndex]; fb->wp = 0; lgmpHostQueuePost(m_frameQueue, 0, m_frameMemory[m_frameIndex]); @@ -739,8 +740,7 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame void CIndirectDeviceContext::WriteFrameBuffer(unsigned frameIndex, void* src, size_t offset, size_t len, bool setWritePos) { - KVMFRFrame * fi = (KVMFRFrame*)lgmpHostMemPtr(m_frameMemory[frameIndex]); - FrameBuffer * fb = (FrameBuffer*)(((uint8_t*)fi) + fi->offset); + FrameBuffer * fb = m_frameBuffer[frameIndex]; memcpy( (void *)((uintptr_t)fb->data + offset), @@ -753,8 +753,7 @@ void CIndirectDeviceContext::WriteFrameBuffer(unsigned frameIndex, void* src, si void CIndirectDeviceContext::FinalizeFrameBuffer(unsigned frameIndex) { - KVMFRFrame * fi = (KVMFRFrame*)lgmpHostMemPtr(m_frameMemory[frameIndex]); - FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset); + FrameBuffer * fb = m_frameBuffer[frameIndex]; fb->wp = m_height * m_pitch; } diff --git a/idd/LGIdd/CIndirectDeviceContext.h b/idd/LGIdd/CIndirectDeviceContext.h index a1779fe4..8bb2088d 100644 --- a/idd/LGIdd/CIndirectDeviceContext.h +++ b/idd/LGIdd/CIndirectDeviceContext.h @@ -35,6 +35,16 @@ extern "C" { #define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (512 * 512 * 4)) #define POINTER_SHAPE_BUFFERS 3 +//FIXME: this should not really be done here, this is a hack +#pragma warning(push) +#pragma warning(disable: 4200) +struct FrameBuffer +{ + volatile uint32_t wp; + uint8_t data[0]; +}; +#pragma warning(pop) + class CIndirectDeviceContext { private: @@ -64,6 +74,8 @@ private: uint32_t m_formatVer = 0; uint32_t m_frameSerial = 0; PLGMPMemory m_frameMemory[LGMP_Q_FRAME_LEN] = {}; + KVMFRFrame * m_frame [LGMP_Q_FRAME_LEN] = {}; + FrameBuffer * m_frameBuffer[LGMP_Q_FRAME_LEN] = {}; int m_width = 0; int m_height = 0; diff --git a/idd/LGIdd/CSwapChainProcessor.cpp b/idd/LGIdd/CSwapChainProcessor.cpp index 31defc03..03f71fe8 100644 --- a/idd/LGIdd/CSwapChainProcessor.cpp +++ b/idd/LGIdd/CSwapChainProcessor.cpp @@ -248,14 +248,9 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer srcLoc.SubresourceIndex = 0; D3D12_TEXTURE_COPY_LOCATION dstLoc = {}; - dstLoc.pResource = fbRes->Get().Get(); - dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dstLoc.PlacedFootprint.Offset = 0; - dstLoc.PlacedFootprint.Footprint.Format = desc.Format; - dstLoc.PlacedFootprint.Footprint.Width = (UINT)desc.Width; - dstLoc.PlacedFootprint.Footprint.Height = (UINT)desc.Height; - dstLoc.PlacedFootprint.Footprint.Depth = 1; - dstLoc.PlacedFootprint.Footprint.RowPitch = layout.Footprint.RowPitch; + dstLoc.pResource = fbRes->Get().Get(); + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dstLoc.PlacedFootprint = layout; srcRes->Sync(*copyQueue); copyQueue->GetGfxList()->CopyTextureRegion(