Fix source buffer mapping in PresentDisplayOnly

Part of source image mapped by PresentDisplayOnly
should be big enough to cover all rectangles being
transferred.

Signed-off-by: Sameeh Jubran <sameeh@daynix.com>
Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Sameeh Jubran 2016-09-28 14:09:28 +03:00 committed by Frediano Ziglio
parent 54e2f808c9
commit bcff8a6d4e
2 changed files with 25 additions and 5 deletions

View File

@ -3666,12 +3666,11 @@ QxlDevice::ExecutePresentDisplayOnly(
ctx->Mdl = NULL; ctx->Mdl = NULL;
ctx->DisplaySource = this; ctx->DisplaySource = this;
// Alternate between synch and asynch execution, for demonstrating // Source bitmap is in user mode, must be locked under __try/__except
// that a real hardware implementation can do either // and mapped to kernel space before use.
{ {
// Map Source into kernel space, as Blt will be executed by system worker thread LONG maxHeight = GetMaxSourceMappingHeight(ctx->Moves, ctx->NumMoves, ctx->DirtyRect, ctx->NumDirtyRects);
UINT sizeToMap = ctx->SrcPitch * ctx->SrcHeight; UINT sizeToMap = ctx->SrcPitch * maxHeight;
PMDL mdl = IoAllocateMdl((PVOID)SrcAddr, sizeToMap, FALSE, FALSE, NULL); PMDL mdl = IoAllocateMdl((PVOID)SrcAddr, sizeToMap, FALSE, FALSE, NULL);
if(!mdl) if(!mdl)
@ -4523,6 +4522,25 @@ void QxlDevice::SetMonitorConfig(QXLHead * monitor_config)
AsyncIo(QXL_IO_MONITORS_CONFIG_ASYNC, 0); AsyncIo(QXL_IO_MONITORS_CONFIG_ASYNC, 0);
} }
LONG QxlDevice::GetMaxSourceMappingHeight(D3DKMT_MOVE_RECT* Moves, ULONG NumMoves, RECT* DirtyRects, ULONG NumDirtyRects)
{
LONG maxHeight = 0;
if (Moves != NULL) {
for (UINT i = 0; i < NumMoves; i++) {
const POINT& pSourcePoint = Moves[i].SourcePoint;
const RECT& pDestRect = Moves[i].DestRect;
maxHeight = MAX(maxHeight, pDestRect.bottom - pDestRect.top + pSourcePoint.y);
}
}
if (DirtyRects != NULL) {
for (UINT i = 0; i < NumDirtyRects; i++) {
const RECT& pDirtyRect = DirtyRects[i];
maxHeight = MAX(maxHeight, pDirtyRect.bottom);
}
}
return maxHeight;
}
NTSTATUS QxlDevice::Escape(_In_ CONST DXGKARG_ESCAPE* pEscape) NTSTATUS QxlDevice::Escape(_In_ CONST DXGKARG_ESCAPE* pEscape)
{ {
size_t data_size(sizeof(uint32_t)); size_t data_size(sizeof(uint32_t));

View File

@ -542,6 +542,8 @@ private:
NTSTATUS SetCustomDisplay(QXLEscapeSetCustomDisplay* custom_display); NTSTATUS SetCustomDisplay(QXLEscapeSetCustomDisplay* custom_display);
void SetMonitorConfig(QXLHead* monitor_config); void SetMonitorConfig(QXLHead* monitor_config);
static LONG GetMaxSourceMappingHeight(D3DKMT_MOVE_RECT* Moves, ULONG NumMoves, RECT* DirtyRects, ULONG NumDirtyRects);
private: private:
PUCHAR m_IoBase; PUCHAR m_IoBase;
BOOLEAN m_IoMapped; BOOLEAN m_IoMapped;