DevVGA_VBVA.cpp revision 2b3b333d5ad53a822bd09813be3dc1d77c43f000
65fea56f17cd614bc8908264df980a62e1931468vboxsync * VirtualBox Video Acceleration (VBVA).
65fea56f17cd614bc8908264df980a62e1931468vboxsync * Copyright (C) 2006-2013 Oracle Corporation
65fea56f17cd614bc8908264df980a62e1931468vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
65fea56f17cd614bc8908264df980a62e1931468vboxsync * available from http://www.virtualbox.org. This file is free software;
65fea56f17cd614bc8908264df980a62e1931468vboxsync * you can redistribute it and/or modify it under the terms of the GNU
65fea56f17cd614bc8908264df980a62e1931468vboxsync * General Public License (GPL) as published by the Free Software
65fea56f17cd614bc8908264df980a62e1931468vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
65fea56f17cd614bc8908264df980a62e1931468vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
65fea56f17cd614bc8908264df980a62e1931468vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
65fea56f17cd614bc8908264df980a62e1931468vboxsync/*******************************************************************************
65fea56f17cd614bc8908264df980a62e1931468vboxsync* Header Files *
65fea56f17cd614bc8908264df980a62e1931468vboxsync*******************************************************************************/
65fea56f17cd614bc8908264df980a62e1931468vboxsync/* A very detailed logging. */
65fea56f17cd614bc8908264df980a62e1931468vboxsync#if 0 // def DEBUG_sunlover
65fea56f17cd614bc8908264df980a62e1931468vboxsync#define LOGVBVABUFFER(a) do {} while (0)
65fea56f17cd614bc8908264df980a62e1931468vboxsync/*******************************************************************************
65fea56f17cd614bc8908264df980a62e1931468vboxsync* Structures and Typedefs *
65fea56f17cd614bc8908264df980a62e1931468vboxsync*******************************************************************************/
65fea56f17cd614bc8908264df980a62e1931468vboxsynctypedef struct VBVAVIEW
65fea56f17cd614bc8908264df980a62e1931468vboxsync/** @todo saved state: save and restore VBVACONTEXT */
65fea56f17cd614bc8908264df980a62e1931468vboxsynctypedef struct VBVACONTEXT
65fea56f17cd614bc8908264df980a62e1931468vboxsync VBVAVIEW aViews[64 /* @todo SchemaDefs::MaxGuestMonitors*/];
65fea56f17cd614bc8908264df980a62e1931468vboxsync/** Copies @a cb bytes from the VBVA ring buffer to the @a pu8Dst.
65fea56f17cd614bc8908264df980a62e1931468vboxsync * Used for partial records or for records which cross the ring boundary.
if (i32Diff <= 0)
static bool vbvaPartialRead (VBVAPARTIALRECORD *pPartialRecord, uint32_t cbRecord, VBVABUFFER *pVBVA)
if (!pu8New)
cbRecord));
static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR **ppHdr, uint32_t *pcbCmd)
LOGVBVABUFFER(("cbRecord = 0x%08X, pPartialRecord->cb = 0x%08X\n", cbRecordCurrent, pPartialRecord->cb));
if (cbRecord)
if (!dst)
static void vbvaReleaseCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA, VBVACMDHDR *pHdr, uint32_t cbCmd)
static int vbvaFlushProcess (unsigned uScreenId, PVGASTATE pVGAState, VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA)
LOGVBVABUFFER(("uScreenId %d, indexRecordFirst = %d, indexRecordFree = %d, off32Data = %d, off32Free = %d\n",
} dirtyRect;
bool fDirtyEmpty = true;
return VERR_NOT_SUPPORTED;
if (cbCmd != 0)
if (!fUpdate)
fUpdate = true;
phdr->h));
if (fDirtyEmpty)
fDirtyEmpty = false;
if (fUpdate)
return VINF_SUCCESS;
unsigned uScreenId;
if (pVBVA)
return VINF_SUCCESS;
return rc;
static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored)
int rc;
if (!fRestored)
return rc;
return VINF_SUCCESS;
if (pHGSMI)
if (pCtx)
#ifdef DEBUG_sunlover
static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape, const uint8_t *pu8Shape)
int rc;
#ifdef DEBUG_sunlover
pu8Shape);
NULL);
return rc;
static int vbvaMousePointerShape (PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape)
if (fShape)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (fShape)
if (pu8Shape)
return VERR_NOT_SUPPORTED;
int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape, &pShape->au8Data[0]);
return rc;
unsigned uScreenId;
#ifdef DEBUG_sunlover
#ifdef VBOX_WITH_VIDEOHWACCEL
static VBOXVHWACMD* vbvaVHWAHHCommandCreate (PVGASTATE pVGAState, VBOXVHWACMD_TYPE enmCmd, int32_t iDisplay, VBOXVHWACMD_LENGTH cbCmd)
if (pHdr)
return pHdr;
if(!cRefs)
if (fAsyncCommand)
RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
if (pPend)
rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pIter->pCommand) - ((uint8_t*)pVGAState->vram_ptrR3)));
return rc;
return VINF_SUCCESS;
int rc;
return rc;
bool fPend = false;
if (!fPend)
AssertFailed();
if (fPend)
RTListForEachSafe(&pVGAState->pendingVhwaCommands.PendingList, pIter, pNext, VBOX_VHWA_PENDINGCMD, Node)
return rc;
VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_CONSTRUCT, 0, sizeof(VBOXVHWACMD_HH_CONSTRUCT));
if(pCmd)
++iDisplay;
return rc;
return VERR_OUT_OF_RESOURCES;
if(pCmd)
++iDisplay;
return rc;
return VERR_OUT_OF_RESOURCES;
typedef DECLCALLBACK(bool) FNVBOXVHWAHHCMDPRECB(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext);
typedef DECLCALLBACK(bool) FNVBOXVHWAHHCMDPOSTCB(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext);
int vbvaVHWAHHPost(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, PFNVBOXVHWAHHCMDPRECB pfnPre, PFNVBOXVHWAHHCMDPOSTCB pfnPost, void *pvContext)
if (pfnPost)
++iDisplay;
return rc;
const VBOXVHWACMD_TYPE enmType = bEnable ? VBOXVHWACMD_TYPE_HH_ENABLE : VBOXVHWACMD_TYPE_HH_DISABLE;
if(pCmd)
return rc;
return VERR_OUT_OF_RESOURCES;
int rc;
#ifdef VBOX_WITH_WDDM
(void**)&pHostCmd,
(void**)&pHostCmd,
rc = HGSMIHostCommandProcessAndFreeAsynch(pIns, pHostCmd, (pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ) != 0);
return rc;
if(pfn)
return rc;
typedef struct VBOXVBVASAVEDSTATECBDATA
int rc;
static DECLCALLBACK(bool) vboxVBVASaveStateBeginPostCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext)
static DECLCALLBACK(bool) vboxVBVASaveStatePerformPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext)
int rc;
static DECLCALLBACK(bool) vboxVBVASaveStateEndPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext)
static DECLCALLBACK(bool) vboxVBVALoadStatePerformPostCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, int rc, void *pvContext)
static DECLCALLBACK(bool) vboxVBVALoadStatePerformPreCb(PVGASTATE pVGAState, VBOXVHWACMD *pCmd, uint32_t iDisplay, void *pvContext)
int rc;
switch (u32)
if (!pCtx)
AssertFailed();
#ifdef DEBUG_sunlover
#ifdef VBOX_WITH_WDDM
sizeof(VBVAMODEHINT));
return rc;
int rc;
#ifdef VBOX_WITH_VIDEOHWACCEL
VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN, 0, cbCmd);
if(pCmd)
#ifdef VBOX_WITH_VIDEOHWACCEL
VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM *pSave = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM);
return rc;
return VINF_SUCCESS;
if (!pCtx)
AssertFailed();
if (!pu8)
return VERR_NO_MEMORY;
return VERR_NO_MEMORY;
#ifdef VBOX_WITH_WDDM
if (cbExtra > 0)
unsigned iHint;
bool fLoadCommands;
fLoadCommands = true;
#ifdef VBOX_WITH_VIDEOHWACCEL
VBOXVHWACMD *pCmd = vbvaVHWAHHCommandCreate(pVGAState, VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM, 0, cbCmd);
if(pCmd)
VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM *pLoad = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM);
vbvaVHWAHHPost (pVGAState, pCmd, vboxVBVALoadStatePerformPreCb, vboxVBVALoadStatePerformPostCb, &VhwaData);
if (fLoadCommands)
return VERR_NOT_SUPPORTED;
if (fLoadCommands)
if (u32)
return VERR_NOT_SUPPORTED;
#ifdef DEBUG_sunlover
return rc;
if (pCtx)
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
return VINF_SUCCESS;
/* we can not use PDMDevHlpPCISetIrqNoWait here, because we need to set IRG host flag and raise IRQ atomically,
VMR3ReqCallNoWait(PDMDevHlpGetVM(pVGAState->pDevInsR3), VMCPUID_ANY, (PFNRT)vbvaRaiseIrqEMT, 2, pVGAState, fFlags);
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
return VINF_SUCCESS;
LogRelFlow(("VBVA_INFO_SCREEN [%lu]: bad data: %lux%lu, line 0x%lx, BPP %u, start offset %lu, max screen size %lu\n",
return VERR_INVALID_PARAMETER;
int VBVAGetInfoViewAndScreen(PVGASTATE pVGAState, uint32_t u32ViewIndex, VBVAINFOVIEW *pView, VBVAINFOSCREEN *pScreen)
return VERR_INVALID_PARAMETER;
if (pView)
if (pScreen)
return VINF_SUCCESS;
#if defined(VBOX_WITH_HGSMI) && (defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_VDMA) || defined(VBOX_WITH_WDDM))
static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
switch (u16ChannelInfo)
case VBVA_CMDVBVA_SUBMIT:
# ifdef VBOX_WITH_CRHGSMI
case VBVA_CMDVBVA_FLUSH:
# ifdef VBOX_WITH_CRHGSMI
case VBVA_CMDVBVA_CTL:
#ifdef VBOX_WITH_CRHGSMI
#ifdef DEBUG_misha
#ifdef VBOX_WITH_VDMA
case VBVA_VDMA_CMD:
case VBVA_VDMA_CTL:
case VBVA_QUERY_CONF32:
case VBVA_SET_CONF32:
case VBVA_INFO_VIEW:
#ifdef VBOX_WITH_CRHGSMI
case VBVA_INFO_HEAP:
case VBVA_FLUSH:
case VBVA_INFO_SCREEN:
#ifdef VBOX_WITH_CRHGSMI
case VBVA_ENABLE:
#ifdef VBOX_WITH_CRHGSMI
unsigned uScreenId;
if (uScreenId == ~0U)
if (pVBVA)
case VBVA_MOUSE_POINTER_SHAPE:
LogFlowFunc(("VBVA_MOUSE_POINTER_SHAPE: i32Result 0x%x, fu32Flags 0x%x, hot spot %d,%d, size %dx%d\n",
#ifdef VBOX_WITH_VIDEOHWACCEL
case VBVA_VHWA_CMD:
#ifdef VBOX_WITH_WDDM
case VBVA_INFO_CAPS:
case VBVA_SCANLINE_CFG:
case VBVA_QUERY_MODE_HINTS:
unsigned iHint;
sizeof(VBVAMODEHINT)));
LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%u, y=%u, cx=%u, cy=%u\n", (unsigned)pReport->x, (unsigned)pReport->y,
pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, pReport->x, pReport->y, pReport->cx, pReport->cy);
case VBVA_CURSOR_POSITION:
return rc;
if (pCtx)
#ifdef VBOX_WITH_VIDEOHWACCEL
if (pCtx)
unsigned uScreenId;
if (pCtx)
return rc;
return VERR_OUT_OF_RANGE;
if (fNotifyGuest && pThis->fGuestCaps & VBVACAPS_IRQ && pThis->fGuestCaps & VBVACAPS_VIDEO_MODE_HINTS)
return VINF_SUCCESS;
#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, IPort)) )
int rc;
return rc;
DECLCALLBACK(void) vbvaPortReportHostCursorCapabilities(PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
pVM,
sizeof (VBVACONTEXT));
return rc;
if (pCtx)