int vboxUhgsmiKmtEscBufferInit(PVBOXUHGSMI_PRIVATE_BASE pPrivate, PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PFNVBOXUHGSMI_BUFFER_DESTROY pfnDestroy) { HANDLE hSynch = NULL; if (!cbBuf) return VERR_INVALID_PARAMETER; int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch); if (RT_FAILURE(rc)) { WARN(("vboxUhgsmiBaseEventChkCreate failed, rc %d", rc)); return rc; } cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); uint32_t cPages = cbBuf >> 12; Assert(cPages); VBOXDISPIFESCAPE_UHGSMI_ALLOCATE AllocInfo = {0}; AllocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_ALLOCATE; AllocInfo.Alloc.cbData = cbBuf; AllocInfo.Alloc.hSynch = (uint64_t)hSynch; AllocInfo.Alloc.fUhgsmiType = fUhgsmiType; rc = vboxCrHgsmiPrivateEscape(pPrivate, &AllocInfo, sizeof (AllocInfo), FALSE); if (RT_FAILURE(rc)) { if (hSynch) CloseHandle(hSynch); WARN(("vboxCrHgsmiPrivateEscape failed, rc %d", rc)); return rc; } pBuffer->Alloc = AllocInfo.Alloc; Assert(pBuffer->Alloc.pvData); pBuffer->BasePrivate.pHgsmi = pPrivate; pBuffer->BasePrivate.Base.pfnLock = vboxUhgsmiBaseEscBufferLock; pBuffer->BasePrivate.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock; pBuffer->BasePrivate.Base.pfnDestroy = pfnDestroy; pBuffer->BasePrivate.Base.fType = fUhgsmiType; pBuffer->BasePrivate.Base.cbBuffer = AllocInfo.Alloc.cbData; pBuffer->hSynch = hSynch; return VINF_SUCCESS; }
DECLCALLBACK(int) vboxUhgsmiKmtEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_SYNCHOBJECT_TYPE enmSynchType, HVBOXUHGSMI_SYNCHOBJECT hSynch, PVBOXUHGSMI_BUFFER* ppBuf) { bool bSynchCreated = false; if (!cbBuf) return VERR_INVALID_PARAMETER; int rc = vboxUhgsmiBaseEventChkCreate(enmSynchType, &hSynch, &bSynchCreated); AssertRC(rc); if (RT_FAILURE(rc)) return rc; cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); uint32_t cPages = cbBuf >> 12; Assert(cPages); PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi); PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC)RTMemAllocZ(sizeof (VBOXUHGSMI_BUFFER_PRIVATE_KMT_ESC)); Assert(pBuf); if (pBuf) { struct { D3DKMT_ESCAPE DdiEscape; VBOXDISPIFESCAPE_UHGSMI_ALLOCATE AllocInfo; } Buf; memset(&Buf, 0, sizeof (Buf)); Buf.DdiEscape.hAdapter = pPrivate->Adapter.hAdapter; Buf.DdiEscape.hDevice = pPrivate->Device.hDevice; Buf.DdiEscape.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; //Buf.DdiEscape.Flags.HardwareAccess = 1; Buf.DdiEscape.pPrivateDriverData = &Buf.AllocInfo; Buf.DdiEscape.PrivateDriverDataSize = sizeof (Buf.AllocInfo); Buf.DdiEscape.hContext = pPrivate->Context.hContext; Buf.AllocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_ALLOCATE; Buf.AllocInfo.Alloc.cbData = cbBuf; Buf.AllocInfo.Alloc.hSynch = (uint64_t)hSynch; Buf.AllocInfo.Alloc.enmSynchType = enmSynchType; HRESULT hr = pPrivate->Callbacks.pfnD3DKMTEscape(&Buf.DdiEscape); Assert(hr == S_OK); if (hr == S_OK) { pBuf->Alloc = Buf.AllocInfo.Alloc; Assert(pBuf->Alloc.pvData); pBuf->pHgsmi = pPrivate; pBuf->Base.pfnLock = vboxUhgsmiKmtEscBufferLock; pBuf->Base.pfnUnlock = vboxUhgsmiKmtEscBufferUnlock; // pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange; pBuf->Base.pfnDestroy = vboxUhgsmiKmtEscBufferDestroy; pBuf->Base.hSynch = hSynch; pBuf->Base.enmSynchType = enmSynchType; pBuf->Base.cbBuffer = Buf.AllocInfo.Alloc.cbData; pBuf->Base.bSynchCreated = bSynchCreated; *ppBuf = &pBuf->Base; return VINF_SUCCESS; } else { rc = VERR_OUT_OF_RESOURCES; } RTMemFree(pBuf); } else rc = VERR_NO_MEMORY; if (bSynchCreated) CloseHandle(hSynch); return rc; }
DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_SYNCHOBJECT_TYPE enmSynchType, HVBOXUHGSMI_SYNCHOBJECT hSynch, PVBOXUHGSMI_BUFFER* ppBuf) { bool bSynchCreated = false; if (!cbBuf) return VERR_INVALID_PARAMETER; int rc = vboxUhgsmiBaseEventChkCreate(enmSynchType, &hSynch, &bSynchCreated); AssertRC(rc); if (RT_FAILURE(rc)) return rc; cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); uint32_t cPages = cbBuf >> 12; Assert(cPages); PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi); PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_KMT, aLockPageIndices[cPages])); Assert(pBuf); if (pBuf) { struct { D3DKMT_CREATEALLOCATION DdiAlloc; D3DDDI_ALLOCATIONINFO DdiAllocInfo; VBOXWDDM_ALLOCINFO AllocInfo; } Buf; memset(&Buf, 0, sizeof (Buf)); Buf.DdiAlloc.hDevice = pPrivate->Device.hDevice; Buf.DdiAlloc.NumAllocations = 1; Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo; Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo; Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo); Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER; Buf.AllocInfo.cbBuffer = cbBuf; Buf.AllocInfo.hSynch = (uint64_t)hSynch; Buf.AllocInfo.enmSynchType = enmSynchType; HRESULT hr = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&Buf.DdiAlloc); Assert(hr == S_OK); if (hr == S_OK) { InitializeCriticalSection(&pBuf->CritSect); Assert(Buf.DdiAllocInfo.hAllocation); pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock; pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock; // pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange; pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy; pBuf->BasePrivate.Base.hSynch = hSynch; pBuf->BasePrivate.Base.enmSynchType = enmSynchType; pBuf->BasePrivate.Base.cbBuffer = cbBuf; pBuf->BasePrivate.Base.bSynchCreated = bSynchCreated; pBuf->pHgsmi = pPrivate; pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation; *ppBuf = &pBuf->BasePrivate.Base; return VINF_SUCCESS; } else { rc = VERR_OUT_OF_RESOURCES; } RTMemFree(pBuf); } else rc = VERR_NO_MEMORY; if (bSynchCreated) CloseHandle(hSynch); return rc; }
DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf) { HANDLE hSynch = NULL; if (!cbBuf) return VERR_INVALID_PARAMETER; int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch); AssertRC(rc); if (RT_FAILURE(rc)) return rc; cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000); Assert(cbBuf); uint32_t cPages = cbBuf >> 12; Assert(cPages); PVBOXUHGSMI_PRIVATE_D3D pPrivate = VBOXUHGSMID3D_GET(pHgsmi); PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_D3D)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_D3D, aLockPageIndices[cPages])); Assert(pBuf); if (pBuf) { struct { D3DDDICB_ALLOCATE DdiAlloc; D3DDDI_ALLOCATIONINFO DdiAllocInfo; VBOXWDDM_ALLOCINFO AllocInfo; } Buf; memset(&Buf, 0, sizeof (Buf)); Buf.DdiAlloc.hResource = NULL; Buf.DdiAlloc.hKMResource = NULL; Buf.DdiAlloc.NumAllocations = 1; Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo; Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo; Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo); Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER; Buf.AllocInfo.cbBuffer = cbBuf; Buf.AllocInfo.hSynch = hSynch; Buf.AllocInfo.fUhgsmiType = fUhgsmiType; HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &Buf.DdiAlloc); Assert(hr == S_OK); if (hr == S_OK) { Assert(Buf.DdiAllocInfo.hAllocation); pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiD3DBufferLock; pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiD3DBufferUnlock; // pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiD3DBufferAdjustValidDataRange; pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiD3DBufferDestroy; pBuf->BasePrivate.Base.fType = fUhgsmiType; pBuf->BasePrivate.Base.cbBuffer = cbBuf; pBuf->pDevice = pPrivate->pDevice; pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation; *ppBuf = &pBuf->BasePrivate.Base; return VINF_SUCCESS; } RTMemFree(pBuf); } else rc = VERR_NO_MEMORY; if (hSynch) CloseHandle(hSynch); return rc; }