VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp@ 43489

Last change on this file since 43489 was 43489, checked in by vboxsync, 12 years ago

wddm: basics for miniport-based visible rects processing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.3 KB
Line 
1/* $Id: VBoxMPCr.cpp 43489 2012-10-01 11:55:58Z vboxsync $ */
2
3/** @file
4 * VBox WDDM Miniport driver
5 */
6
7/*
8 * Copyright (C) 2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxMPWddm.h"
20#include "VBoxMPCr.h"
21
22#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
23
24#ifdef VBOX_WITH_CROGL
25#include <cr_protocol.h>
26
27# ifdef VBOX_WDDM_WITH_CRCMD
28
29static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
30{
31 return VBoxSHGSMIHeapBufferAlloc(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, cbData);
32}
33
34static VBOXVIDEOOFFSET vboxMpCrShgsmiBufferOffset(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
35{
36 return (VBOXVIDEOOFFSET)HGSMIPointerToOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (const HGSMIBUFFERHEADER *)pvBuffer);
37}
38
39static void* vboxMpCrShgsmiBufferFromOffset(PVBOXMP_DEVEXT pDevExt, VBOXVIDEOOFFSET offBuffer)
40{
41 return HGSMIOffsetToPointer(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (HGSMIOFFSET)offBuffer);
42}
43
44static void vboxMpCrShgsmiBufferFree(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
45{
46 VBoxSHGSMIHeapBufferFree(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pvBuffer);
47}
48
49static VBOXVIDEOOFFSET vboxMpCrShgsmiTransportBufOffset(PVBOXMP_CRSHGSMITRANSPORT pCon, void* pvBuffer)
50{
51 return vboxMpCrShgsmiBufferOffset(pCon->pDevExt, pvBuffer);
52}
53
54static void* vboxMpCrShgsmiTransportBufFromOffset(PVBOXMP_CRSHGSMITRANSPORT pCon, VBOXVIDEOOFFSET offBuffer)
55{
56 return vboxMpCrShgsmiBufferFromOffset(pCon->pDevExt, offBuffer);
57}
58
59void* VBoxMpCrShgsmiTransportBufAlloc(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t cbBuffer)
60{
61 return vboxMpCrShgsmiBufferAlloc(pCon->pDevExt, cbBuffer);
62}
63
64void VBoxMpCrShgsmiTransportBufFree(PVBOXMP_CRSHGSMITRANSPORT pCon, void* pvBuffer)
65{
66 vboxMpCrShgsmiBufferFree(pCon->pDevExt, pvBuffer);
67}
68
69static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr, uint32_t cbRequested)
70{
71 if (pDr->cbBuf >= cbRequested)
72 return VINF_SUCCESS;
73
74 if (pDr->pvBuf)
75 VBoxMpCrShgsmiTransportBufFree(pCon, pDr->pvBuf);
76
77 pDr->pvBuf = VBoxMpCrShgsmiTransportBufAlloc(pCon, cbRequested);
78 if (!pDr->pvBuf)
79 {
80 WARN(("VBoxMpCrShgsmiTransportBufAlloc failed"));
81 pDr->cbBuf = 0;
82 return VERR_NO_MEMORY;
83 }
84
85 pDr->cbBuf = cbRequested;
86 return VINF_SUCCESS;
87}
88
89static void vboxMpCrShgsmiBufCacheFree(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr)
90{
91 if (ASMAtomicCmpXchgPtr(&pCache->pBufDr, pDr, NULL))
92 return;
93
94 /* the value is already cached, free the current one */
95 VBoxMpCrShgsmiTransportBufFree(pCon, pDr->pvBuf);
96 vboxWddmMemFree(pDr);
97}
98
99static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheGetAllocDr(PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
100{
101 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)ASMAtomicXchgPtr((void * volatile *)&pCache->pBufDr, NULL);
102 if (!pBufDr)
103 {
104 pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)vboxWddmMemAllocZero(sizeof (*pBufDr));
105 if (!pBufDr)
106 {
107 WARN(("vboxWddmMemAllocZero failed!"));
108 return NULL;
109 }
110 }
111 return pBufDr;
112}
113
114static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
115{
116 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
117 int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
118 if (RT_SUCCESS(rc))
119 return pBufDr;
120
121 WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
122
123 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
124 return NULL;
125}
126
127static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
128{
129 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
130
131 if (pBufDr->cbBuf)
132 return pBufDr;
133
134 int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
135 if (RT_SUCCESS(rc))
136 return pBufDr;
137
138 WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
139
140 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
141 return NULL;
142}
143
144
145static int vboxMpCrShgsmiBufCacheInit(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
146{
147 memset(pCache, 0, sizeof (*pCache));
148 return VINF_SUCCESS;
149}
150
151static void vboxMpCrShgsmiBufCacheTerm(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
152{
153 if (pCache->pBufDr)
154 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pCache->pBufDr);
155}
156
157int VBoxMpCrShgsmiTransportCreate(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_DEVEXT pDevExt)
158{
159 memset(pCon, 0, sizeof (*pCon));
160 pCon->pDevExt = pDevExt;
161 return VINF_SUCCESS;
162 int rc;
163// int rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->CmdDrCache);
164// if (RT_SUCCESS(rc))
165 {
166 rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->WbDrCache);
167 if (RT_SUCCESS(rc))
168 {
169 }
170 else
171 {
172 WARN(("vboxMpCrShgsmiBufCacheInit2 failed rc %d", rc));
173 }
174// vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
175 }
176// else
177// {
178// WARN(("vboxMpCrShgsmiBufCacheInit1 failed rc %d", rc));
179// }
180
181 return rc;
182}
183
184void VBoxMpCrShgsmiTransportTerm(PVBOXMP_CRSHGSMITRANSPORT pCon)
185{
186 vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
187// vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
188}
189
190//typedef struct VBOXMP_CRHGSMICMD_HDR
191//{
192// union
193// {
194// PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnWriteReadCompletion;
195// PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnWriteCompletion;
196// };
197//} VBOXMP_CRHGSMICMD_HDR, *PVBOXMP_CRHGSMICMD_HDR;
198
199typedef struct VBOXMP_CRHGSMICMD_BASE
200{
201// VBOXMP_CRHGSMICMD_HDR Hdr;
202 CRVBOXHGSMIHDR CmdHdr;
203} VBOXMP_CRHGSMICMD_BASE, *PVBOXMP_CRHGSMICMD_BASE;
204
205typedef struct VBOXMP_CRHGSMICMD_WRITEREAD
206{
207// VBOXMP_CRHGSMICMD_HDR Hdr;
208 CRVBOXHGSMIWRITEREAD Cmd;
209} VBOXMP_CRHGSMICMD_WRITEREAD, *PVBOXMP_CRHGSMICMD_WRITEREAD;
210
211typedef struct VBOXMP_CRHGSMICMD_READ
212{
213// VBOXMP_CRHGSMICMD_HDR Hdr;
214 CRVBOXHGSMIREAD Cmd;
215} VBOXMP_CRHGSMICMD_READ, *PVBOXMP_CRHGSMICMD_READ;
216
217typedef struct VBOXMP_CRHGSMICMD_WRITE
218{
219// VBOXMP_CRHGSMICMD_HDR Hdr;
220 CRVBOXHGSMIWRITE Cmd;
221} VBOXMP_CRHGSMICMD_WRITE, *PVBOXMP_CRHGSMICMD_WRITE;
222
223#define VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) VBOXWDDM_ROUNDBOUND((VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[_cBuffers]))), 8)
224#define VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf) ( VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) + VBOXWDDM_ROUNDBOUND(_cbCmdBuf, 8))
225#define VBOXMP_CRSHGSMICON_DR_GET_CRCMD(_pDr) (VBOXVDMACMD_BODY((_pDr), VBOXVDMACMD_CHROMIUM_CMD))
226#define VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(_pDr, _cBuffers, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers)))
227#define VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(_pDr, _cBuffers, _cbCmdBuf, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf)))
228#define VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(_pCtx, _cBuffers, _cbCmdBuf) ((VBOXVDMACMD*)(((uint8_t*)(_pCtx)) - VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf)))
229#define VBOXMP_CRSHGSMICON_DR_SIZE(_cBuffers, _cbCmdBuf, _cbCtx) (VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf) + (_cbCtx))
230
231
232static int vboxMpCrShgsmiTransportCmdSubmitDr(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACBUF_DR pDr, PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete)
233{
234
235 PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
236 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
237 vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, pfnComplete, pCon);
238 /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
239 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
240 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
241 if (RT_SUCCESS(rc))
242 {
243 return VINF_SUCCESS;
244 }
245
246 WARN(("vboxVdmaCBufDrSubmit failed rc %d", rc));
247 return rc;
248}
249
250static int vboxMpCrShgsmiTransportCmdSubmitDmaCmd(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACMD pHdr, PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete)
251{
252 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_TAIL(pHdr);
253 return vboxMpCrShgsmiTransportCmdSubmitDr(pCon, pDr, pfnComplete);
254}
255
256static void vboxMpCrShgsmiTransportCmdTermDmaCmd(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACMD pHdr)
257{
258 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_TAIL(pHdr);
259 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
260 vboxVdmaCBufDrFree (&pDevExt->u.primary.Vdma, pDr);
261}
262
263
264typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx);
265typedef FNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION *PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION;
266
267static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendReadAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
268{
269 /* we should be called from our DPC routine */
270 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
271
272 PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
273 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
274 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
275 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
276 const UINT cBuffers = 2;
277 Assert(pBody->cBuffers == cBuffers);
278 PVBOXMP_CRHGSMICMD_READ pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_READ);
279 CRVBOXHGSMIREAD *pCmd = &pWrData->Cmd;
280 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
281 Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIREAD));
282 CRVBOXHGSMIREAD * pWr = (CRVBOXHGSMIREAD*)vboxMpCrShgsmiTransportBufFromOffset(pCon, pBufCmd->offBuffer);
283 PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION)pBufCmd->u64GuestData;
284 VBOXVDMACMD_CHROMIUM_BUFFER *pRxBuf = &pBody->aBuffers[1];
285 PVBOXMP_CRSHGSMICON_BUFDR pWbDr = (PVBOXMP_CRSHGSMICON_BUFDR)pRxBuf->u64GuestData;
286 void *pvRx = NULL;
287 uint32_t cbRx = 0;
288
289 int rc = pDr->rc;
290 if (RT_SUCCESS(rc))
291 {
292 rc = pWr->hdr.result;
293 if (RT_SUCCESS(rc))
294 {
295 cbRx = pCmd->cbBuffer;
296 if (cbRx)
297 pvRx = pWbDr->pvBuf;
298 }
299 else
300 {
301 WARN(("CRVBOXHGSMIREAD failed, rc %d", rc));
302 }
303 }
304 else
305 {
306 WARN(("dma command buffer failed rc %d!", rc));
307 }
308
309 if (pfnCompletion)
310 {
311 void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), void);
312 pfnCompletion(pCon, rc, pvRx, cbRx, pvCtx);
313 }
314
315 vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
316}
317
318static void* vboxMpCrShgsmiTransportCmdCreateReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, PVBOXVDMACBUF_DR pDr, uint32_t cbDrData, PVBOXMP_CRSHGSMICON_BUFDR pWbDr,
319 PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
320{
321 const uint32_t cBuffers = 2;
322 const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), cbContextData);
323 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
324 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
325 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
326 PVBOXMP_CRHGSMICMD_READ pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_READ);
327 CRVBOXHGSMIREAD *pCmd = &pWrData->Cmd;
328
329 if (cbCmd > cbContextData)
330 {
331 ERR(("the passed descriptor is less than needed!"));
332 return NULL;
333 }
334
335 memset(pDr, 0, VBOXVDMACBUF_DR_SIZE(cbCmd));
336
337 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET;
338 pDr->cbBuf = cbCmd;
339 pDr->rc = VERR_NOT_IMPLEMENTED;
340 pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
341
342 pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
343 pHdr->u32CmdSpecific = 0;
344
345 pBody->cBuffers = cBuffers;
346
347 pCmd->hdr.result = VERR_WRONG_ORDER;
348 pCmd->hdr.u32ClientID = u32ClientID;
349 pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
350 // pCmd->hdr.u32Reserved = 0;
351 pCmd->iBuffer = 1;
352
353 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
354 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
355 pBufCmd->cbBuffer = sizeof (*pCmd);
356 pBufCmd->u32GuestData = 0;
357 pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
358
359 pBufCmd = &pBody->aBuffers[1];
360 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pWbDr->pvBuf);
361 pBufCmd->cbBuffer = pWbDr->cbBuf;
362 pBufCmd->u32GuestData = 0;
363 pBufCmd->u64GuestData = (uint64_t)pWbDr;
364
365 return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), void);
366}
367
368static int vboxMpCrShgsmiTransportCmdSubmitReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
369{
370 VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_READ));
371 return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendReadAsyncCompletion);
372}
373
374typedef struct VBOXMP_CRHGSMICON_WRR_COMPLETION_CTX
375{
376 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion;
377 void *pvContext;
378
379} VBOXMP_CRHGSMICON_WRR_COMPLETION_CTX, *PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX;
380
381static DECLCALLBACK(void) vboxMpCrShgsmiTransportSendWriteReadReadRepostCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx)
382{
383 PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX pData = (PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX)pvCtx;
384 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion = pData->pfnCompletion;
385 if (pfnCompletion)
386 pfnCompletion(pCon, rc, pvRx, cbRx, pData->pvContext);
387}
388
389static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendWriteReadAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
390{
391 /* we should be called from our DPC routine */
392 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
393
394 PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
395 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
396 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
397 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
398 const UINT cBuffers = 3;
399 Assert(pBody->cBuffers == cBuffers);
400 PVBOXMP_CRHGSMICMD_WRITEREAD pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITEREAD);
401 CRVBOXHGSMIWRITEREAD *pCmd = &pWrData->Cmd;
402 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
403 Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIWRITEREAD));
404 CRVBOXHGSMIWRITEREAD * pWr = (CRVBOXHGSMIWRITEREAD*)vboxMpCrShgsmiTransportBufFromOffset(pCon, pBufCmd->offBuffer);
405 VBOXVDMACMD_CHROMIUM_BUFFER *pRxBuf = &pBody->aBuffers[2];
406 PVBOXMP_CRSHGSMICON_BUFDR pWbDr = (PVBOXMP_CRSHGSMICON_BUFDR)pRxBuf->u64GuestData;
407 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION)pBufCmd->u64GuestData;
408 void *pvRx = NULL;
409 uint32_t cbRx = 0;
410
411 int rc = pDr->rc;
412 if (RT_SUCCESS(rc))
413 {
414 rc = pWr->hdr.result;
415 if (RT_SUCCESS(rc))
416 {
417 cbRx = pCmd->cbWriteback;
418 if (cbRx)
419 pvRx = pWbDr->pvBuf;
420 }
421 else if (rc == VERR_BUFFER_OVERFLOW)
422 {
423 /* issue read */
424 void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
425 vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
426 pWbDr = vboxMpCrShgsmiBufCacheAlloc(pCon, &pCon->WbDrCache, pCmd->cbWriteback);
427 if (pWbDr)
428 {
429 /* the Read Command is shorter than WriteRead, so just reuse the Write-Read descriptor here */
430 PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX pReadCtx = (PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX)vboxMpCrShgsmiTransportCmdCreateReadAsync(pCon, pCmd->hdr.u32ClientID,
431 pDr, VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), 0),
432 pWbDr, vboxMpCrShgsmiTransportSendWriteReadReadRepostCompletion, sizeof (*pReadCtx));
433 pReadCtx->pfnCompletion = pfnCompletion;
434 pReadCtx->pvContext = pvCtx;
435 vboxMpCrShgsmiTransportCmdSubmitReadAsync(pCon, pReadCtx);
436 /* don't do completion here, the completion will be called from the read completion we issue here */
437 pfnCompletion = NULL;
438 /* the current pWbDr was already freed, and we'll free the Read dr in the Read Completion */
439 pWbDr = NULL;
440 }
441 else
442 {
443 WARN(("vboxMpCrShgsmiBufCacheAlloc failed for %d", pCmd->cbWriteback));
444 rc = VERR_NO_MEMORY;
445 }
446 }
447 else
448 {
449 WARN(("CRVBOXHGSMIWRITEREAD failed, rc %d", rc));
450 }
451 }
452 else
453 {
454 WARN(("dma command buffer failed rc %d!", rc));
455 }
456
457 if (pfnCompletion)
458 {
459 void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
460 pfnCompletion(pCon, rc, pvRx, cbRx, pvCtx);
461 }
462
463 if (pWbDr)
464 vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
465}
466
467static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendWriteAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
468{
469 /* we should be called from our DPC routine */
470 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
471
472 PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
473 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
474 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
475 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
476 const UINT cBuffers = 2;
477 Assert(pBody->cBuffers == cBuffers);
478 PVBOXMP_CRHGSMICMD_WRITE pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITE);
479 CRVBOXHGSMIWRITE *pCmd = &pWrData->Cmd;
480 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
481 Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIWRITE));
482 CRVBOXHGSMIWRITE * pWr = (CRVBOXHGSMIWRITE*)vboxMpCrShgsmiTransportBufFromOffset(pCon, pBufCmd->offBuffer);
483 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION)pBufCmd->u64GuestData;
484
485 int rc = pDr->rc;
486 if (RT_SUCCESS(rc))
487 {
488 rc = pWr->hdr.result;
489 if (!RT_SUCCESS(rc))
490 {
491 WARN(("CRVBOXHGSMIWRITE failed, rc %d", rc));
492 }
493 }
494 else
495 {
496 WARN(("dma command buffer failed rc %d!", rc));
497 }
498
499 if (pfnCompletion)
500 {
501 void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), void);
502 pfnCompletion(pCon, rc, pvCtx);
503 }
504}
505
506void* VBoxMpCrShgsmiTransportCmdCreateWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
507 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
508{
509 const uint32_t cBuffers = 3;
510 const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), cbContextData);
511 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
512 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
513 if (!pDr)
514 {
515 WARN(("vboxVdmaCBufDrCreate failed"));
516 return NULL;
517 }
518
519 PVBOXMP_CRSHGSMICON_BUFDR pWbDr = vboxMpCrShgsmiBufCacheAllocAny(pCon, &pCon->WbDrCache, 1000);
520 if (!pWbDr)
521 {
522 WARN(("vboxMpCrShgsmiBufCacheAlloc for wb dr failed"));
523 vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
524 return NULL;
525 }
526
527 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
528 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
529 PVBOXMP_CRHGSMICMD_WRITEREAD pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITEREAD);
530 CRVBOXHGSMIWRITEREAD *pCmd = &pWrData->Cmd;
531
532 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET;
533 pDr->cbBuf = cbCmd;
534 pDr->rc = VERR_NOT_IMPLEMENTED;
535 pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
536
537 pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
538 pHdr->u32CmdSpecific = 0;
539
540 pBody->cBuffers = cBuffers;
541
542 pCmd->hdr.result = VERR_WRONG_ORDER;
543 pCmd->hdr.u32ClientID = u32ClientID;
544 pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
545 // pCmd->hdr.u32Reserved = 0;
546 pCmd->iBuffer = 1;
547 pCmd->iWriteback = 2;
548 pCmd->cbWriteback = 0;
549
550 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
551 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
552 pBufCmd->cbBuffer = sizeof (*pCmd);
553 pBufCmd->u32GuestData = 0;
554 pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
555
556 pBufCmd = &pBody->aBuffers[1];
557 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pvBuffer);
558 pBufCmd->cbBuffer = cbBuffer;
559 pBufCmd->u32GuestData = 0;
560 pBufCmd->u64GuestData = 0;
561
562 pBufCmd = &pBody->aBuffers[2];
563 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pWbDr->pvBuf);
564 pBufCmd->cbBuffer = pWbDr->cbBuf;
565 pBufCmd->u32GuestData = 0;
566 pBufCmd->u64GuestData = (uint64_t)pWbDr;
567
568 return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
569}
570
571void* VBoxMpCrShgsmiTransportCmdCreateWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
572 PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
573{
574
575 const uint32_t cBuffers = 2;
576 const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), cbContextData);
577 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
578 PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
579 if (!pDr)
580 {
581 WARN(("vboxVdmaCBufDrCreate failed"));
582 return NULL;
583 }
584
585 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
586 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
587 PVBOXMP_CRHGSMICMD_WRITE pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITE);
588 CRVBOXHGSMIWRITE *pCmd = &pWrData->Cmd;
589
590 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET;
591 pDr->cbBuf = cbCmd;
592 pDr->rc = VERR_NOT_IMPLEMENTED;
593 pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
594
595 pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
596 pHdr->u32CmdSpecific = 0;
597
598 pBody->cBuffers = cBuffers;
599
600 pCmd->hdr.result = VERR_WRONG_ORDER;
601 pCmd->hdr.u32ClientID = u32ClientID;
602 pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
603 // pCmd->hdr.u32Reserved = 0;
604 pCmd->iBuffer = 1;
605
606 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
607 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
608 pBufCmd->cbBuffer = sizeof (*pCmd);
609 pBufCmd->u32GuestData = 0;
610 pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
611
612 pBufCmd = &pBody->aBuffers[1];
613 pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pvBuffer);
614 pBufCmd->cbBuffer = cbBuffer;
615 pBufCmd->u32GuestData = 0;
616 pBufCmd->u64GuestData = 0;
617
618 return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), void);
619}
620
621int VBoxMpCrShgsmiTransportCmdSubmitWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
622{
623 VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 3, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD));
624 return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendWriteReadAsyncCompletion);
625}
626
627int VBoxMpCrShgsmiTransportCmdSubmitWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
628{
629 VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_WRITE));
630 return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendWriteAsyncCompletion);
631}
632
633void VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
634{
635 VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 3, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD));
636 vboxMpCrShgsmiTransportCmdTermDmaCmd(pCon, pHdr);
637}
638
639void VBoxMpCrShgsmiTransportCmdTermWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
640{
641 VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_WRITE));
642 vboxMpCrShgsmiTransportCmdTermDmaCmd(pCon, pHdr);
643}
644
645# endif
646#endif
647
648static int vboxMpCrCtlAddRef(PVBOXMP_CRCTLCON pCrCtlCon)
649{
650 if (pCrCtlCon->cCrCtlRefs++)
651 return VINF_ALREADY_INITIALIZED;
652
653 int rc = vboxCrCtlCreate(&pCrCtlCon->hCrCtl);
654 if (RT_SUCCESS(rc))
655 {
656 Assert(pCrCtlCon->hCrCtl);
657 return VINF_SUCCESS;
658 }
659
660 WARN(("vboxCrCtlCreate failed, rc (%d)", rc));
661
662 --pCrCtlCon->cCrCtlRefs;
663 return rc;
664}
665
666static int vboxMpCrCtlRelease(PVBOXMP_CRCTLCON pCrCtlCon)
667{
668 Assert(pCrCtlCon->cCrCtlRefs);
669 if (--pCrCtlCon->cCrCtlRefs)
670 {
671 return VINF_SUCCESS;
672 }
673
674 int rc = vboxCrCtlDestroy(pCrCtlCon->hCrCtl);
675 if (RT_SUCCESS(rc))
676 {
677 pCrCtlCon->hCrCtl = NULL;
678 return VINF_SUCCESS;
679 }
680
681 WARN(("vboxCrCtlDestroy failed, rc (%d)", rc));
682
683 ++pCrCtlCon->cCrCtlRefs;
684 return rc;
685}
686
687static int vboxMpCrCtlConSetVersion(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor)
688{
689 CRVBOXHGCMSETVERSION parms;
690 int rc;
691
692 parms.hdr.result = VERR_WRONG_ORDER;
693 parms.hdr.u32ClientID = u32ClientID;
694 parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_VERSION;
695 parms.hdr.cParms = SHCRGL_CPARMS_SET_VERSION;
696
697 parms.vMajor.type = VMMDevHGCMParmType_32bit;
698 parms.vMajor.u.value32 = vMajor;
699 parms.vMinor.type = VMMDevHGCMParmType_32bit;
700 parms.vMinor.u.value32 = vMinor;
701
702 rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
703 if (RT_FAILURE(rc))
704 {
705 WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
706 return rc;
707 }
708
709 if (RT_FAILURE(parms.hdr.result))
710 {
711 WARN(("version validation failed, rc (%d)", parms.hdr.result));
712 return parms.hdr.result;
713 }
714 return VINF_SUCCESS;
715}
716
717static int vboxMpCrCtlConSetPID(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID)
718{
719 CRVBOXHGCMSETPID parms;
720 int rc;
721
722 parms.hdr.result = VERR_WRONG_ORDER;
723 parms.hdr.u32ClientID = u32ClientID;
724 parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_PID;
725 parms.hdr.cParms = SHCRGL_CPARMS_SET_PID;
726
727 parms.u64PID.type = VMMDevHGCMParmType_64bit;
728 parms.u64PID.u.value64 = (uint64_t)PsGetCurrentProcessId();
729
730 Assert(parms.u64PID.u.value64);
731
732 rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
733 if (RT_FAILURE(rc))
734 {
735 WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
736 return rc;
737 }
738
739 if (RT_FAILURE(parms.hdr.result))
740 {
741 WARN(("set PID failed, rc (%d)", parms.hdr.result));
742 return parms.hdr.result;
743 }
744 return VINF_SUCCESS;
745}
746
747int VBoxMpCrCtlConConnect(PVBOXMP_CRCTLCON pCrCtlCon,
748 uint32_t crVersionMajor, uint32_t crVersionMinor,
749 uint32_t *pu32ClientID)
750{
751 uint32_t u32ClientID;
752 int rc = vboxMpCrCtlAddRef(pCrCtlCon);
753 if (RT_SUCCESS(rc))
754 {
755 rc = vboxCrCtlConConnect(pCrCtlCon->hCrCtl, &u32ClientID);
756 if (RT_SUCCESS(rc))
757 {
758 rc = vboxMpCrCtlConSetVersion(pCrCtlCon, u32ClientID, crVersionMajor, crVersionMinor);
759 if (RT_SUCCESS(rc))
760 {
761 rc = vboxMpCrCtlConSetPID(pCrCtlCon, u32ClientID);
762 if (RT_SUCCESS(rc))
763 {
764 *pu32ClientID = u32ClientID;
765 return VINF_SUCCESS;
766 }
767 else
768 {
769 WARN(("vboxMpCrCtlConSetPID failed, rc (%d)", rc));
770 }
771 }
772 else
773 {
774 WARN(("vboxMpCrCtlConSetVersion failed, rc (%d)", rc));
775 }
776 vboxCrCtlConDisconnect(pCrCtlCon->hCrCtl, u32ClientID);
777 }
778 else
779 {
780 WARN(("vboxCrCtlConConnect failed, rc (%d)", rc));
781 }
782 vboxMpCrCtlRelease(pCrCtlCon);
783 }
784 else
785 {
786 WARN(("vboxMpCrCtlAddRef failed, rc (%d)", rc));
787 }
788
789 *pu32ClientID = 0;
790 Assert(RT_FAILURE(rc));
791 return rc;
792}
793
794int VBoxMpCrCtlConDisconnect(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID)
795{
796 int rc = vboxCrCtlConDisconnect(pCrCtlCon->hCrCtl, u32ClientID);
797 if (RT_SUCCESS(rc))
798 {
799 vboxMpCrCtlRelease(pCrCtlCon);
800 return VINF_SUCCESS;
801 }
802 else
803 {
804 WARN(("vboxCrCtlConDisconnect failed, rc (%d)", rc));
805 }
806 return rc;
807}
808
809int VBoxMpCrCtlConCall(PVBOXMP_CRCTLCON pCrCtlCon, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
810{
811 int rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, pData, cbData);
812 if (RT_SUCCESS(rc))
813 return VINF_SUCCESS;
814
815 WARN(("vboxCrCtlConCallUserData failed, rc(%d)", rc));
816 return rc;
817}
818
819int VBoxMpCrCtlConCallUserData(PVBOXMP_CRCTLCON pCrCtlCon, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
820{
821 int rc = vboxCrCtlConCallUserData(pCrCtlCon->hCrCtl, pData, cbData);
822 if (RT_SUCCESS(rc))
823 return VINF_SUCCESS;
824
825 WARN(("vboxCrCtlConCallUserData failed, rc(%d)", rc));
826 return rc;
827}
828
829bool VBoxMpCrCtlConIs3DSupported()
830{
831#ifdef VBOX_WITH_CROGL
832 VBOXMP_CRCTLCON CrCtlCon = {0};
833 uint32_t u32ClientID = 0;
834 int rc = VBoxMpCrCtlConConnect(&CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &u32ClientID);
835 if (RT_FAILURE(rc))
836 {
837 LOGREL(("VBoxMpCrCtlConConnect failed with rc(%d), 3D not supported!"));
838 return false;
839 }
840
841 rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
842 if (RT_FAILURE(rc))
843 WARN(("VBoxMpCrCtlConDisconnect failed, ignoring.."));
844
845 return true;
846#else
847 return false;
848#endif
849}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette