VirtualBox

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

Last change on this file since 48146 was 47603, checked in by vboxsync, 11 years ago

wddm: enable TexPresent

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