d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/* $Id$ */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/** @file
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * VirtualBox Video driver, common code - VBVA initialisation and helper
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * functions.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2011 Oracle Corporation
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync *
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * available from http://www.virtualbox.org. This file is free software;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * General Public License (GPL) as published by the Free Software
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#include <VBox/VBoxVideoGuest.h>
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#include <VBox/VBoxVideo.h>
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#include <VBox/err.h>
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#include <VBox/log.h>
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#include <iprt/assert.h>
0fc8a97f9a19a44f1ad4670454edf26d80c42281vboxsync#include <iprt/string.h>
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/*
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * There is a hardware ring buffer in the graphics device video RAM, formerly
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * in the VBox VMMDev PCI memory space.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * All graphics commands go there serialized by VBoxVBVABufferBeginUpdate.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * and vboxHwBufferEndUpdate.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync *
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * off32Free is writing position. off32Data is reading position.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * off32Free == off32Data means buffer is empty.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * There must be always gap between off32Data and off32Free when data
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * are in the buffer.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * Guest only changes off32Free, host changes off32Data.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/* Forward declarations of internal functions. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic void vboxHwBufferFlush(PHGSMIGUESTCOMMANDCONTEXT pCtx);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic void vboxHwBufferPlaceDataAt(PVBVABUFFERCONTEXT pCtx, const void *p,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t cb, uint32_t offset);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync const void *p, uint32_t cb);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic bool vboxVBVAInformHost(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync int32_t cScreen, bool bEnable)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync bool bRc = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#if 0 /* All callers check this */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (ppdev->bHGSMISupported)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#endif
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync void *p = VBoxHGSMIBufferAlloc(pHGSMICtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync sizeof (VBVAENABLE_EX),
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync HGSMI_CH_VBVA,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVA_ENABLE);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (!p)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("HGSMIHeapAlloc failed\n"));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync else
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync VBVAENABLE_EX *pEnable = (VBVAENABLE_EX *)p;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pEnable->Base.u32Flags = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pEnable->Base.u32Offset = pCtx->offVRAMBuffer;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pEnable->Base.i32Result = VERR_NOT_SUPPORTED;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (cScreen >= 0)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync {
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pEnable->Base.u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pEnable->u32ScreenId = cScreen;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBoxHGSMIBufferSubmit(pHGSMICtx, p);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (bEnable)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync bRc = RT_SUCCESS(pEnable->Base.i32Result);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync else
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync bRc = true;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBoxHGSMIBufferFree(pHGSMICtx, p);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return bRc;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/*
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * Public hardware buffer methods.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(bool) VBoxVBVAEnable(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync VBVABUFFER *pVBVA, int32_t cScreen)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync bool bRc = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFlowFunc(("pVBVA %p\n", pVBVA));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#if 0 /* All callers check this */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (ppdev->bHGSMISupported)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync#endif
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("pVBVA %p vbva off 0x%x\n", pVBVA, pCtx->offVRAMBuffer));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->hostFlags.u32HostEvents = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->hostFlags.u32SupportedOrders = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->off32Data = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->off32Free = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync memset(pVBVA->aRecords, 0, sizeof (pVBVA->aRecords));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->indexRecordFirst = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->indexRecordFree = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->cbPartialWriteThreshold = 256;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->cbData = pCtx->cbBuffer - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->fHwBufferOverflow = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pRecord = NULL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pVBVA = pVBVA;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync bRc = vboxVBVAInformHost(pCtx, pHGSMICtx, cScreen, true);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (!bRc)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync VBoxVBVADisable(pCtx, pHGSMICtx, cScreen);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return bRc;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(void) VBoxVBVADisable(PVBVABUFFERCONTEXT pCtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync int32_t cScreen)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFlowFunc(("\n"));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->fHwBufferOverflow = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pRecord = NULL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pVBVA = NULL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync vboxVBVAInformHost(pCtx, pHGSMICtx, cScreen, false);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync bool bRc = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if ( pCtx->pVBVA
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t indexRecordNext;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(!pCtx->fHwBufferOverflow);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pCtx->pRecord == NULL);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync indexRecordNext = (pCtx->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (indexRecordNext == pCtx->pVBVA->indexRecordFirst)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* All slots in the records queue are used. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync vboxHwBufferFlush (pHGSMICtx);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (indexRecordNext == pCtx->pVBVA->indexRecordFirst)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Even after flush there is no place. Fail the request. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("no space in the queue of records!!! first %d, last %d\n",
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pVBVA->indexRecordFirst, pCtx->pVBVA->indexRecordFree));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync else
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Initialize the record. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVARECORD *pRecord = &pCtx->pVBVA->aRecords[pCtx->pVBVA->indexRecordFree];
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pVBVA->indexRecordFree = indexRecordNext;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync // LogFunc(("indexRecordNext = %d\n", indexRecordNext));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Remember which record we are using. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pRecord = pRecord;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync bRc = true;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return bRc;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(void) VBoxVBVABufferEndUpdate(PVBVABUFFERCONTEXT pCtx)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVARECORD *pRecord;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync // LogFunc(("\n"));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pCtx->pVBVA);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pRecord = pCtx->pRecord;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Mark the record completed. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->fHwBufferOverflow = false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->pRecord = NULL;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/*
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * Private operations.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic void vboxHwBufferFlush(PHGSMIGUESTCOMMANDCONTEXT pCtx)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Issue the flush command. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync void *p = VBoxHGSMIBufferAlloc(pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync sizeof (VBVAFLUSH),
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync HGSMI_CH_VBVA,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVA_FLUSH);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (!p)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("HGSMIHeapAlloc failed\n"));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync else
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVAFLUSH *pFlush = (VBVAFLUSH *)p;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pFlush->u32Reserved = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBoxHGSMIBufferSubmit(pCtx, p);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
899cf29db99feb05eeba969fe77ba7c62334adf4vboxsync VBoxHGSMIBufferFree(pCtx, p);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic void vboxHwBufferPlaceDataAt(PVBVABUFFERCONTEXT pCtx, const void *p,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t cb, uint32_t offset)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVABUFFER *pVBVA = pCtx->pVBVA;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint8_t *dst = &pVBVA->au8Data[offset];
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync int32_t i32Diff = cb - u32BytesTillBoundary;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (i32Diff <= 0)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Chunk will not cross buffer boundary. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync memcpy (dst, p, cb);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync else
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync /* Chunk crosses buffer boundary. */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync memcpy (dst, p, u32BytesTillBoundary);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncstatic bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync const void *p, uint32_t cb)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVARECORD *pRecord;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t cbHwBufferAvail;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t cbWritten = 0;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVABUFFER *pVBVA = pCtx->pVBVA;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pVBVA);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (!pVBVA || pCtx->fHwBufferOverflow)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pRecord = pCtx->pRecord;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
5b7a95b197f6cbe38714438cc07f722209f78455vboxsync // LogFunc(("%d\n", cb));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync while (cb > 0)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync uint32_t cbChunk = cb;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (cbChunk >= cbHwBufferAvail)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync vboxHwBufferFlush (pHGSMICtx);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (cbChunk >= cbHwBufferAvail)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n",
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cb, cbHwBufferAvail));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync LogFunc(("Buffer overflow!!!\n"));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pCtx->fHwBufferOverflow = true;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(false);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(cbChunk <= cb);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync Assert(cbChunk <= vboxHwBufferAvail (pVBVA));
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync pRecord->cbRecord += cbChunk;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cbHwBufferAvail -= cbChunk;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cb -= cbChunk;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync cbWritten += cbChunk;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return true;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync/*
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync * Public writer to the hardware buffer.
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync */
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(bool) VBoxVBVAWrite(PVBVABUFFERCONTEXT pCtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync const void *pv, uint32_t cb)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return vboxHwBufferWrite (pCtx, pHGSMICtx, pv, cb);
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsyncRTDECL(bool) VBoxVBVAOrderSupported(PVBVABUFFERCONTEXT pCtx, unsigned code)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync{
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync VBVABUFFER *pVBVA = pCtx->pVBVA;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (!pVBVA)
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync if (pVBVA->hostFlags.u32SupportedOrders & (1 << code))
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync {
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return true;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync }
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync return false;
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync}
d1bf0617b0c08b530ed5dcdcc1d6dbd7eb2ed2fcvboxsync
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsyncRTDECL(void) VBoxVBVASetupBufferContext(PVBVABUFFERCONTEXT pCtx,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync uint32_t offVRAMBuffer,
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync uint32_t cbBuffer)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync{
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pCtx->offVRAMBuffer = offVRAMBuffer;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync pCtx->cbBuffer = cbBuffer;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync}