VirtualBox

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

Last change on this file since 42054 was 42028, checked in by vboxsync, 13 years ago

wddm/crOpenGL: moreon kernel-based cr commands submission

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/* $Id: VBoxMPCr.cpp 42028 2012-07-05 15:22:55Z 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# include <cr_pack.h>
29
30typedef struct VBOXMP_CRSHGSMICON_BUFDR
31{
32 uint32_t cbBuf;
33 void *pvBuf;
34} VBOXMP_CRSHGSMICON_BUFDR, *PVBOXMP_CRSHGSMICON_BUFDR;
35
36typedef struct VBOXMP_CRSHGSMICON_BUFDR_CACHE
37{
38 volatile PVBOXMP_CRSHGSMICON_BUFDR pBufDr;
39} VBOXMP_CRSHGSMICON_BUFDR_CACHE, *PVBOXMP_CRSHGSMICON_BUFDR_CACHE;
40
41typedef struct VBOXMP_CRSHGSMICON
42{
43 PVBOXMP_DEVEXT pDevExt;
44 PVBOXMP_CRCTLCON pCtlCon;
45 uint32_t u32ClientID;
46 VBOXMP_CRSHGSMICON_BUFDR_CACHE CmdDrCache;
47 VBOXMP_CRSHGSMICON_BUFDR_CACHE WbDrCache;
48} VBOXMP_CRSHGSMICON, *PVBOXMP_CRSHGSMICON;
49
50typedef struct VBOXMP_CRSHGSMIPACKER
51{
52 PVBOXMP_CRSHGSMICON pCon;
53 CRPackContext CrPacker;
54 CRPackBuffer CrBuffer;
55} VBOXMP_CRSHGSMIPACKER, *PVBOXMP_CRSHGSMIPACKER;
56
57static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
58{
59 return VBoxSHGSMIHeapBufferAlloc(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, cbData);
60}
61
62static VBOXVIDEOOFFSET vboxMpCrShgsmiBufferOffset(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
63{
64 return HGSMIPointerToOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (const HGSMIBUFFERHEADER *)pvBuffer);
65}
66
67static void vboxMpCrShgsmiBufferFree(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
68{
69 VBoxSHGSMIHeapBufferFree(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pvBuffer);
70}
71
72static void* vboxMpCrShgsmiConAlloc(PVBOXMP_CRSHGSMICON pCon, uint32_t cbBuffer)
73{
74 return vboxMpCrShgsmiBufferAlloc(pCon->pDevExt, cbBuffer);
75}
76
77static VBOXVIDEOOFFSET vboxMpCrShgsmiConBufOffset(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
78{
79 return vboxMpCrShgsmiBufferOffset(pCon->pDevExt, pvBuffer);
80}
81
82
83static void vboxMpCrShgsmiConFree(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
84{
85 vboxMpCrShgsmiBufferFree(pCon->pDevExt, pvBuffer);
86}
87
88#define VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) VBOXWDDM_ROUNDBOUND((VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[_cBuffers]))), 8)
89#define VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(_pDr, _cBuffers, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers)))
90#define VBOXMP_CRSHGSMICON_DR_SIZE(_cBuffers, _cbCmdBuf) ( VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) + _cbCmdBuf)
91
92static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr, uint32_t cbRequested)
93{
94 if (pDr->cbBuf >= cbRequested)
95 return VINF_SUCCESS;
96
97 if (pDr->pvBuf)
98 vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
99
100 pDr->pvBuf = vboxMpCrShgsmiConAlloc(pCon, cbRequested);
101 if (!pDr->pvBuf)
102 {
103 WARN(("vboxMpCrShgsmiConAlloc failed"));
104 pDr->cbBuf = 0;
105 return VERR_NO_MEMORY;
106 }
107
108 pDr->cbBuf = cbRequested;
109 return VINF_SUCCESS;
110}
111
112static void vboxMpCrShgsmiBufCacheFree(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr)
113{
114 if (ASMAtomicCmpXchgPtr(&pCache->pBufDr, pDr, NULL))
115 return;
116
117 /* the value is already cached, free the current one */
118 vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
119 vboxWddmMemFree(pDr);
120}
121
122static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheGetAllocDr(PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
123{
124 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)ASMAtomicXchgPtr((void * volatile *)&pCache->pBufDr, NULL);
125 if (!pBufDr)
126 {
127 pBufDr = (PVBOXMP_CRSHGSMICON_BUFDR)vboxWddmMemAllocZero(sizeof (*pBufDr));
128 if (!pBufDr)
129 {
130 WARN(("vboxWddmMemAllocZero failed!"));
131 return NULL;
132 }
133 }
134 return pBufDr;
135}
136
137static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
138{
139 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
140 int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
141 if (RT_SUCCESS(rc))
142 return pBufDr;
143
144 WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
145
146 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
147 return NULL;
148}
149
150static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
151{
152 PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
153
154 if (pBufDr->cbBuf)
155 return pBufDr;
156
157 int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
158 if (RT_SUCCESS(rc))
159 return pBufDr;
160
161 WARN(("vboxMpCrShgsmiBufCacheBufReinit failed, rc %d", rc));
162
163 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pBufDr);
164 return NULL;
165}
166
167
168static int vboxMpCrShgsmiBufCacheInit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
169{
170 memset(pCache, 0, sizeof (*pCache));
171 return VINF_SUCCESS;
172}
173
174static void vboxMpCrShgsmiBufCacheTerm(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
175{
176 if (pCache->pBufDr)
177 vboxMpCrShgsmiBufCacheFree(pCon, pCache, pCache->pBufDr);
178}
179
180static int vboxMpCrShgsmiConConnect(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_DEVEXT pDevExt, PVBOXMP_CRCTLCON pCrCtlCon)
181{
182 memset(pCon, 0, sizeof (*pCon));
183 int rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->CmdDrCache);
184 if (RT_SUCCESS(rc))
185 {
186 rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->WbDrCache);
187 if (RT_SUCCESS(rc))
188 {
189 rc = VBoxMpCrCtlConConnect(pCrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pCon->u32ClientID);
190 if (RT_SUCCESS(rc))
191 {
192 pCon->pDevExt = pDevExt;
193 pCon->pCtlCon = pCrCtlCon;
194 return VINF_SUCCESS;
195 }
196 else
197 {
198 WARN(("VBoxMpCrCtlConConnect failed rc %d", rc));
199 }
200 vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
201 }
202 else
203 {
204 WARN(("vboxMpCrShgsmiBufCacheInit2 failed rc %d", rc));
205 }
206 vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
207 }
208 else
209 {
210 WARN(("vboxMpCrShgsmiBufCacheInit1 failed rc %d", rc));
211 }
212
213 return rc;
214}
215
216static int vboxMpCrShgsmiConDisconnect(PVBOXMP_CRSHGSMICON pCon)
217{
218 int rc = VBoxMpCrCtlConDisconnect(pCon->pCtlCon, pCon->u32ClientID);
219 if (RT_FAILURE(rc))
220 {
221 WARN(("VBoxMpCrCtlConDisconnect failed rc %d", rc));
222 return rc;
223 }
224
225 vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
226 vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
227
228 return VINF_SUCCESS;
229}
230
231typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMICON_SEND_COMPLETION(PVBOXMP_CRSHGSMICON pCon, void *pvRx, uint32_t cbRx, void *pvCtx);
232typedef FNVBOXMP_CRSHGSMICON_SEND_COMPLETION *PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION;
233
234typedef struct VBOXMP_CRSHGSMICON_SEND_COMPLETION
235{
236 PVBOXMP_CRSHGSMICON pCon;
237 PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pvnCompletion;
238 void *pvCompletion;
239} VBOXMP_CRSHGSMICON_SEND_COMPLETION, *PVBOXMP_CRSHGSMICON_SEND_COMPLETION;
240
241static DECLCALLBACK(VOID) vboxMpCrShgsmiConSendAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
242{
243 /* we should be called from our DPC routine */
244 Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
245
246 PVBOXMP_CRSHGSMICON_SEND_COMPLETION pData = (PVBOXMP_CRSHGSMICON_SEND_COMPLETION)pvContext;
247 PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pCmd);
248 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
249 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
250 UINT cBufs = pBody->cBuffers;
251 /* the first one is a command buffer: obtain it and get the result */
252
253 /* if write back buffer is too small, issue read command.
254 * we can use exactly the same command buffer for it */
255 /* impl */
256 Assert(0);
257}
258
259static int vboxMpCrShgsmiConSendAsync(PVBOXMP_CRSHGSMICON pCon, void *pvTx, uint32_t cbTx, PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pfnCompletion, void *pvCompletion)
260{
261 const uint32_t cBuffers = 3;
262 const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (CRVBOXHGSMIWRITEREAD));
263 PVBOXMP_CRSHGSMICON_BUFDR pCmdDr = vboxMpCrShgsmiBufCacheAlloc(pCon, &pCon->CmdDrCache, cbCmd);
264 if (!pCmdDr)
265 {
266 WARN(("vboxMpCrShgsmiBufCacheAlloc for cmd dr failed"));
267 return VERR_NO_MEMORY;
268 }
269 PVBOXMP_CRSHGSMICON_BUFDR pWbDr = vboxMpCrShgsmiBufCacheAllocAny(pCon, &pCon->WbDrCache, 1000);
270 if (!pWbDr)
271 {
272 WARN(("vboxMpCrShgsmiBufCacheAlloc for wb dr failed"));
273 vboxMpCrShgsmiBufCacheFree(pCon, &pCon->CmdDrCache, pCmdDr);
274 return VERR_NO_MEMORY;
275 }
276
277 PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pCmdDr->pvBuf;
278 pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
279 pDr->cbBuf = cbCmd;
280 pDr->rc = VERR_NOT_IMPLEMENTED;
281
282 PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
283 pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
284 pHdr->u32CmdSpecific = 0;
285 VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
286 pBody->cBuffers = cBuffers;
287 CRVBOXHGSMIWRITEREAD *pCmd = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pDr, cBuffers, CRVBOXHGSMIWRITEREAD);
288 pCmd->hdr.result = VERR_WRONG_ORDER;
289 pCmd->hdr.u32ClientID = pCon->u32ClientID;
290 pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
291 // pCmd->hdr.u32Reserved = 0;
292 pCmd->iBuffer = 1;
293 pCmd->iWriteback = 2;
294 pCmd->cbWriteback = 0;
295
296 VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
297 pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pCmd);
298 pBufCmd->cbBuffer = sizeof (*pCmd);
299 pBufCmd->u32GuestData = 0;
300 pBufCmd->u64GuestData = (uint64_t)pCmdDr;
301
302 pBufCmd = &pBody->aBuffers[1];
303 pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pvTx);
304 pBufCmd->cbBuffer = cbTx;
305 pBufCmd->u32GuestData = 0;
306 pBufCmd->u64GuestData = 0;
307
308 pBufCmd = &pBody->aBuffers[2];
309 pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pWbDr->pvBuf);
310 pBufCmd->cbBuffer = pWbDr->cbBuf;
311 pBufCmd->u32GuestData = 0;
312 pBufCmd->u64GuestData = (uint64_t)pWbDr;
313
314 PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
315 PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
316 vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxMpCrShgsmiConSendAsyncCompletion, pDr);
317 /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
318 vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
319 int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
320 if (RT_SUCCESS(rc))
321 {
322 return STATUS_SUCCESS;
323 }
324
325 /* impl failure branch */
326 Assert(0);
327 return rc;
328}
329
330static CRMessageOpcodes *
331vboxMpCrPackerPrependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
332{
333 UINT num_opcodes;
334 CRMessageOpcodes *hdr;
335
336 Assert(buf);
337 Assert(buf->opcode_current < buf->opcode_start);
338 Assert(buf->opcode_current >= buf->opcode_end);
339 Assert(buf->data_current > buf->data_start);
340 Assert(buf->data_current <= buf->data_end);
341
342 num_opcodes = (UINT)(buf->opcode_start - buf->opcode_current);
343 hdr = (CRMessageOpcodes *)
344 ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
345
346 Assert((void *) hdr >= buf->pack);
347
348 hdr->header.type = CR_MESSAGE_OPCODES;
349 hdr->numOpcodes = num_opcodes;
350
351 *len = (UINT)(buf->data_current - (unsigned char *) hdr);
352
353 return hdr;
354}
355
356static void vboxMpCrShgsmiPackerCbFlush(void *pvFlush)
357{
358 PVBOXMP_CRSHGSMIPACKER pPacker = (PVBOXMP_CRSHGSMIPACKER)pvFlush;
359
360 crPackReleaseBuffer(&pPacker->CrPacker);
361
362 if (pPacker->CrBuffer.opcode_current != pPacker->CrBuffer.opcode_start)
363 {
364 CRMessageOpcodes *pHdr;
365 unsigned int len;
366 pHdr = vboxMpCrPackerPrependHeader(&pPacker->CrBuffer, &len, 0);
367
368 /*Send*/
369 }
370
371
372 crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
373 crPackResetPointers(&pPacker->CrPacker);
374}
375
376int vboxMpCrShgsmiPackerInit(PVBOXMP_CRSHGSMIPACKER pPacker, PVBOXMP_CRSHGSMICON pCon)
377{
378 memset(pPacker, 0, sizeof (*pPacker));
379
380 static const HGSMISIZE cbBuffer = 1000;
381 void *pvBuffer = vboxMpCrShgsmiConAlloc(pCon, cbBuffer);
382 if (!pvBuffer)
383 {
384 WARN(("vboxMpCrShgsmiConAlloc failed"));
385 return VERR_NO_MEMORY;
386 }
387 pPacker->pCon = pCon;
388 crPackInitBuffer(&pPacker->CrBuffer, pvBuffer, cbBuffer, cbBuffer);
389 crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
390 crPackFlushFunc(&pPacker->CrPacker, vboxMpCrShgsmiPackerCbFlush);
391 crPackFlushArg(&pPacker->CrPacker, pPacker);
392// crPackSendHugeFunc( thread->packer, packspuHuge );
393 return VINF_SUCCESS;
394}
395# endif
396#endif
397
398static int vboxMpCrCtlAddRef(PVBOXMP_CRCTLCON pCrCtlCon)
399{
400 if (pCrCtlCon->cCrCtlRefs++)
401 return VINF_ALREADY_INITIALIZED;
402
403 int rc = vboxCrCtlCreate(&pCrCtlCon->hCrCtl);
404 if (RT_SUCCESS(rc))
405 {
406 Assert(pCrCtlCon->hCrCtl);
407 return VINF_SUCCESS;
408 }
409
410 WARN(("vboxCrCtlCreate failed, rc (%d)", rc));
411
412 --pCrCtlCon->cCrCtlRefs;
413 return rc;
414}
415
416static int vboxMpCrCtlRelease(PVBOXMP_CRCTLCON pCrCtlCon)
417{
418 Assert(pCrCtlCon->cCrCtlRefs);
419 if (--pCrCtlCon->cCrCtlRefs)
420 {
421 return VINF_SUCCESS;
422 }
423
424 int rc = vboxCrCtlDestroy(pCrCtlCon->hCrCtl);
425 if (RT_SUCCESS(rc))
426 {
427 pCrCtlCon->hCrCtl = NULL;
428 return VINF_SUCCESS;
429 }
430
431 WARN(("vboxCrCtlDestroy failed, rc (%d)", rc));
432
433 ++pCrCtlCon->cCrCtlRefs;
434 return rc;
435}
436
437static int vboxMpCrCtlConSetVersion(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor)
438{
439 CRVBOXHGCMSETVERSION parms;
440 int rc;
441
442 parms.hdr.result = VERR_WRONG_ORDER;
443 parms.hdr.u32ClientID = u32ClientID;
444 parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_VERSION;
445 parms.hdr.cParms = SHCRGL_CPARMS_SET_VERSION;
446
447 parms.vMajor.type = VMMDevHGCMParmType_32bit;
448 parms.vMajor.u.value32 = vMajor;
449 parms.vMinor.type = VMMDevHGCMParmType_32bit;
450 parms.vMinor.u.value32 = vMinor;
451
452 rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
453 if (RT_FAILURE(rc))
454 {
455 WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
456 return rc;
457 }
458
459 if (RT_FAILURE(parms.hdr.result))
460 {
461 WARN(("version validation failed, rc (%d)", parms.hdr.result));
462 return parms.hdr.result;
463 }
464 return VINF_SUCCESS;
465}
466
467static int vboxMpCrCtlConSetPID(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID)
468{
469 CRVBOXHGCMSETPID parms;
470 int rc;
471
472 parms.hdr.result = VERR_WRONG_ORDER;
473 parms.hdr.u32ClientID = u32ClientID;
474 parms.hdr.u32Function = SHCRGL_GUEST_FN_SET_PID;
475 parms.hdr.cParms = SHCRGL_CPARMS_SET_PID;
476
477 parms.u64PID.type = VMMDevHGCMParmType_64bit;
478 parms.u64PID.u.value64 = (uint64_t)PsGetCurrentProcessId();
479
480 Assert(parms.u64PID.u.value64);
481
482 rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
483 if (RT_FAILURE(rc))
484 {
485 WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
486 return rc;
487 }
488
489 if (RT_FAILURE(parms.hdr.result))
490 {
491 WARN(("set PID failed, rc (%d)", parms.hdr.result));
492 return parms.hdr.result;
493 }
494 return VINF_SUCCESS;
495}
496
497int VBoxMpCrCtlConConnect(PVBOXMP_CRCTLCON pCrCtlCon,
498 uint32_t crVersionMajor, uint32_t crVersionMinor,
499 uint32_t *pu32ClientID)
500{
501 uint32_t u32ClientID;
502 int rc = vboxMpCrCtlAddRef(pCrCtlCon);
503 if (RT_SUCCESS(rc))
504 {
505 rc = vboxCrCtlConConnect(pCrCtlCon->hCrCtl, &u32ClientID);
506 if (RT_SUCCESS(rc))
507 {
508 rc = vboxMpCrCtlConSetVersion(pCrCtlCon, u32ClientID, crVersionMajor, crVersionMinor);
509 if (RT_SUCCESS(rc))
510 {
511 rc = vboxMpCrCtlConSetPID(pCrCtlCon, u32ClientID);
512 if (RT_SUCCESS(rc))
513 {
514 *pu32ClientID = u32ClientID;
515 return VINF_SUCCESS;
516 }
517 else
518 {
519 WARN(("vboxMpCrCtlConSetPID failed, rc (%d)", rc));
520 }
521 }
522 else
523 {
524 WARN(("vboxMpCrCtlConSetVersion failed, rc (%d)", rc));
525 }
526 vboxCrCtlConDisconnect(pCrCtlCon->hCrCtl, u32ClientID);
527 }
528 else
529 {
530 WARN(("vboxCrCtlConConnect failed, rc (%d)", rc));
531 }
532 vboxMpCrCtlRelease(pCrCtlCon);
533 }
534 else
535 {
536 WARN(("vboxMpCrCtlAddRef failed, rc (%d)", rc));
537 }
538
539 *pu32ClientID = 0;
540 Assert(RT_FAILURE(rc));
541 return rc;
542}
543
544int VBoxMpCrCtlConDisconnect(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID)
545{
546 int rc = vboxCrCtlConDisconnect(pCrCtlCon->hCrCtl, u32ClientID);
547 if (RT_SUCCESS(rc))
548 {
549 vboxMpCrCtlRelease(pCrCtlCon);
550 return VINF_SUCCESS;
551 }
552 else
553 {
554 WARN(("vboxCrCtlConDisconnect failed, rc (%d)", rc));
555 }
556 return rc;
557}
558
559int VBoxMpCrCtlConCall(PVBOXMP_CRCTLCON pCrCtlCon, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
560{
561 int rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, pData, cbData);
562 if (RT_SUCCESS(rc))
563 return VINF_SUCCESS;
564
565 WARN(("vboxCrCtlConCallUserData failed, rc(%d)", rc));
566 return rc;
567}
568
569int VBoxMpCrCtlConCallUserData(PVBOXMP_CRCTLCON pCrCtlCon, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
570{
571 int rc = vboxCrCtlConCallUserData(pCrCtlCon->hCrCtl, pData, cbData);
572 if (RT_SUCCESS(rc))
573 return VINF_SUCCESS;
574
575 WARN(("vboxCrCtlConCallUserData failed, rc(%d)", rc));
576 return rc;
577}
578
579bool VBoxMpCrCtlConIs3DSupported()
580{
581#ifdef VBOX_WITH_CROGL
582 VBOXMP_CRCTLCON CrCtlCon = {0};
583 uint32_t u32ClientID = 0;
584 int rc = VBoxMpCrCtlConConnect(&CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &u32ClientID);
585 if (RT_FAILURE(rc))
586 {
587 LOGREL(("VBoxMpCrCtlConConnect failed with rc(%d), 3D not supported!"));
588 return false;
589 }
590
591 rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
592 if (RT_FAILURE(rc))
593 WARN(("VBoxMpCrCtlConDisconnect failed, ignoring.."));
594
595 return true;
596#else
597 return false;
598#endif
599}
Note: See TracBrowser for help on using the repository browser.

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