VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/gallium/GaDdi.cpp@ 98103

Last change on this file since 98103 was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 192.3 KB
Line 
1/* $Id: GaDdi.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * WDDM D3DDDI callbacks implemented for the Gallium based driver.
4 */
5
6/*
7 * Copyright (C) 2017-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "VBoxGallium.h"
29//#include "../../../common/wddm/VBoxMPIf.h"
30#include "../VBoxDispD3DCmn.h"
31#include "../VBoxDispD3D.h"
32
33#include "GaDxva.h"
34
35/* Copy surface data from D3DPOOL_DEFAULT to D3DPOOL_SYSTEMMEM */
36static HRESULT gaSurfaceCopyD2S(IDirect3DDevice9 *pDevice,
37 D3DDDIFORMAT srcFormat,
38 IDirect3DSurface9 *pSrcSurf,
39 const RECT *pSrcRect,
40 D3DDDIFORMAT dstFormat,
41 IDirect3DSurface9 *pDstSurf,
42 const POINT *pDstPoint)
43{
44 RT_NOREF(pDevice);
45
46 AssertReturn(pSrcRect->right >= pSrcRect->left, E_NOTIMPL);
47 AssertReturn(pSrcRect->bottom >= pSrcRect->top, E_NOTIMPL);
48 AssertReturn(dstFormat == srcFormat, E_NOTIMPL);
49
50 RECT dstRect;
51 dstRect.left = pDstPoint->x;
52 dstRect.top = pDstPoint->y;
53 dstRect.right = pDstPoint->x + (pSrcRect->right - pSrcRect->left);
54 dstRect.bottom = pDstPoint->y + (pSrcRect->bottom - pSrcRect->top);
55
56 D3DLOCKED_RECT SrcLockedRect;
57 HRESULT hr = pSrcSurf->LockRect(&SrcLockedRect, pSrcRect, D3DLOCK_READONLY);
58 Assert(hr == S_OK);
59 if (SUCCEEDED(hr))
60 {
61 D3DLOCKED_RECT DstLockedRect;
62 hr = pDstSurf->LockRect(&DstLockedRect, &dstRect, D3DLOCK_DISCARD);
63 Assert(hr == S_OK);
64 if (SUCCEEDED(hr))
65 {
66 const uint8_t *pu8Src = (uint8_t *)SrcLockedRect.pBits;
67 uint8_t *pu8Dst = (uint8_t *)DstLockedRect.pBits;
68
69 const uint32_t cbLine = vboxWddmCalcRowSize(pSrcRect->left, pSrcRect->right, srcFormat);
70 const uint32_t cRows = vboxWddmCalcNumRows(pSrcRect->top, pSrcRect->bottom, srcFormat);
71 for (uint32_t i = 0; i < cRows; ++i)
72 {
73 memcpy(pu8Dst, pu8Src, cbLine);
74 pu8Src += SrcLockedRect.Pitch;
75 pu8Dst += DstLockedRect.Pitch;
76 }
77
78 hr = pDstSurf->UnlockRect();
79 Assert(hr == S_OK);
80 }
81
82 hr = pSrcSurf->UnlockRect();
83 Assert(hr == S_OK);
84 }
85
86 return hr;
87}
88
89
90HRESULT APIENTRY GaDdiBlt(HANDLE hDevice, const D3DDDIARG_BLT *pData)
91{
92 VBOXVDBG_BREAK_DDI();
93
94 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
95 vboxVDbgPrintF(("src %p[%d] %d,%d %d,%d dst %p[%d] %d,%d %d,%d ColorKey 0x%08X Flags 0x%08X\n",
96 pData->hSrcResource, pData->SrcSubResourceIndex,
97 pData->SrcRect.left, pData->SrcRect.top, pData->SrcRect.right, pData->SrcRect.bottom,
98 pData->hDstResource, pData->DstSubResourceIndex,
99 pData->DstRect.left, pData->DstRect.top, pData->DstRect.right, pData->DstRect.bottom,
100 pData->ColorKey, pData->Flags.Value));
101
102 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
103 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
104
105 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
106 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
107
108 AssertReturn(pDstRc->cAllocations > pData->DstSubResourceIndex, E_INVALIDARG);
109 AssertReturn(pSrcRc->cAllocations > pData->SrcSubResourceIndex, E_INVALIDARG);
110
111 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
112// PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
113
114 IDirect3DSurface9 *pSrcSurfIf = NULL;
115 IDirect3DSurface9 *pDstSurfIf = NULL;
116
117 HRESULT hr;
118 hr = VBoxD3DIfSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
119 Assert(hr == S_OK);
120 if (hr == S_OK)
121 {
122 Assert(pDstSurfIf);
123
124 hr = VBoxD3DIfSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
125 Assert(hr == S_OK);
126 if (hr == S_OK)
127 {
128 Assert(pSrcSurfIf);
129
130 /*
131 * Use appropriate method depending on where the resource is allocated (system memory or default pool).
132 * @todo Store the actual pool, where the resorce was created, in the VBOXWDDMDISP_RESOURCE structure.
133 */
134 const D3DPOOL poolSrc = vboxDDI2D3DPool(pSrcRc->RcDesc.enmPool);
135 const D3DPOOL poolDst = vboxDDI2D3DPool(pDstRc->RcDesc.enmPool);
136
137 if (poolSrc == D3DPOOL_SYSTEMMEM)
138 {
139 if (poolDst == D3DPOOL_SYSTEMMEM)
140 {
141 /* D3DPOOL_SYSTEMMEM -> D3DPOOL_SYSTEMMEM
142 *
143 * "If both the source and destination allocations are in system memory,
144 * the driver should synchronize as necessary but should not copy the contents
145 * of the source surface. The Direct3D runtime copies the contents after the call
146 * to pfnRenderCb returns. "
147 *
148 * @todo Later, if necessary. memcpy?
149 */
150 AssertFailed();
151 hr = E_NOTIMPL;
152 }
153 else
154 {
155 /* D3DPOOL_SYSTEMMEM -> D3DPOOL_DEFAULT
156 * UpdateSurface allows copying from memory to surface.
157 * @todo Stretching.
158 */
159 Assert(pData->DstRect.right - pData->DstRect.left == pData->SrcRect.right - pData->SrcRect.left);
160 Assert(pData->DstRect.bottom - pData->DstRect.top == pData->SrcRect.bottom - pData->SrcRect.top);
161
162 POINT pointDst;
163 pointDst.x = pData->DstRect.left;
164 pointDst.y = pData->DstRect.top;
165 hr = pDevice9If->UpdateSurface(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &pointDst);
166 Assert(hr == S_OK);
167 }
168 }
169 else
170 {
171 if (poolDst == D3DPOOL_SYSTEMMEM)
172 {
173 /* D3DPOOL_DEFAULT -> D3DPOOL_SYSTEMMEM
174 * @todo GetRenderTargetData, and rectangle copy?
175 * Lock both and memcpy?
176 */
177 Assert(pData->DstRect.right - pData->DstRect.left == pData->SrcRect.right - pData->SrcRect.left);
178 Assert(pData->DstRect.bottom - pData->DstRect.top == pData->SrcRect.bottom - pData->SrcRect.top);
179
180// seems to work AssertFailed(); /** @todo test this */
181
182 POINT pointDst;
183 pointDst.x = pData->DstRect.left;
184 pointDst.y = pData->DstRect.top;
185 hr = gaSurfaceCopyD2S(pDevice9If,
186 pSrcRc->RcDesc.enmFormat, pSrcSurfIf, &pData->SrcRect,
187 pDstRc->RcDesc.enmFormat, pDstSurfIf, &pointDst);
188 Assert(hr == S_OK);
189 }
190 else
191 {
192 /* D3DPOOL_DEFAULT -> D3DPOOL_DEFAULT
193 * Can use StretchRect.
194 */
195 const D3DTEXTUREFILTERTYPE Filter = vboxDDI2D3DBltFlags(pData->Flags);
196
197 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
198 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
199
200 if (!pSrcRc->RcDesc.fFlags.RenderTarget || pDstRc->RcDesc.fFlags.RenderTarget)
201 {
202 /** @todo It seems that Gallium flips the image vertically if scaling is applied.
203 * In this case the SVGA driver draws a quad using the source as texture
204 * and apparently texture coords are set using the OpenGL coodinate system
205 * with the vertical axis going up for quad vertices, while in D3D the texture
206 * vertical axis goes down.
207 *
208 * The result is that StrechRect produces different results:
209 * - if scaling is required then the image will be flipped;
210 * - if scaling is NOT required then the image will be correct.
211 *
212 * Figure out who is to blame for the vertical flipping.
213 * At the moment NineDevice9_StretchRect includes VBox hack, see "Hack. Flip src Y."
214 */
215 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &pData->DstRect, Filter);
216 Assert(hr == S_OK);
217 }
218 else
219 {
220 /* If src is a render target and destination is not, StretchRect will fail.
221 * Instead use a very slow path: GetRenderTargetData + UpdateSurface with a tmp surface.
222 */
223 const UINT Width = pSrcAlloc->SurfDesc.width;
224 const UINT Height = pSrcAlloc->SurfDesc.height;
225 const UINT Levels = 1;
226 const DWORD Usage = 0;
227 const D3DFORMAT Format = vboxDDI2D3DFormat(pSrcRc->RcDesc.enmFormat);
228 const D3DPOOL Pool = D3DPOOL_SYSTEMMEM;
229 IDirect3DTexture9 *pTmpTexture;
230 hr = pDevice9If->CreateTexture(Width, Height, Levels, Usage, Format, Pool, &pTmpTexture, NULL);
231 Assert(hr == D3D_OK);
232 if (SUCCEEDED(hr))
233 {
234 IDirect3DSurface9 *pTmpSurface;
235 hr = pTmpTexture->GetSurfaceLevel(0, &pTmpSurface);
236 Assert(hr == D3D_OK);
237 if (SUCCEEDED(hr))
238 {
239 hr = pDevice9If->GetRenderTargetData(pSrcSurfIf, pTmpSurface);
240 Assert(hr == D3D_OK);
241 if (SUCCEEDED(hr))
242 {
243 Assert(pData->DstRect.right - pData->DstRect.left == pData->SrcRect.right - pData->SrcRect.left);
244 Assert(pData->DstRect.bottom - pData->DstRect.top == pData->SrcRect.bottom - pData->SrcRect.top);
245
246 POINT pointDst;
247 pointDst.x = pData->DstRect.left;
248 pointDst.y = pData->DstRect.top;
249
250 hr = pDevice9If->UpdateSurface(pTmpSurface, &pData->SrcRect, pDstSurfIf, &pointDst);
251 Assert(hr == D3D_OK);
252 }
253
254 pTmpSurface->Release();
255 }
256
257 pTmpTexture->Release();
258 }
259 }
260 }
261 }
262
263 pSrcSurfIf->Release();
264 }
265
266 pDstSurfIf->Release();
267 }
268
269 if (hr != S_OK)
270 {
271 /** @todo fallback to memcpy or whatever ? */
272 Assert(0);
273 }
274
275 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
276 return hr;
277}
278
279HRESULT APIENTRY GaDdiTexBlt(HANDLE hDevice, const D3DDDIARG_TEXBLT *pData)
280{
281 VBOXVDBG_BREAK_DDI();
282
283 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
284 vboxVDbgPrintF(("hDst %p, hSrc %p, face %d, dst %d,%d src %d,%d %d,%d\n",
285 pData->hDstResource,
286 pData->hSrcResource,
287 pData->CubeMapFace,
288 pData->DstPoint.x, pData->DstPoint.y,
289 pData->SrcRect.left, pData->SrcRect.top, pData->SrcRect.right, pData->SrcRect.bottom));
290
291 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
292 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
293
294 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
295 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
296
297 Assert( pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
298 || pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE);
299 Assert( pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
300 || pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE);
301 Assert(pSrcRc->aAllocations[0].enmD3DIfType == pDstRc->aAllocations[0].enmD3DIfType);
302 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
303 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
304
305 HRESULT hr = S_OK;
306/// @todo VBOXVDBG_CHECK_SMSYNC(pDstRc);
307/// @todo VBOXVDBG_CHECK_SMSYNC(pSrcRc);
308
309 if ( pSrcRc->aAllocations[0].SurfDesc.d3dWidth == pDstRc->aAllocations[0].SurfDesc.d3dWidth
310 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
311 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
312 && pData->DstPoint.x == 0
313 && pData->DstPoint.y == 0
314 && pData->SrcRect.left == 0
315 && pData->SrcRect.top == 0
316 && pData->SrcRect.right - pData->SrcRect.left == (LONG)pSrcRc->aAllocations[0].SurfDesc.width
317 && pData->SrcRect.bottom - pData->SrcRect.top == (LONG)pSrcRc->aAllocations[0].SurfDesc.height)
318 {
319 IDirect3DBaseTexture9 *pD3DIfSrcTex = (IDirect3DBaseTexture9*)pSrcRc->aAllocations[0].pD3DIf;
320 IDirect3DBaseTexture9 *pD3DIfDstTex = (IDirect3DBaseTexture9*)pDstRc->aAllocations[0].pD3DIf;
321 Assert(pD3DIfSrcTex);
322 Assert(pD3DIfDstTex);
323 VBOXVDBG_CHECK_TEXBLT(
324 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex); Assert(hr == S_OK),
325 pSrcRc,
326 &pData->SrcRect,
327 pDstRc,
328 &pData->DstPoint);
329 }
330 else
331 {
332 Assert(pDstRc->aAllocations[0].enmD3DIfType != VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
333 Assert(pSrcRc->aAllocations[0].enmD3DIfType != VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
334 Assert(pDstRc->RcDesc.MipLevels == 1);
335 Assert(pSrcRc->RcDesc.MipLevels == 1);
336
337 /// @todo Miplevels
338 IDirect3DSurface9 *pSrcSurfIf = NULL;
339 IDirect3DSurface9 *pDstSurfIf = NULL;
340 hr = VBoxD3DIfSurfGet(pDstRc, 0, &pDstSurfIf);
341 Assert(hr == S_OK);
342 if (hr == S_OK)
343 {
344 hr = VBoxD3DIfSurfGet(pSrcRc, 0, &pSrcSurfIf);
345 Assert(hr == S_OK);
346 if (hr == S_OK)
347 {
348 VBOXVDBG_CHECK_TEXBLT(hr = pDevice9If->UpdateSurface(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &pData->DstPoint);
349 Assert(hr == S_OK),
350 pSrcRc, &pData->SrcRect,
351 pDstRc, &pData->DstPoint);
352 pSrcSurfIf->Release();
353 }
354 pDstSurfIf->Release();
355 }
356 }
357
358 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
359 return hr;
360}
361
362static void wddmD3DBOXOrder(D3DBOX *pBox)
363{
364 UINT uTmp;
365 if (pBox->Left > pBox->Right)
366 {
367 uTmp = pBox->Left;
368 pBox->Left = pBox->Right;
369 pBox->Right = uTmp;
370 }
371 if (pBox->Top > pBox->Bottom)
372 {
373 uTmp = pBox->Top;
374 pBox->Top = pBox->Bottom;
375 pBox->Bottom = uTmp;
376 }
377 if (pBox->Front > pBox->Back)
378 {
379 uTmp = pBox->Front;
380 pBox->Front = pBox->Back;
381 pBox->Back = uTmp;
382 }
383}
384
385UINT wddmCoordDivBy2(UINT v)
386{
387 if (v > 0)
388 {
389 v >>= 1;
390 if (v > 0)
391 return v;
392 return 1;
393 }
394 return 0;
395}
396
397void wddmD3DBoxDivBy2(D3DBOX *pBox)
398{
399 pBox->Left = wddmCoordDivBy2(pBox->Left);
400 pBox->Top = wddmCoordDivBy2(pBox->Top);
401 pBox->Right = wddmCoordDivBy2(pBox->Right);
402 pBox->Bottom = wddmCoordDivBy2(pBox->Bottom);
403 pBox->Front = wddmCoordDivBy2(pBox->Front);
404 pBox->Back = wddmCoordDivBy2(pBox->Back);
405}
406
407HRESULT APIENTRY GaDdiVolBlt(HANDLE hDevice, const D3DDDIARG_VOLUMEBLT *pData)
408{
409 VBOXVDBG_BREAK_DDI();
410
411 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
412 vboxVDbgPrintF(("hDst %p, hSrc %p, dst %d,%d,%d src LT %d,%d RB %d,%d FB %d,%d\n",
413 pData->hDstResource,
414 pData->hSrcResource,
415 pData->DstX, pData->DstY, pData->DstZ,
416 pData->SrcBox.Left, pData->SrcBox.Top,
417 pData->SrcBox.Right, pData->SrcBox.Bottom,
418 pData->SrcBox.Front, pData->SrcBox.Back));
419
420 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
421 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
422
423 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
424 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
425
426 Assert(pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
427 Assert(pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
428 Assert(pSrcRc->cAllocations == pDstRc->cAllocations);
429 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
430 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
431
432 HRESULT hr = S_OK;
433
434 RT_NOREF(pDevice9If);
435
436 INT iWidth = pData->SrcBox.Right - pData->SrcBox.Left;
437 INT iHeight = pData->SrcBox.Bottom - pData->SrcBox.Top;
438 INT iDepth = pData->SrcBox.Back - pData->SrcBox.Front;
439
440 D3DBOX srcBox;
441 srcBox.Left = pData->SrcBox.Left;
442 srcBox.Top = pData->SrcBox.Top;
443 srcBox.Right = pData->SrcBox.Right;
444 srcBox.Bottom = pData->SrcBox.Bottom;
445 srcBox.Front = pData->SrcBox.Front;
446 srcBox.Back = pData->SrcBox.Back;
447 wddmD3DBOXOrder(&srcBox);
448
449 D3DBOX dstBox;
450 dstBox.Left = pData->DstX;
451 dstBox.Top = pData->DstY;
452 dstBox.Right = pData->DstX + iWidth;
453 dstBox.Bottom = pData->DstY + iHeight;
454 dstBox.Front = pData->DstZ;
455 dstBox.Back = pData->DstZ + iDepth;
456 wddmD3DBOXOrder(&dstBox);
457
458 UINT Level;
459 for (Level = 0; Level < pSrcRc->cAllocations; ++Level)
460 {
461 if (Level > 0)
462 {
463 /* Each next level is 2 times smaller. */
464 iWidth = wddmCoordDivBy2(iWidth);
465 iHeight = wddmCoordDivBy2(iHeight);
466 iDepth = wddmCoordDivBy2(iDepth);
467 wddmD3DBoxDivBy2(&srcBox);
468 wddmD3DBoxDivBy2(&dstBox);
469 }
470
471 IDirect3DVolumeTexture9 *pSrcVolTex = (IDirect3DVolumeTexture9 *)pSrcRc->aAllocations[0].pD3DIf;
472 D3DLOCKED_BOX srcLockedVolume;
473 hr = pSrcVolTex->LockBox(Level, &srcLockedVolume, &srcBox, D3DLOCK_READONLY);
474 Assert(hr == S_OK);
475 if (SUCCEEDED(hr))
476 {
477 IDirect3DVolumeTexture9 *pDstVolTex = (IDirect3DVolumeTexture9 *)pDstRc->aAllocations[0].pD3DIf;
478 D3DLOCKED_BOX dstLockedVolume;
479 hr = pDstVolTex->LockBox(Level, &dstLockedVolume, &dstBox, D3DLOCK_DISCARD);
480 Assert(hr == S_OK);
481 if (SUCCEEDED(hr))
482 {
483 const UINT cbLine = vboxWddmCalcRowSize(srcBox.Left, srcBox.Right, pSrcRc->RcDesc.enmFormat);
484 uint8_t *pu8Dst = (uint8_t *)dstLockedVolume.pBits;
485 const uint8_t *pu8Src = (uint8_t *)srcLockedVolume.pBits;
486 for (INT d = 0; d < iDepth; ++d)
487 {
488 uint8_t *pu8RowDst = pu8Dst;
489 const uint8_t *pu8RowSrc = pu8Src;
490 const UINT cRows = vboxWddmCalcNumRows(0, iHeight, pSrcRc->RcDesc.enmFormat);
491 for (UINT h = 0; h < cRows; ++h)
492 {
493 memcpy(pu8RowDst, pu8RowSrc, cbLine);
494 pu8RowDst += dstLockedVolume.RowPitch;
495 pu8RowSrc += srcLockedVolume.RowPitch;
496 }
497 pu8Dst += dstLockedVolume.SlicePitch;
498 pu8Src += srcLockedVolume.SlicePitch;
499 }
500
501 hr = pDstVolTex->UnlockBox(Level);
502 Assert(hr == S_OK);
503 }
504 hr = pSrcVolTex->UnlockBox(Level);
505 Assert(hr == S_OK);
506 }
507 }
508
509 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
510 return hr;
511}
512
513HRESULT APIENTRY GaDdiFlush(HANDLE hDevice)
514{
515 VBOXVDBG_BREAK_DDI();
516
517 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
518
519 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
520 IDirect3DDevice9 *pDevice9If = pDevice->pDevice9If;
521
522 HRESULT hr = S_OK;
523 if ( VBOXDISPMODE_IS_3D(pDevice->pAdapter)
524 && pDevice9If) /* Windows 10 can call the Flush when pDevice9If is not yet initialized. */
525 {
526#if 1
527 /* Flush the Gallium pipe. */
528 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
529 HRESULT hr2 = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
530 if (SUCCEEDED(hr2))
531 {
532 hr2 = pGaD3DDevice9Ex->GaFlush();
533
534 pGaD3DDevice9Ex->Release();
535 }
536#else
537 /** @todo remove. Test code for D3DQUERYTYPE_EVENT, which does the flush too. */
538 IDirect3DQuery9 *pQuery;
539 hr = pDevice9If->CreateQuery(D3DQUERYTYPE_EVENT, &pQuery);
540 if (SUCCEEDED(hr))
541 {
542 hr = pQuery->Issue(D3DISSUE_END);
543 while (pQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE);
544 pQuery->Release();
545 }
546#endif
547
548 VBOXVDBG_DUMP_FLUSH(pDevice);
549 }
550
551 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
552 return hr;
553}
554
555HRESULT APIENTRY GaDdiPresent(HANDLE hDevice, const D3DDDIARG_PRESENT *pData)
556{
557 VBOXVDBG_BREAK_DDI();
558
559 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
560
561 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
562 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
563 PVBOXWDDMDISP_RESOURCE pSrcRc = NULL;
564 PVBOXWDDMDISP_RESOURCE pDstRc = NULL;
565 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = NULL;
566 PVBOXWDDMDISP_ALLOCATION pDstAlloc = NULL;
567
568 if (pData->hSrcResource)
569 {
570 pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
571 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
572 pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
573 Assert(pSrcAlloc->hAllocation);
574 }
575
576 if (pData->hDstResource)
577 {
578 pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
579 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
580 pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
581 Assert(pDstAlloc->hAllocation);
582 }
583
584 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
585 HRESULT hr = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
586 if (SUCCEEDED(hr))
587 {
588 /* Query DdiPresent.hContext for this device. */
589 HANDLE hContext = 0;
590 hr = pGaD3DDevice9Ex->GaWDDMContextHandle(&hContext);
591 Assert(hr == S_OK);
592 if (SUCCEEDED(hr))
593 {
594 HRESULT hr2 = pGaD3DDevice9Ex->GaFlush();
595 Assert(hr2 == S_OK);
596 RT_NOREF(hr2);
597 }
598
599 pGaD3DDevice9Ex->Release();
600
601 if (SUCCEEDED(hr))
602 {
603 D3DDDICB_PRESENT DdiPresent;
604 RT_ZERO(DdiPresent);
605 DdiPresent.hSrcAllocation = pSrcAlloc ? pSrcAlloc->hAllocation : 0;
606 DdiPresent.hDstAllocation = pDstAlloc ? pDstAlloc->hAllocation : 0;
607 DdiPresent.hContext = hContext;
608
609 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
610 Assert(hr == S_OK);
611 }
612 }
613 else
614 {
615 AssertFailed();
616 }
617
618 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
619 return hr;
620}
621
622HRESULT APIENTRY GaDdiLock(HANDLE hDevice, D3DDDIARG_LOCK *pData)
623{
624 VBOXVDBG_BREAK_DDI();
625
626 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) hResource 0x%p[%d] flags 0x%08X\n",
627 hDevice, pData->hResource, pData->SubResourceIndex, pData->Flags.Value));
628
629 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
630 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
631 AssertReturn(pData->SubResourceIndex < pRc->cAllocations, E_INVALIDARG);
632
633 HRESULT hr = S_OK;
634
635 /*
636 * Memory buffers for D3DDDIPOOL_SYSTEMMEM resources are allocated by Windows (pAlloc->pvMem).
637 * Normally the Gallium D3D backend (Nine state stracker) also has its own memory for
638 * corresponding D3D resources.
639 * The driver must synchronize these memory buffers:
640 * - copy from the backend to Windows buffer on Lock;
641 * - copy from Windows to the backend buffer on Unlock.
642 *
643 * However for textures and cube textures we can use Gallium backend feature:
644 * the shared handle of a D3DPOOL_SYSTEMMEM is the pointer to the actual memory buffer.
645 * So we create texture and cube texture resources for D3DDDIPOOL_SYSTEMMEM with
646 * pSharedHandle set to pAlloc->pvMem (the buffer has the same layout as the Gallium one).
647 * See GaD3DIfCreateForRc. There is no need to sync in this case.
648 *
649 * This is how D3DDDIPOOL_SYSTEMMEM resource synchronization is handled:
650 * Index and vertex buffers - copy data on lock/unlock.
651 * Textures - set the shared handle to pAlloc->pvMem. No sync required.
652 * Cube textures - set the shared handle to pAlloc->pvMem, because VBox version of Nine
653 * implements SYSTEMMEM shared cube textures. No sync required.
654 * Volume textures - GaD3DResourceSynchMem. Possibly have to implement SharedHandle support in Nine.
655 * Surfaces - these should not reallly be in D3DDDIPOOL_SYSTEMMEM, so GaD3DResourceSynchMem.
656 *
657 * NotifyOnly flag is set for D3DDDIPOOL_SYSTEMMEM locks/unlocks:
658 * "... for preallocated system memory surfaces, the runtime ignores the driver-set memory and pitch, ... .
659 * The runtime sets the NotifyOnly bit-field flag in the Flags member of the D3DDDIARG_LOCK structure
660 * to differentiate Lock calls that lock preallocated system memory surfaces from other Lock calls."
661 *
662 * It turned out that Windows always passes pData->SubResourceIndex == 0 for
663 * NotifyOnly locks when locking a textures, cubemaps and volumes.
664 * So the GaD3DResourceSynchMem must sync all subresources in this case.
665 */
666
667 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
668 const VBOXDISP_D3DIFTYPE enmD3DIfType = pAlloc->enmD3DIfType;
669 const DWORD dwD3DLockFlags = vboxDDI2D3DLockFlags(pData->Flags);
670
671 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
672 {
673 if (pData->Flags.NotifyOnly)
674 {
675 Assert(pAlloc->pvMem);
676 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
677
678 if ( enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE
679 || enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
680 {
681 /* Brute-force. */
682 if (pAlloc->LockInfo.cLocks == 0)
683 {
684 vboxVDbgPrintF((__FUNCTION__", sync from backend\n"));
685 GaD3DResourceSynchMem(pRc, /* fToBackend */ false);
686 }
687 }
688
689 //VBOXVDBG_CHECK_SMSYNC(pRc);
690 }
691 else
692 {
693 Assert(!pAlloc->pvMem);
694 Assert(pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
695 }
696
697 if ( enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
698 || enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
699 || enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE)
700 {
701 Assert(pAlloc->pD3DIf);
702 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pAlloc->pD3DIf;
703 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pAlloc->pD3DIf;
704 IDirect3DSurface9 *pD3DIfSurface = (IDirect3DSurface9*)pAlloc->pD3DIf;
705
706 Assert(!pData->Flags.RangeValid);
707 Assert(!pData->Flags.BoxValid);
708
709 RECT *pRect = NULL;
710 if (pData->Flags.AreaValid)
711 {
712 pRect = &pData->Area;
713 }
714 /* else - we lock the entire texture, pRect == NULL */
715
716 BOOL fNeedLock = TRUE;
717 if (pAlloc->LockInfo.cLocks)
718 {
719 /* Can happen.
720 * It is OK to lock buffers again, but Gallium backend does not allow nested locking for anything else.
721 */
722 Assert(pAlloc->LockInfo.LockedRect.pBits);
723
724 bool fSameLock = (pAlloc->LockInfo.fFlags.ReadOnly == pData->Flags.ReadOnly)
725 && (pAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
726 if (fSameLock && pAlloc->LockInfo.fFlags.AreaValid)
727 {
728 fSameLock = fSameLock
729 && (pAlloc->LockInfo.Area.left == pData->Area.left)
730 && (pAlloc->LockInfo.Area.top == pData->Area.top)
731 && (pAlloc->LockInfo.Area.right == pData->Area.right)
732 && (pAlloc->LockInfo.Area.bottom == pData->Area.bottom);
733 }
734
735 if (!fSameLock)
736 {
737 switch (enmD3DIfType)
738 {
739 case VBOXDISP_D3DIFTYPE_TEXTURE:
740 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
741 break;
742 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
743 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
744 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex));
745 break;
746 case VBOXDISP_D3DIFTYPE_SURFACE:
747 hr = pD3DIfSurface->UnlockRect();
748 break;
749 default:
750 AssertFailed();
751 break;
752 }
753 Assert(hr == S_OK);
754 }
755 else
756 {
757 fNeedLock = FALSE;
758 }
759 }
760
761 if (fNeedLock && SUCCEEDED(hr))
762 {
763 pAlloc->LockInfo.fFlags = pData->Flags;
764 if (pRect)
765 {
766 pAlloc->LockInfo.Area = *pRect;
767 Assert(pAlloc->LockInfo.fFlags.AreaValid == 1);
768 }
769 else
770 {
771 Assert(pAlloc->LockInfo.fFlags.AreaValid == 0);
772 }
773
774 switch (enmD3DIfType)
775 {
776 case VBOXDISP_D3DIFTYPE_TEXTURE:
777 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
778 &pAlloc->LockInfo.LockedRect,
779 pRect,
780 dwD3DLockFlags);
781 break;
782 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
783 hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
784 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex),
785 &pAlloc->LockInfo.LockedRect,
786 pRect,
787 dwD3DLockFlags);
788 break;
789 case VBOXDISP_D3DIFTYPE_SURFACE:
790 hr = pD3DIfSurface->LockRect(&pAlloc->LockInfo.LockedRect,
791 pRect,
792 dwD3DLockFlags);
793 break;
794 default:
795 AssertFailed();
796 break;
797 }
798
799 if (FAILED(hr))
800 {
801 WARN(("LockRect failed, hr %x", hr));
802 }
803 }
804
805 if (SUCCEEDED(hr))
806 {
807 ++pAlloc->LockInfo.cLocks;
808
809 if (!pData->Flags.NotifyOnly)
810 {
811 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
812 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
813 pData->SlicePitch = 0;
814 Assert(pAlloc->SurfDesc.slicePitch == 0);
815 Assert(!pAlloc->pvMem);
816 }
817
818 VBOXVDBG_DUMP_LOCK_ST(pData);
819
820 hr = S_OK;
821 }
822 }
823 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
824 {
825 Assert(pAlloc->pD3DIf);
826 IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pAlloc->pD3DIf;
827
828 Assert(!pData->Flags.AreaValid);
829 Assert(!pData->Flags.RangeValid);
830
831 D3DDDIBOX *pBox = NULL;
832 if (pData->Flags.BoxValid)
833 {
834 pBox = &pData->Box;
835 }
836 /* else - we lock the entire texture, pBox == NULL */
837
838 BOOL fNeedLock = TRUE;
839 if (pAlloc->LockInfo.cLocks)
840 {
841 Assert(pAlloc->LockInfo.LockedBox.pBits);
842
843 bool fSameLock = (pAlloc->LockInfo.fFlags.ReadOnly == pData->Flags.ReadOnly)
844 && (pAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid);
845 if (fSameLock && pAlloc->LockInfo.fFlags.BoxValid)
846 {
847 fSameLock = fSameLock
848 && (pAlloc->LockInfo.Box.Left == pData->Box.Left)
849 && (pAlloc->LockInfo.Box.Top == pData->Box.Top)
850 && (pAlloc->LockInfo.Box.Right == pData->Box.Right)
851 && (pAlloc->LockInfo.Box.Bottom == pData->Box.Bottom)
852 && (pAlloc->LockInfo.Box.Front == pData->Box.Front)
853 && (pAlloc->LockInfo.Box.Back == pData->Box.Back);
854 }
855
856 if (!fSameLock)
857 {
858 hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex);
859 Assert(hr == S_OK);
860 }
861 else
862 {
863 fNeedLock = FALSE;
864 }
865 }
866
867 if (fNeedLock && SUCCEEDED(hr))
868 {
869 pAlloc->LockInfo.fFlags = pData->Flags;
870 if (pBox)
871 {
872 pAlloc->LockInfo.Box = *pBox;
873 Assert(pAlloc->LockInfo.fFlags.BoxValid == 1);
874 }
875 else
876 {
877 Assert(pAlloc->LockInfo.fFlags.BoxValid == 0);
878 }
879
880 hr = pD3DIfTex->LockBox(pData->SubResourceIndex,
881 &pAlloc->LockInfo.LockedBox,
882 (D3DBOX *)pBox,
883 dwD3DLockFlags);
884 if (FAILED(hr))
885 {
886 WARN(("LockRect failed, hr", hr));
887 }
888 }
889
890 if (SUCCEEDED(hr))
891 {
892 ++pAlloc->LockInfo.cLocks;
893
894 if (!pData->Flags.NotifyOnly)
895 {
896 pData->pSurfData = pAlloc->LockInfo.LockedBox.pBits;
897 pData->Pitch = pAlloc->LockInfo.LockedBox.RowPitch;
898 pData->SlicePitch = pAlloc->LockInfo.LockedBox.SlicePitch;
899 Assert(!pAlloc->pvMem);
900 }
901
902 VBOXVDBG_DUMP_LOCK_ST(pData);
903
904 hr = S_OK;
905 }
906 }
907 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
908 {
909 Assert(pAlloc->pD3DIf);
910 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
911
912 Assert(!pData->Flags.AreaValid);
913 Assert(!pData->Flags.BoxValid);
914
915 D3DDDIRANGE *pRange = NULL;
916 if (pData->Flags.RangeValid)
917 {
918 pRange = &pData->Range;
919 }
920 /* else - we lock the entire vertex buffer, pRange == NULL */
921
922 bool bLocked = false;
923 if (!pAlloc->LockInfo.cLocks)
924 {
925 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
926 {
927 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
928 pRange ? pRange->Size : 0,
929 &pAlloc->LockInfo.LockedRect.pBits,
930 dwD3DLockFlags);
931 bLocked = true;
932 }
933
934 Assert(hr == S_OK);
935 if (hr == S_OK)
936 {
937 Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
938 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
939 pAlloc->LockInfo.fFlags = pData->Flags;
940 if (pRange)
941 {
942 pAlloc->LockInfo.Range = *pRange;
943 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
944 }
945 else
946 {
947 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
948 }
949 }
950 }
951 else
952 {
953 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
954 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
955 {
956 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
957 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
958 }
959 Assert(pAlloc->LockInfo.LockedRect.pBits);
960 }
961
962 if (hr == S_OK)
963 {
964 ++pAlloc->LockInfo.cLocks;
965
966 if (!pData->Flags.NotifyOnly)
967 {
968 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
969 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
970 pData->SlicePitch = 0;
971 Assert(pAlloc->SurfDesc.slicePitch == 0);
972 Assert(!pAlloc->pvMem);
973 }
974 else
975 {
976 Assert(pAlloc->pvMem);
977 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
978 if (bLocked && !pData->Flags.Discard)
979 {
980 RECT r, *pr;
981 if (pRange)
982 {
983 r.top = 0;
984 r.left = pRange->Offset;
985 r.bottom = 1;
986 r.right = pRange->Offset + pRange->Size;
987 pr = &r;
988 }
989 else
990 pr = NULL;
991 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
992 }
993 }
994
995 }
996 }
997 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
998 {
999 Assert(pAlloc->pD3DIf);
1000 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
1001
1002 Assert(!pData->Flags.AreaValid);
1003 Assert(!pData->Flags.BoxValid);
1004
1005 D3DDDIRANGE *pRange = NULL;
1006 if (pData->Flags.RangeValid)
1007 {
1008 pRange = &pData->Range;
1009 }
1010 /* else - we lock the entire vertex buffer, pRect == NULL */
1011
1012 bool bLocked = false;
1013 if (!pAlloc->LockInfo.cLocks)
1014 {
1015 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
1016 {
1017 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
1018 pRange ? pRange->Size : 0,
1019 &pAlloc->LockInfo.LockedRect.pBits,
1020 dwD3DLockFlags);
1021 bLocked = true;
1022 }
1023
1024 Assert(hr == S_OK);
1025 if (hr == S_OK)
1026 {
1027 Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
1028 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
1029 pAlloc->LockInfo.fFlags = pData->Flags;
1030 if (pRange)
1031 {
1032 pAlloc->LockInfo.Range = *pRange;
1033 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
1034 }
1035 else
1036 {
1037 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
1038 }
1039 }
1040 }
1041 else
1042 {
1043 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
1044 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
1045 {
1046 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
1047 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
1048 }
1049 Assert(pAlloc->LockInfo.LockedRect.pBits);
1050 }
1051
1052 if (hr == S_OK)
1053 {
1054 ++pAlloc->LockInfo.cLocks;
1055
1056 if (!pData->Flags.NotifyOnly)
1057 {
1058 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
1059 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
1060 pData->SlicePitch = 0;
1061 Assert(pAlloc->SurfDesc.slicePitch == 0);
1062 }
1063 else
1064 {
1065 Assert(pAlloc->pvMem);
1066 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
1067 if (bLocked && !pData->Flags.Discard)
1068 {
1069 RECT r, *pr;
1070 if (pRange)
1071 {
1072 r.top = 0;
1073 r.left = pRange->Offset;
1074 r.bottom = 1;
1075 r.right = pRange->Offset + pRange->Size;
1076 pr = &r;
1077 }
1078 else
1079 pr = NULL;
1080 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
1081 }
1082 }
1083 }
1084 }
1085 else
1086 {
1087 WARN(("not implemented %d", enmD3DIfType));
1088 }
1089 }
1090 else /* if !VBOXDISPMODE_IS_3D(pDevice->pAdapter) */
1091 {
1092 if (pAlloc->hAllocation)
1093 {
1094 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
1095 {
1096 D3DDDICB_LOCK LockData;
1097 LockData.hAllocation = pAlloc->hAllocation;
1098 LockData.PrivateDriverData = 0;
1099 LockData.NumPages = 0;
1100 LockData.pPages = NULL;
1101 LockData.pData = NULL; /* out */
1102 LockData.Flags.Value = 0;
1103 LockData.Flags.Discard = pData->Flags.Discard;
1104 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
1105
1106 uintptr_t offset;
1107 if (pData->Flags.AreaValid)
1108 {
1109 offset = vboxWddmCalcOffXYrd(pData->Area.left, pData->Area.top, pAlloc->SurfDesc.pitch,
1110 pAlloc->SurfDesc.format);
1111 }
1112 else if (pData->Flags.RangeValid)
1113 {
1114 offset = pData->Range.Offset;
1115 }
1116 else if (pData->Flags.BoxValid)
1117 {
1118 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
1119 Assert(0);
1120 offset = 0;
1121 }
1122 else
1123 {
1124 offset = 0;
1125 }
1126
1127 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
1128 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
1129 if (hr == S_OK)
1130 {
1131 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
1132 pData->Pitch = pAlloc->SurfDesc.pitch;
1133 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
1134
1135 if (pData->Flags.Discard)
1136 {
1137 /* check if the surface was renamed */
1138 if (LockData.hAllocation)
1139 pAlloc->hAllocation = LockData.hAllocation;
1140 }
1141 }
1142 }
1143 /* else - d3d may create sysmem render targets and call our Present callbacks for those
1144 * to make it work properly we need to create a VRAM surface corresponding to sysmem one
1145 * and copy stuff to VRAM on lock/unlock
1146 *
1147 * so we don't do any locking here, but still track the lock info here
1148 * and do lock-memcopy-unlock to VRAM surface on sysmem surface unlock
1149 * */
1150
1151 if (hr == S_OK)
1152 {
1153 Assert(!pAlloc->LockInfo.cLocks);
1154
1155 if (!pData->Flags.ReadOnly)
1156 {
1157 if (pData->Flags.AreaValid)
1158 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
1159 else
1160 {
1161 Assert(!pData->Flags.RangeValid);
1162 Assert(!pData->Flags.BoxValid);
1163 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
1164 }
1165 }
1166
1167 ++pAlloc->LockInfo.cLocks;
1168 }
1169 }
1170 }
1171
1172 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1173 return hr;
1174}
1175
1176HRESULT APIENTRY GaDdiUnlock(HANDLE hDevice, const D3DDDIARG_UNLOCK *pData)
1177{
1178 VBOXVDBG_BREAK_DDI();
1179
1180 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) hResource 0x%p[%d]\n",
1181 hDevice, pData->hResource, pData->SubResourceIndex));
1182
1183 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1184 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
1185 AssertReturn(pData->SubResourceIndex < pRc->cAllocations, E_INVALIDARG);
1186
1187 HRESULT hr = S_OK;
1188
1189 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
1190 const VBOXDISP_D3DIFTYPE enmD3DIfType = pAlloc->enmD3DIfType;
1191
1192 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
1193 {
1194 if ( enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
1195 || enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
1196 || enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE)
1197 {
1198 VBOXVDBG_DUMP_UNLOCK_ST(pData);
1199
1200 --pAlloc->LockInfo.cLocks;
1201 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
1202 if (!pAlloc->LockInfo.cLocks)
1203 {
1204 Assert(pAlloc->pD3DIf);
1205 switch (enmD3DIfType)
1206 {
1207 case VBOXDISP_D3DIFTYPE_TEXTURE:
1208 {
1209 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pAlloc->pD3DIf;
1210 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
1211 break;
1212 }
1213 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
1214 {
1215 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pAlloc->pD3DIf;
1216 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
1217 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex));
1218 break;
1219 }
1220 case VBOXDISP_D3DIFTYPE_SURFACE:
1221 {
1222 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
1223 hr = pD3DIfSurf->UnlockRect();
1224 break;
1225 }
1226 default:
1227 AssertFailed();
1228 break;
1229 }
1230 Assert(hr == S_OK);
1231 }
1232 }
1233 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
1234 {
1235 VBOXVDBG_DUMP_UNLOCK_ST(pData);
1236
1237 --pAlloc->LockInfo.cLocks;
1238 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
1239 if (!pAlloc->LockInfo.cLocks)
1240 {
1241 Assert(pAlloc->pD3DIf);
1242 IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pAlloc->pD3DIf;
1243 hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex);
1244 Assert(hr == S_OK);
1245 }
1246 }
1247 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
1248 {
1249 --pAlloc->LockInfo.cLocks;
1250 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
1251 if (!pAlloc->LockInfo.cLocks
1252 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
1253 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
1254 {
1255 Assert(pAlloc->pD3DIf);
1256 /* this is a sysmem texture, update */
1257 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
1258 {
1259 RECT r, *pr;
1260 if (pAlloc->LockInfo.fFlags.RangeValid)
1261 {
1262 r.top = 0;
1263 r.left = pAlloc->LockInfo.Range.Offset;
1264 r.bottom = 1;
1265 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
1266 pr = &r;
1267 }
1268 else
1269 pr = NULL;
1270 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
1271 pr,
1272 true /*bool bToLockInfo*/);
1273 }
1274 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
1275 hr = pD3D9VBuf->Unlock();
1276 Assert(hr == S_OK);
1277 }
1278 }
1279 else if (enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
1280 {
1281 --pAlloc->LockInfo.cLocks;
1282 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
1283 if (!pAlloc->LockInfo.cLocks
1284 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
1285 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
1286 {
1287 Assert(pAlloc->pD3DIf);
1288 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
1289 /* this is a sysmem texture, update */
1290 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
1291 {
1292 RECT r, *pr;
1293 if (pAlloc->LockInfo.fFlags.RangeValid)
1294 {
1295 r.top = 0;
1296 r.left = pAlloc->LockInfo.Range.Offset;
1297 r.bottom = 1;
1298 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
1299 pr = &r;
1300 }
1301 else
1302 pr = NULL;
1303 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
1304 pr,
1305 true /*bool bToLockInfo*/);
1306 }
1307 hr = pD3D9IBuf->Unlock();
1308 Assert(hr == S_OK);
1309 }
1310 }
1311 else
1312 {
1313 WARN(("Unlock unsupported %d", pRc->aAllocations[0].enmD3DIfType));
1314 }
1315
1316 if (hr == S_OK)
1317 {
1318 if (pData->Flags.NotifyOnly)
1319 {
1320 Assert(pAlloc->pvMem);
1321 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
1322
1323 if ( enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE
1324 || enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
1325 {
1326 /* Brute-force. */
1327 if (pAlloc->LockInfo.cLocks == 0)
1328 {
1329 vboxVDbgPrintF((__FUNCTION__", sync to backend\n"));
1330 GaD3DResourceSynchMem(pRc, /* fToBackend */ true);
1331 }
1332 }
1333
1334 //VBOXVDBG_CHECK_SMSYNC(pRc);
1335 }
1336 else
1337 {
1338 Assert(!pAlloc->pvMem);
1339 Assert(pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
1340 }
1341 }
1342 }
1343 else
1344 {
1345 if (pAlloc->hAllocation)
1346 {
1347 BOOL fDoUnlock = FALSE;
1348
1349 Assert(pAlloc->LockInfo.cLocks);
1350 --pAlloc->LockInfo.cLocks;
1351 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
1352
1353 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
1354 {
1355 fDoUnlock = TRUE;
1356 }
1357 else
1358 {
1359 if (!pAlloc->LockInfo.cLocks)
1360 {
1361 D3DDDICB_LOCK LockData;
1362 LockData.hAllocation = pAlloc->hAllocation;
1363 LockData.PrivateDriverData = 0;
1364 LockData.NumPages = 0;
1365 LockData.pPages = NULL;
1366 LockData.pData = NULL; /* out */
1367 LockData.Flags.Value = 0;
1368
1369 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
1370 if (hr == S_OK)
1371 {
1372 D3DLOCKED_RECT LRect;
1373 LRect.pBits = LockData.pData;
1374 LRect.Pitch = pAlloc->SurfDesc.pitch;
1375 Assert(pAlloc->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID);
1376 VBoxD3DIfLockUnlockMemSynch(pAlloc, &LRect, &pAlloc->DirtyRegion.Rect, TRUE /* bool bToLockInfo*/);
1377 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
1378 fDoUnlock = TRUE;
1379 }
1380 else
1381 {
1382 WARN(("pfnLockCb failed, hr 0x%x", hr));
1383 }
1384 }
1385 }
1386
1387 if (fDoUnlock)
1388 {
1389 D3DDDICB_UNLOCK Unlock;
1390
1391 Unlock.NumAllocations = 1;
1392 Unlock.phAllocations = &pAlloc->hAllocation;
1393
1394 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &Unlock);
1395 if(hr != S_OK)
1396 {
1397 WARN(("pfnUnlockCb failed, hr 0x%x", hr));
1398 }
1399 }
1400
1401 if (!SUCCEEDED(hr))
1402 {
1403 WARN(("unlock failure!"));
1404 ++pAlloc->LockInfo.cLocks;
1405 }
1406 }
1407 }
1408
1409 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1410 return hr;
1411}
1412
1413HRESULT APIENTRY GaDdiCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC *pData, const UINT *pCode)
1414{
1415 VBOXVDBG_BREAK_DDI();
1416
1417 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) Size %d\n", hDevice, pData->Size));
1418
1419 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1420 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1421
1422 AssertReturn(pDevice9If, E_INVALIDARG);
1423 AssertReturn(pData->Size >= 2 * sizeof(uint32_t), E_INVALIDARG);
1424
1425#ifdef LOG_ENABLED
1426 vboxVDbgPrintF(("Vertex shader code:\n"));
1427 const uint32_t *paTokens = (uint32_t *)pCode;
1428 const uint32_t cTokens = pData->Size / sizeof(uint32_t);
1429 for (uint32_t iToken = 0; iToken < cTokens; ++iToken)
1430 {
1431 vboxVDbgPrintF(("%08X", paTokens[iToken]));
1432 }
1433 vboxVDbgPrintF(("\n"));
1434#endif
1435
1436 HRESULT hr = S_OK;
1437 DWORD *pFunction;
1438 if (pCode[0] == 0xFFFE0200)
1439 {
1440 /* Treat 2.0 shaders as 2.1, because Gallium is strict and rejects 2.0 shaders which use 2.1 instructions. */
1441 vboxVDbgPrintF(("Bumping version 2.0 to 2.1\n"));
1442
1443 pFunction = (DWORD *)RTMemAlloc(pData->Size);
1444 if (pFunction)
1445 {
1446 memcpy(pFunction, pCode, pData->Size);
1447 pFunction[0] |= 1;
1448 }
1449 else
1450 {
1451 hr = E_OUTOFMEMORY;
1452 }
1453 }
1454 else
1455 {
1456 pFunction = (DWORD *)pCode;
1457 }
1458
1459 if (hr == S_OK)
1460 {
1461 IDirect3DVertexShader9 *pShader;
1462 hr = pDevice9If->CreateVertexShader(pFunction, &pShader);
1463 Assert(hr == S_OK);
1464 if (hr == S_OK)
1465 {
1466 Assert(pShader);
1467 pData->ShaderHandle = pShader;
1468 }
1469
1470 if ((uintptr_t)pFunction != (uintptr_t)pCode)
1471 {
1472 RTMemFree(pFunction);
1473 }
1474 }
1475
1476 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1477 return hr;
1478}
1479
1480HRESULT APIENTRY GaDdiSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
1481{
1482 VBOXVDBG_BREAK_DDI();
1483
1484 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1485
1486 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1487 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1488
1489 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9 *)hShaderHandle;
1490
1491 HRESULT hr = pDevice9If->SetVertexShader(pShader);
1492 Assert(hr == S_OK);
1493
1494 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1495 return hr;
1496}
1497
1498HRESULT APIENTRY GaDdiDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
1499{
1500 VBOXVDBG_BREAK_DDI();
1501
1502 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1503
1504 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1505 RT_NOREF(pDevice);
1506
1507 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9 *)hShaderHandle;
1508 pShader->Release();
1509
1510 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, S_OK));
1511 return S_OK;
1512}
1513
1514HRESULT APIENTRY GaDdiSetVertexShaderConst(HANDLE hDevice, const D3DDDIARG_SETVERTEXSHADERCONST *pData,
1515 const VOID *pRegisters)
1516{
1517 VBOXVDBG_BREAK_DDI();
1518
1519 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1520
1521 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1522 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
1523
1524 HRESULT hr = pDevice9If->SetVertexShaderConstantF(pData->Register,
1525 (const float*)pRegisters,
1526 pData->Count);
1527 Assert(hr == S_OK);
1528
1529 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1530 return hr;
1531}
1532
1533HRESULT APIENTRY GaDdiSetVertexShaderConstI(HANDLE hDevice, const D3DDDIARG_SETVERTEXSHADERCONSTI *pData,
1534 const INT *pRegisters)
1535{
1536 VBOXVDBG_BREAK_DDI();
1537
1538 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1539
1540 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1541 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1542
1543 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
1544 Assert(hr == S_OK);
1545
1546 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1547 return hr;
1548}
1549
1550HRESULT APIENTRY GaDdiSetVertexShaderConstB(HANDLE hDevice, const D3DDDIARG_SETVERTEXSHADERCONSTB *pData,
1551 const BOOL *pRegisters)
1552{
1553 VBOXVDBG_BREAK_DDI();
1554
1555 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1556
1557 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1558 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1559
1560 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
1561 Assert(hr == S_OK);
1562
1563 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1564 return hr;
1565}
1566
1567HRESULT APIENTRY GaDdiCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER *pData, const UINT *pCode)
1568{
1569 VBOXVDBG_BREAK_DDI();
1570
1571 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) Size %d\n", hDevice, pData->CodeSize));
1572 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1573 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1574
1575 AssertReturn(pDevice9If, E_INVALIDARG);
1576 AssertReturn(pData->CodeSize >= 2 * sizeof(uint32_t), E_INVALIDARG);
1577
1578#ifdef LOG_ENABLED
1579 vboxVDbgPrintF(("Shader code:\n"));
1580 const uint32_t *paTokens = (uint32_t *)pCode;
1581 const uint32_t cTokens = pData->CodeSize / sizeof(uint32_t);
1582 for (uint32_t iToken = 0; iToken < cTokens; ++iToken)
1583 {
1584 vboxVDbgPrintF(("%08X", paTokens[iToken]));
1585 }
1586 vboxVDbgPrintF(("\n"));
1587#endif
1588
1589 HRESULT hr = S_OK;
1590 DWORD *pFunction;
1591 if (pCode[0] == 0xFFFF0200)
1592 {
1593 /* Treat 2.0 shaders as 2.1, because Gallium is strict and rejects 2.0 shaders which use 2.1 instructions. */
1594 vboxVDbgPrintF(("Bumping version 2.0 to 2.1\n"));
1595
1596 pFunction = (DWORD *)RTMemAlloc(pData->CodeSize);
1597 if (pFunction)
1598 {
1599 memcpy(pFunction, pCode, pData->CodeSize);
1600 pFunction[0] |= 1;
1601 }
1602 else
1603 {
1604 hr = E_OUTOFMEMORY;
1605 }
1606 }
1607 else
1608 {
1609 pFunction = (DWORD *)pCode;
1610 }
1611
1612 if (hr == S_OK)
1613 {
1614 IDirect3DPixelShader9 *pShader;
1615 hr = pDevice9If->CreatePixelShader(pFunction, &pShader);
1616 Assert(hr == S_OK);
1617 if (hr == S_OK)
1618 {
1619 Assert(pShader);
1620 pData->ShaderHandle = pShader;
1621 }
1622
1623 if ((uintptr_t)pFunction != (uintptr_t)pCode)
1624 {
1625 RTMemFree(pFunction);
1626 }
1627 }
1628
1629 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1630 return hr;
1631}
1632
1633HRESULT APIENTRY GaDdiDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
1634{
1635 VBOXVDBG_BREAK_DDI();
1636
1637 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1638
1639 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1640 RT_NOREF(pDevice);
1641
1642 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9 *)hShaderHandle;
1643
1644 pShader->Release();
1645
1646 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, S_OK));
1647 return S_OK;
1648}
1649
1650HRESULT APIENTRY GaDdiSetPixelShaderConstI(HANDLE hDevice, const D3DDDIARG_SETPIXELSHADERCONSTI *pData,
1651 const INT *pRegisters)
1652{
1653 VBOXVDBG_BREAK_DDI();
1654
1655 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1656
1657 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1658 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1659
1660 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
1661 Assert(hr == S_OK);
1662
1663 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1664 return hr;
1665}
1666
1667HRESULT APIENTRY GaDdiSetPixelShaderConstB(HANDLE hDevice, const D3DDDIARG_SETPIXELSHADERCONSTB *pData,
1668 const BOOL *pRegisters)
1669{
1670 VBOXVDBG_BREAK_DDI();
1671
1672 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1673
1674 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1675 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1676
1677 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
1678 Assert(hr == S_OK);
1679
1680 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
1681 return hr;
1682}
1683
1684static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
1685{
1686 RTMemFree(pAlloc);
1687}
1688
1689static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
1690{
1691 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
1692 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
1693 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
1694 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
1695 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
1696 uint32_t offRcInfo = (cbBuf + 7) & ~3;
1697 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
1698 cbBuf = offRcInfo + cbRcInfo;
1699 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
1700 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
1701 cbBuf = offAllocInfos + cbAllocInfos;
1702 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
1703 Assert(pvBuf);
1704 if (pvBuf)
1705 {
1706 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
1707 pAlloc->NumAllocations = pResource->SurfCount;
1708 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
1709 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
1710 pAlloc->PrivateDriverDataSize = cbRcInfo;
1711 pAlloc->pPrivateDriverData = pRcInfo;
1712 pAlloc->hResource = pResource->hResource;
1713 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
1714 for (UINT i = 0; i < pResource->SurfCount; ++i)
1715 {
1716 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
1717 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
1718 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
1719 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
1720 }
1721 return pAlloc;
1722 }
1723 return NULL;
1724}
1725
1726HRESULT APIENTRY GaDdiCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE *pResource)
1727{
1728 VBOXVDBG_BREAK_DDI();
1729
1730 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
1731
1732 HRESULT hr = S_OK;
1733 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
1734 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
1735
1736 vboxVDbgPrintF(("Format %d(0x%x), Shared %d, Pool %d, MsType %d, MsQuality %d, SurfCount %d, MipLevels %d, Fvf 0x%x, VidPnSourceId 0x%x, hResource 0x%x, Flags 0x%x, Rotation %d\n",
1737 pResource->Format, pResource->Format, pResource->Flags.SharedResource, pResource->Pool, pResource->MultisampleType, pResource->MultisampleQuality,
1738 pResource->SurfCount, pResource->MipLevels, pResource->Fvf, pResource->VidPnSourceId,
1739 pResource->hResource, pResource->Flags, pResource->Rotation));
1740
1741 for (UINT iSurf = 0; iSurf < pResource->SurfCount; ++iSurf)
1742 {
1743 vboxVDbgPrintF((" [%d]: %dx%d @%d SysMem %p pitch %d, slice %d\n",
1744 iSurf,
1745 pResource->pSurfList[iSurf].Width,
1746 pResource->pSurfList[iSurf].Height,
1747 pResource->pSurfList[iSurf].Depth,
1748 pResource->pSurfList[iSurf].pSysMem,
1749 pResource->pSurfList[iSurf].SysMemPitch,
1750 pResource->pSurfList[iSurf].SysMemSlicePitch));
1751 }
1752
1753 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAllocZ(RT_UOFFSETOF_DYN(VBOXWDDMDISP_RESOURCE,
1754 aAllocations[pResource->SurfCount]));
1755 if (!pRc)
1756 {
1757 WARN(("vboxResourceAlloc failed"));
1758 return E_OUTOFMEMORY;
1759 }
1760
1761 bool bIssueCreateResource = false;
1762 bool bCreateKMResource = false;
1763 bool bSetHostID = false;
1764
1765 pRc->hResource = pResource->hResource;
1766 pRc->hKMResource = NULL;
1767 pRc->pDevice = pDevice;
1768 pRc->fFlags.Generic = 1;
1769 pRc->RcDesc.fFlags = pResource->Flags;
1770 pRc->RcDesc.enmFormat = pResource->Format;
1771 pRc->RcDesc.enmPool = pResource->Pool;
1772 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
1773 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
1774 pRc->RcDesc.MipLevels = pResource->MipLevels;
1775 pRc->RcDesc.Fvf = pResource->Fvf;
1776 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
1777 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
1778 pRc->RcDesc.enmRotation = pResource->Rotation;
1779 pRc->cAllocations = pResource->SurfCount;
1780 for (UINT i = 0; i < pResource->SurfCount; ++i)
1781 {
1782 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
1783 const D3DDDI_SURFACEINFO *pSurf = &pResource->pSurfList[i];
1784
1785 pAllocation->iAlloc = i;
1786 pAllocation->pRc = pRc;
1787 pAllocation->hAllocation = 0;
1788 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
1789 pAllocation->pvMem = (void *)pSurf->pSysMem;
1790
1791 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
1792 pAllocation->SurfDesc.depth = pSurf->Depth;
1793 pAllocation->SurfDesc.width = pSurf->Width;
1794 pAllocation->SurfDesc.height = pSurf->Height;
1795 pAllocation->SurfDesc.format = pResource->Format;
1796 pAllocation->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
1797
1798 /* No bpp for formats represented by FOURCC code. */
1799 if (!vboxWddmFormatToFourcc(pResource->Format))
1800 pAllocation->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
1801 else
1802 pAllocation->SurfDesc.bpp = 0;
1803
1804 if (pSurf->SysMemPitch)
1805 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
1806 else
1807 pAllocation->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pResource->Format);
1808
1809 pAllocation->SurfDesc.cbSize = vboxWddmCalcSize(pAllocation->SurfDesc.pitch,
1810 pAllocation->SurfDesc.height,
1811 pAllocation->SurfDesc.format);
1812
1813 /* Calculate full scanline width, which might be greater than width. Apparently for SYSTEMMEM only. */
1814 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
1815 {
1816 pAllocation->SurfDesc.d3dWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch,
1817 pAllocation->SurfDesc.format);
1818 Assert(pAllocation->SurfDesc.d3dWidth >= pAllocation->SurfDesc.width);
1819 }
1820 else
1821 {
1822 pAllocation->SurfDesc.d3dWidth = pSurf->Width;
1823 }
1824 }
1825
1826 if (VBOXDISPMODE_IS_3D(pAdapter))
1827 {
1828 if (pRc->RcDesc.fFlags.SharedResource)
1829 {
1830 bIssueCreateResource = true;
1831 bCreateKMResource = true;
1832 /* Miniport needs to know id of the surface which is being shared. */
1833 bSetHostID = true;
1834 }
1835
1836 if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary)
1837 {
1838 bIssueCreateResource = true;
1839 bSetHostID = true;
1840 }
1841
1842 hr = GaD3DIfCreateForRc(pRc);
1843 if (FAILED(hr))
1844 {
1845 WARN(("D3DIfCreateForRc failed, hr 0x%x", hr));
1846 }
1847 }
1848 else
1849 {
1850 bIssueCreateResource = (pResource->Pool != D3DDDIPOOL_SYSTEMMEM) || pResource->Flags.RenderTarget;
1851 bCreateKMResource = bIssueCreateResource;
1852 }
1853
1854 if (SUCCEEDED(hr) && bIssueCreateResource)
1855 {
1856 pRc->fFlags.KmResource = bCreateKMResource;
1857
1858 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
1859 if (pDdiAllocate)
1860 {
1861 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
1862 if (bSetHostID)
1863 {
1864 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
1865 hr = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
1866 if (FAILED(hr))
1867 {
1868 WARN(("QueryInterface(IID_IGaDirect3DDevice9Ex) failed, hr 0x%x", hr));
1869 }
1870 }
1871
1872 Assert(pDdiAllocate->pPrivateDriverData);
1873 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof(VBOXWDDM_RCINFO));
1874
1875 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
1876 pRcInfo->fFlags = pRc->fFlags;
1877 pRcInfo->RcDesc = pRc->RcDesc;
1878 pRcInfo->cAllocInfos = pResource->SurfCount;
1879
1880 for (UINT i = 0; i < pResource->SurfCount; ++i)
1881 {
1882 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
1883 const D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
1884
1885 Assert(RT_BOOL(pSurf->pSysMem) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
1886
1887 D3DDDI_ALLOCATIONINFO *pDdiAllocInfo = &pDdiAllocate->pAllocationInfo[i];
1888 pDdiAllocInfo->hAllocation = 0;
1889 pDdiAllocInfo->pSystemMem = pSurf->pSysMem;
1890 pDdiAllocInfo->VidPnSourceId = pResource->VidPnSourceId;
1891 pDdiAllocInfo->Flags.Value = 0;
1892 if (pResource->Flags.Primary)
1893 {
1894 Assert(pResource->Flags.RenderTarget);
1895 pDdiAllocInfo->Flags.Primary = 1;
1896 }
1897
1898 Assert(pDdiAllocInfo->pPrivateDriverData);
1899 Assert(pDdiAllocInfo->PrivateDriverDataSize == sizeof(VBOXWDDM_ALLOCINFO));
1900
1901 PVBOXWDDM_ALLOCINFO pWddmAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
1902 pWddmAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
1903 pWddmAllocInfo->fFlags = pResource->Flags;
1904 pWddmAllocInfo->hSharedHandle = (uintptr_t)pAllocation->hSharedHandle;
1905 pWddmAllocInfo->SurfDesc = pAllocation->SurfDesc;
1906
1907 if (bSetHostID)
1908 {
1909 if (pGaD3DDevice9Ex)
1910 {
1911 hr = pGaD3DDevice9Ex->GaSurfaceId(pAllocation->pD3DIf, &pWddmAllocInfo->hostID);
1912 }
1913 else
1914 {
1915 AssertFailed();
1916 hr = E_FAIL;
1917 }
1918
1919 if (SUCCEEDED(hr))
1920 {
1921 Assert(pWddmAllocInfo->hostID);
1922 }
1923 else
1924 {
1925 WARN(("pGaD3DDevice9Ex->GaSurfaceId failed, hr 0x%x", hr));
1926 break;
1927 }
1928 }
1929 else
1930 pWddmAllocInfo->hostID = 0;
1931
1932 pAllocation->hostID = pWddmAllocInfo->hostID;
1933 if (pResource->Flags.SharedResource)
1934 {
1935 pWddmAllocInfo->hSharedHandle = pWddmAllocInfo->hostID;
1936 pAllocation->hSharedHandle = (HANDLE)(uintptr_t)pWddmAllocInfo->hostID;
1937 }
1938 }
1939
1940 Assert(!pRc->fFlags.Opened);
1941 Assert(pRc->fFlags.Generic);
1942
1943 if (SUCCEEDED(hr))
1944 {
1945 if (bCreateKMResource)
1946 {
1947 Assert(pRc->fFlags.KmResource);
1948
1949 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
1950 Assert(hr == S_OK);
1951 /* For some reason shared resources are created with zero km resource handle on Win7+. */
1952 Assert(pDdiAllocate->hKMResource || pResource->Flags.SharedResource);
1953 }
1954 else
1955 {
1956 Assert(!pRc->fFlags.KmResource);
1957
1958 pDdiAllocate->hResource = NULL;
1959 pDdiAllocate->NumAllocations = 1;
1960 pDdiAllocate->PrivateDriverDataSize = 0;
1961 pDdiAllocate->pPrivateDriverData = NULL;
1962
1963 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
1964 for (UINT i = 0; i < pResource->SurfCount; ++i)
1965 {
1966 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
1967 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
1968 Assert(hr == S_OK);
1969 Assert(!pDdiAllocate->hKMResource);
1970 if (SUCCEEDED(hr))
1971 {
1972 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
1973 }
1974 else
1975 {
1976 for (UINT j = 0; j < i; ++j)
1977 {
1978 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
1979 D3DDDICB_DEALLOCATE Dealloc;
1980 Dealloc.hResource = 0;
1981 Dealloc.NumAllocations = 1;
1982 Dealloc.HandleList = &pCur->hAllocation;
1983 HRESULT hr2 = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
1984 Assert(hr2 == S_OK); NOREF(hr2);
1985 }
1986 break;
1987 }
1988 }
1989
1990 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
1991 }
1992
1993 if (SUCCEEDED(hr))
1994 {
1995 pRc->hKMResource = pDdiAllocate->hKMResource;
1996
1997 for (UINT i = 0; i < pResource->SurfCount; ++i)
1998 {
1999 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2000 D3DDDI_ALLOCATIONINFO *pDdiAllocInfo = &pDdiAllocate->pAllocationInfo[i];
2001 PVBOXWDDM_ALLOCINFO pWddmAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
2002 const D3DDDI_SURFACEINFO *pSurf = &pResource->pSurfList[i];
2003
2004 pAllocation->hAllocation = pDdiAllocInfo->hAllocation;
2005 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
2006 pAllocation->pvMem = (void *)pSurf->pSysMem;
2007 pAllocation->SurfDesc = pWddmAllocInfo->SurfDesc;
2008 }
2009 }
2010 }
2011
2012 vboxWddmRequestAllocFree(pDdiAllocate);
2013
2014 if (pGaD3DDevice9Ex)
2015 pGaD3DDevice9Ex->Release();
2016 }
2017 else
2018 {
2019 AssertFailed();
2020 hr = E_OUTOFMEMORY;
2021 }
2022 }
2023
2024 if (SUCCEEDED(hr))
2025 {
2026 pResource->hResource = pRc;
2027 hr = S_OK;
2028 }
2029 else
2030 {
2031 if (pRc)
2032 {
2033 /** @todo GaDdiDestroyResource(hDevice, pRc); */
2034 RTMemFree(pRc);
2035 }
2036 }
2037
2038 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), pRc 0x%p, hr %x\n", hDevice, pRc, hr));
2039 return hr;
2040}
2041
2042HRESULT APIENTRY GaDdiDestroyResource(HANDLE hDevice, HANDLE hResource)
2043{
2044 VBOXVDBG_BREAK_DDI();
2045
2046 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) hResource %p\n", hDevice, hResource));
2047
2048 HRESULT hr = S_OK;
2049 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2050 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
2051 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
2052
2053 if (VBOXDISPMODE_IS_3D(pAdapter))
2054 {
2055 for (UINT i = 0; i < pRc->cAllocations; ++i)
2056 {
2057 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
2058 if (pAlloc->hSharedHandle)
2059 {
2060 if (pAlloc->hSharedHandle == (HANDLE)(uintptr_t)pAlloc->hostID)
2061 {
2062 /* The original shared resource is being destroyed. */
2063 Assert(pRc->RcDesc.fFlags.SharedResource);
2064 }
2065 else if (i == 0)
2066 {
2067 /* This resource has been opened and maps to a the original shared resource. */
2068 /* Tell miniport to remove the sid -> shared sid mapping. */
2069 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
2070 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2071 HRESULT hr2 = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
2072 if (SUCCEEDED(hr2))
2073 {
2074 Assert(pGaD3DDevice9Ex);
2075 /* Inform the miniport. */
2076 VBOXDISPIFESCAPE_GASHAREDSID data;
2077 RT_ZERO(data);
2078 data.EscapeHdr.escapeCode = VBOXESC_GASHAREDSID;
2079 data.u32Sid = pAlloc->hostID;
2080 data.u32SharedSid = (uint32_t)~0;
2081 hr2 = pGaD3DDevice9Ex->EscapeCb(&data, sizeof(data), /* fHardwareAccess= */ false);
2082
2083 pGaD3DDevice9Ex->Release();
2084 }
2085 }
2086 }
2087
2088 if (pAlloc->pD3DIf)
2089 pAlloc->pD3DIf->Release();
2090 }
2091 }
2092
2093 if (pRc->fFlags.KmResource)
2094 {
2095 D3DDDICB_DEALLOCATE ddiDealloc;
2096 RT_ZERO(ddiDealloc);
2097 ddiDealloc.hResource = pRc->hResource;
2098 /* according to the docs the below two are ignored in case we set the hResource */
2099 // ddiDealloc.NumAllocations = 0;
2100 // ddiDealloc.HandleList = NULL;
2101 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &ddiDealloc);
2102 Assert(hr == S_OK);
2103 }
2104 else
2105 {
2106 Assert(!(pRc->fFlags.Opened));
2107 for (UINT j = 0; j < pRc->cAllocations; ++j)
2108 {
2109 if (pRc->aAllocations[j].hAllocation)
2110 {
2111 D3DDDICB_DEALLOCATE ddiDealloc;
2112 ddiDealloc.hResource = NULL;
2113 ddiDealloc.NumAllocations = 1;
2114 ddiDealloc.HandleList = &pRc->aAllocations[j].hAllocation;
2115 HRESULT hr2 = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &ddiDealloc);
2116 Assert(hr2 == S_OK); NOREF(hr2);
2117 }
2118 }
2119 }
2120
2121 RTMemFree(pRc);
2122
2123 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2124 return hr;
2125}
2126
2127HRESULT APIENTRY GaDdiOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE *pResource)
2128{
2129 VBOXVDBG_BREAK_DDI();
2130
2131 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2132
2133 HRESULT hr = S_OK;
2134 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2135
2136 Assert(pResource->hKMResource);
2137 Assert(pResource->NumAllocations);
2138
2139 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAllocZ(RT_UOFFSETOF_DYN(VBOXWDDMDISP_RESOURCE,
2140 aAllocations[pResource->NumAllocations]));
2141 if (pRc)
2142 {
2143 pRc->cAllocations = pResource->NumAllocations;
2144 pRc->hResource = pResource->hResource;
2145 pRc->hKMResource = pResource->hKMResource;
2146 pRc->pDevice = pDevice;
2147 pRc->RcDesc.enmRotation = pResource->Rotation;
2148 // pRc->fFlags.Value = 0;
2149 pRc->fFlags.Opened = 1;
2150 pRc->fFlags.KmResource = 1;
2151
2152 for (UINT i = 0; i < pResource->NumAllocations; ++i)
2153 {
2154 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
2155 pAllocation->iAlloc = i;
2156 pAllocation->pRc = pRc;
2157
2158 D3DDDI_OPENALLOCATIONINFO *pOAI = &pResource->pOpenAllocationInfo[i];
2159 if (pOAI->PrivateDriverDataSize == sizeof(VBOXWDDM_ALLOCINFO))
2160 {
2161 Assert(pOAI->pPrivateDriverData);
2162 PVBOXWDDM_ALLOCINFO pWddmAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
2163 pAllocation->hAllocation = pOAI->hAllocation;
2164 pAllocation->enmType = pWddmAllocInfo->enmType;
2165 pAllocation->hSharedHandle = (HANDLE)pWddmAllocInfo->hSharedHandle;
2166 pAllocation->SurfDesc = pWddmAllocInfo->SurfDesc;
2167 pAllocation->pvMem = NULL;
2168
2169 Assert(!pAllocation->hSharedHandle == (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE));
2170 }
2171#ifdef VBOX_WITH_VMSVGA3D_DX9
2172 else if (pOAI->PrivateDriverDataSize == sizeof(VBOXDXALLOCATIONDESC))
2173 {
2174 Assert(pOAI->pPrivateDriverData);
2175 VBOXDXALLOCATIONDESC *pAllocDesc = (VBOXDXALLOCATIONDESC *)pOAI->pPrivateDriverData;
2176 pAllocation->hAllocation = pOAI->hAllocation;
2177 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_D3D;
2178
2179 /* 'hSharedHandle' a sid of the allocation. */
2180 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2181 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
2182 HRESULT hr2 = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
2183 Assert(SUCCEEDED(hr2));
2184 if (SUCCEEDED(hr2))
2185 {
2186 Assert(pGaD3DDevice9Ex);
2187
2188 VBOXDISPIFESCAPE_SVGAGETSID data;
2189 memset(&data, 0, sizeof(data));
2190 data.EscapeHdr.escapeCode = VBOXESC_SVGAGETSID;
2191 data.hAllocation = pOAI->hAllocation;
2192 // data.u32Sid = 0;
2193 hr2 = pGaD3DDevice9Ex->EscapeCb(&data, sizeof(data), /* fHardwareAccess= */ false);
2194 if (SUCCEEDED(hr2))
2195 pAllocation->hSharedHandle = (HANDLE)(uintptr_t)data.u32Sid;
2196 else
2197 pAllocation->hSharedHandle = 0;
2198
2199 pGaD3DDevice9Ex->Release();
2200 }
2201
2202 pAllocation->AllocDesc = *pAllocDesc;
2203 pAllocation->pvMem = NULL;
2204 RT_ZERO(pAllocation->SurfDesc);
2205 pAllocation->SurfDesc.width = pAllocation->AllocDesc.surfaceInfo.size.width;
2206 pAllocation->SurfDesc.height = pAllocation->AllocDesc.surfaceInfo.size.height;
2207 pAllocation->SurfDesc.format = pAllocation->AllocDesc.enmDDIFormat;
2208 pAllocation->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pAllocation->AllocDesc.enmDDIFormat);
2209 pAllocation->SurfDesc.pitch = vboxWddmCalcPitch(pAllocation->AllocDesc.surfaceInfo.size.width, pAllocation->AllocDesc.enmDDIFormat);
2210 pAllocation->SurfDesc.depth = pAllocation->AllocDesc.surfaceInfo.size.depth;
2211 pAllocation->SurfDesc.slicePitch = 0;
2212 pAllocation->SurfDesc.d3dWidth = pAllocation->SurfDesc.width;
2213 pAllocation->SurfDesc.cbSize = pAllocation->AllocDesc.cbAllocation;
2214 if (pAllocation->AllocDesc.fPrimary)
2215 {
2216 pAllocation->SurfDesc.VidPnSourceId = pAllocation->AllocDesc.PrimaryDesc.VidPnSourceId;
2217 pAllocation->SurfDesc.RefreshRate.Numerator = pAllocDesc->PrimaryDesc.ModeDesc.RefreshRate.Numerator;
2218 pAllocation->SurfDesc.RefreshRate.Denominator = pAllocDesc->PrimaryDesc.ModeDesc.RefreshRate.Denominator;
2219 }
2220 }
2221#endif
2222 else
2223 {
2224 AssertFailed();
2225 hr = E_INVALIDARG;
2226 break;
2227 }
2228 }
2229
2230 if (!pResource->pPrivateDriverData || !pResource->PrivateDriverDataSize)
2231 {
2232 /* this is a "standard" allocation resource */
2233
2234 /* both should be actually zero */
2235 Assert(!pResource->pPrivateDriverData && !pResource->PrivateDriverDataSize);
2236
2237 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
2238 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
2239 // pRc->RcDesc.MultisampleQuality = 0;
2240 // pRc->RcDesc.MipLevels = 0;
2241 // pRc->RcDesc.Fvf = 0;
2242 pRc->RcDesc.fFlags.SharedResource = 1;
2243
2244 if (pResource->NumAllocations != 1)
2245 {
2246 WARN(("NumAllocations is expected to be 1, but was %d", pResource->NumAllocations));
2247 }
2248
2249 for (UINT i = 0; i < pResource->NumAllocations; ++i)
2250 {
2251 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
2252 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
2253 pAlloc->pD3DIf = NULL;
2254 }
2255
2256 D3DDDI_OPENALLOCATIONINFO *pOAI = &pResource->pOpenAllocationInfo[0];
2257 Assert(pOAI->pPrivateDriverData);
2258 Assert(pOAI->PrivateDriverDataSize >= sizeof(VBOXWDDM_ALLOCINFO));
2259 if (pOAI->pPrivateDriverData && pOAI->PrivateDriverDataSize == sizeof(VBOXWDDM_ALLOCINFO))
2260 {
2261 PVBOXWDDM_ALLOCINFO pWddmAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
2262 switch (pWddmAllocInfo->enmType)
2263 {
2264 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
2265 pRc->RcDesc.fFlags.Primary = 1;
2266 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
2267 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
2268 pRc->RcDesc.enmFormat = pWddmAllocInfo->SurfDesc.format;
2269 pRc->RcDesc.VidPnSourceId = pWddmAllocInfo->SurfDesc.VidPnSourceId;
2270 pRc->RcDesc.RefreshRate = pWddmAllocInfo->SurfDesc.RefreshRate;
2271 break;
2272 default:
2273 AssertFailed();
2274 hr = E_INVALIDARG;
2275 }
2276 }
2277#ifdef VBOX_WITH_VMSVGA3D_DX9
2278 else if (pOAI->pPrivateDriverData && pOAI->PrivateDriverDataSize == sizeof(VBOXDXALLOCATIONDESC))
2279 {
2280 /* This is D3D UMD (VBoxDX) resource. Do the same as for "generic" resource branch below. */
2281 VBOXDXALLOCATIONDESC *pAllocDesc = (VBOXDXALLOCATIONDESC *)pOAI->pPrivateDriverData;
2282
2283 pRc->fFlags.Generic = 1;
2284 pRc->cAllocations = 1;
2285 pRc->RcDesc.fFlags.Primary = pAllocDesc->fPrimary;
2286 pRc->RcDesc.fFlags.RenderTarget = 1;
2287 pRc->RcDesc.enmFormat = pAllocDesc->enmDDIFormat;
2288 if (pAllocDesc->fPrimary)
2289 {
2290 pRc->RcDesc.VidPnSourceId = pAllocDesc->PrimaryDesc.VidPnSourceId;
2291 pRc->RcDesc.RefreshRate.Numerator = pAllocDesc->PrimaryDesc.ModeDesc.RefreshRate.Numerator;
2292 pRc->RcDesc.RefreshRate.Denominator = pAllocDesc->PrimaryDesc.ModeDesc.RefreshRate.Denominator;
2293 }
2294
2295 hr = GaD3DIfCreateForRc(pRc);
2296 if (SUCCEEDED(hr))
2297 {
2298 /* Get the just created surface id and inform the miniport that the surface id
2299 * should be replaced with the original surface id.
2300 */
2301 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2302 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
2303 HRESULT hr2 = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
2304 if (SUCCEEDED(hr2))
2305 {
2306 Assert(pGaD3DDevice9Ex);
2307 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0]; /* First allocation is enough. */
2308 uint32_t u32Sid;
2309 hr2 = pGaD3DDevice9Ex->GaSurfaceId(pAllocation->pD3DIf, &u32Sid);
2310 if (SUCCEEDED(hr2))
2311 {
2312 /* Inform the miniport. */
2313 Assert(pAllocation->hSharedHandle);
2314
2315 pAllocation->hostID = u32Sid;
2316
2317 VBOXDISPIFESCAPE_GASHAREDSID data;
2318 RT_ZERO(data);
2319 data.EscapeHdr.escapeCode = VBOXESC_GASHAREDSID;
2320 data.u32Sid = u32Sid;
2321 data.u32SharedSid = (uint32_t)(uintptr_t)pAllocation->hSharedHandle;
2322 hr2 = pGaD3DDevice9Ex->EscapeCb(&data, sizeof(data), /* fHardwareAccess= */ false);
2323 }
2324 pGaD3DDevice9Ex->Release();
2325 }
2326 }
2327 }
2328#endif
2329 else
2330 hr = E_INVALIDARG;
2331 }
2332 else
2333 {
2334 /* this is a "generic" resource whose creation is initiated by the UMD */
2335 Assert(pResource->PrivateDriverDataSize == sizeof(VBOXWDDM_RCINFO));
2336 if (pResource->PrivateDriverDataSize == sizeof(VBOXWDDM_RCINFO))
2337 {
2338 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO *)pResource->pPrivateDriverData;
2339 Assert(pRcInfo->fFlags.Generic);
2340 Assert(!pRcInfo->fFlags.Opened);
2341 Assert(pRcInfo->cAllocInfos == pResource->NumAllocations);
2342
2343 pRc->fFlags.Value |= pRcInfo->fFlags.Value;
2344 pRc->fFlags.Generic = 1;
2345 pRc->RcDesc = pRcInfo->RcDesc;
2346 pRc->cAllocations = pResource->NumAllocations;
2347 Assert(pRc->RcDesc.fFlags.SharedResource);
2348
2349// ASMBreakpoint();
2350 hr = GaD3DIfCreateForRc(pRc);
2351 if (SUCCEEDED(hr))
2352 {
2353 /* Get the just created surface id and inform the miniport that the surface id
2354 * should be replaced with the original surface id.
2355 */
2356 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2357 IGaDirect3DDevice9Ex *pGaD3DDevice9Ex = NULL;
2358 HRESULT hr2 = pDevice9If->QueryInterface(IID_IGaDirect3DDevice9Ex, (void**)&pGaD3DDevice9Ex);
2359 if (SUCCEEDED(hr2))
2360 {
2361 Assert(pGaD3DDevice9Ex);
2362 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0]; /* First allocation is enough. */
2363 uint32_t u32Sid;
2364 hr2 = pGaD3DDevice9Ex->GaSurfaceId(pAllocation->pD3DIf, &u32Sid);
2365 if (SUCCEEDED(hr2))
2366 {
2367 /* Inform the miniport. */
2368 Assert(pAllocation->hSharedHandle);
2369
2370 pAllocation->hostID = u32Sid;
2371
2372 VBOXDISPIFESCAPE_GASHAREDSID data;
2373 RT_ZERO(data);
2374 data.EscapeHdr.escapeCode = VBOXESC_GASHAREDSID;
2375 data.u32Sid = u32Sid;
2376 data.u32SharedSid = (uint32_t)(uintptr_t)pAllocation->hSharedHandle;
2377 hr2 = pGaD3DDevice9Ex->EscapeCb(&data, sizeof(data), /* fHardwareAccess= */ false);
2378 }
2379 pGaD3DDevice9Ex->Release();
2380 }
2381 }
2382 }
2383 else
2384 hr = E_INVALIDARG;
2385 }
2386
2387 if (hr == S_OK)
2388 {
2389 pResource->hResource = pRc;
2390 vboxVDbgPrintF(("<== " __FUNCTION__ ", pRc(0x%p)\n", pRc));
2391 }
2392 else
2393 RTMemFree(pRc);
2394 }
2395 else
2396 {
2397 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pResource->NumAllocations));
2398 hr = E_OUTOFMEMORY;
2399 }
2400
2401 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2402 return hr;
2403}
2404
2405HRESULT APIENTRY GaDdiDrawPrimitive(HANDLE hDevice, const D3DDDIARG_DRAWPRIMITIVE *pData, const UINT *pFlagBuffer)
2406{
2407 VBOXVDBG_BREAK_DDI();
2408
2409 RT_NOREF(pFlagBuffer);
2410
2411 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2412
2413 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2414 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2415
2416 Assert(!pFlagBuffer);
2417 HRESULT hr = S_OK;
2418
2419 if (pDevice->cStreamSourcesUm)
2420 {
2421#ifdef DEBUG
2422 uint32_t cStreams = 0;
2423 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2424 {
2425 if(pDevice->aStreamSourceUm[i].pvBuffer)
2426 {
2427 ++cStreams;
2428 }
2429 }
2430
2431 Assert(cStreams);
2432 Assert(cStreams == pDevice->cStreamSourcesUm);
2433#endif
2434 if (pDevice->cStreamSourcesUm == 1)
2435 {
2436 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2437 {
2438 VBOXWDDMDISP_STREAMSOURCEUM *pStreamSourceUm = &pDevice->aStreamSourceUm[i];
2439 if (pStreamSourceUm->pvBuffer)
2440 {
2441 const void *pvVertexStream = (uint8_t *)pStreamSourceUm->pvBuffer
2442 + pData->VStart * pStreamSourceUm->cbStride;
2443 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
2444 pData->PrimitiveCount,
2445 pvVertexStream,
2446 pStreamSourceUm->cbStride);
2447 Assert(hr == S_OK);
2448 break;
2449 }
2450 }
2451 }
2452 else
2453 {
2454 /** @todo impl */
2455 WARN(("multiple user stream sources (%d) not implemented!!", pDevice->cStreamSourcesUm));
2456 }
2457 }
2458 else
2459 {
2460#ifdef DEBUG
2461 Assert(!pDevice->cStreamSourcesUm);
2462 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2463 {
2464 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
2465 }
2466
2467 uint32_t cStreams = 0;
2468 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2469 {
2470 if (pDevice->aStreamSource[i])
2471 {
2472 ++cStreams;
2473 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2474 }
2475 }
2476
2477 Assert(cStreams);
2478 Assert(cStreams == pDevice->cStreamSources);
2479#endif
2480 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
2481 pData->VStart,
2482 pData->PrimitiveCount);
2483 Assert(hr == S_OK);
2484 }
2485
2486 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2487 return hr;
2488}
2489
2490
2491HRESULT APIENTRY GaDdiDrawIndexedPrimitive(HANDLE hDevice, const D3DDDIARG_DRAWINDEXEDPRIMITIVE *pData)
2492{
2493 VBOXVDBG_BREAK_DDI();
2494
2495 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2496
2497 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2498 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2499
2500#ifdef DEBUG
2501 uint32_t cStreams = 0;
2502 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2503 {
2504 if(pDevice->aStreamSourceUm[i].pvBuffer)
2505 ++cStreams;
2506 }
2507
2508 Assert(cStreams == pDevice->cStreamSourcesUm);
2509
2510 cStreams = 0;
2511 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2512 {
2513 if (pDevice->aStreamSource[i])
2514 {
2515 ++cStreams;
2516 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2517 }
2518 }
2519
2520 Assert(cStreams == pDevice->cStreamSources);
2521#endif
2522
2523 HRESULT hr = S_OK;
2524
2525 if (pDevice->cStreamSourcesUm)
2526 {
2527 Assert(pDevice->cStreamSourcesUm == 1);
2528 Assert(pDevice->IndiciesInfo.uiStride == 2 || pDevice->IndiciesInfo.uiStride == 4);
2529
2530 const uint8_t *pu8IndexBuffer = NULL;
2531 if (pDevice->IndiciesInfo.pIndicesAlloc)
2532 {
2533 Assert(!pDevice->IndiciesInfo.pvIndicesUm);
2534
2535 pu8IndexBuffer = (const uint8_t *)pDevice->IndiciesInfo.pIndicesAlloc->pvMem;
2536 }
2537 else
2538 {
2539 pu8IndexBuffer = (const uint8_t *)pDevice->IndiciesInfo.pvIndicesUm;
2540 }
2541
2542 if (pu8IndexBuffer)
2543 {
2544 hr = E_FAIL; /* If nothing found. */
2545
2546 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2547 {
2548 VBOXWDDMDISP_STREAMSOURCEUM *pStreamSourceUm = &pDevice->aStreamSourceUm[i];
2549 if (pStreamSourceUm->pvBuffer)
2550 {
2551 hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
2552 pData->MinIndex,
2553 pData->NumVertices,
2554 pData->PrimitiveCount,
2555 pu8IndexBuffer + pDevice->IndiciesInfo.uiStride * pData->StartIndex,
2556 pDevice->IndiciesInfo.uiStride == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
2557 pStreamSourceUm->pvBuffer,
2558 pStreamSourceUm->cbStride);
2559 Assert(hr == S_OK);
2560
2561 if (SUCCEEDED(hr))
2562 {
2563 if (pDevice->IndiciesInfo.pIndicesAlloc)
2564 {
2565 HRESULT hr2 = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
2566 if(!SUCCEEDED(hr2))
2567 WARN(("SetIndices failed hr = 0x%x", hr2));
2568 }
2569 }
2570
2571 break;
2572 }
2573 }
2574 }
2575 else
2576 {
2577 WARN(("not expected!"));
2578 hr = E_FAIL;
2579 }
2580 }
2581 else
2582 {
2583 Assert(pDevice->IndiciesInfo.pIndicesAlloc);
2584 Assert(!pDevice->IndiciesInfo.pvIndicesUm);
2585 Assert(!pDevice->IndiciesInfo.pIndicesAlloc->LockInfo.cLocks);
2586 Assert(!pDevice->cStreamSourcesUm);
2587
2588 hr = pDevice9If->DrawIndexedPrimitive(pData->PrimitiveType,
2589 pData->BaseVertexIndex,
2590 pData->MinIndex,
2591 pData->NumVertices,
2592 pData->StartIndex,
2593 pData->PrimitiveCount);
2594 Assert(hr == S_OK);
2595 }
2596
2597 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2598 return hr;
2599}
2600
2601
2602HRESULT APIENTRY GaDdiDrawPrimitive2(HANDLE hDevice, const D3DDDIARG_DRAWPRIMITIVE2 *pData)
2603{
2604 VBOXVDBG_BREAK_DDI();
2605
2606 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2607
2608 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2609 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2610
2611 HRESULT hr = S_OK;
2612
2613 /* "Stream zero contains transform vertices and is the only stream that should be accessed." */
2614 if (pDevice->aStreamSource[0])
2615 {
2616 VBOXWDDMDISP_ALLOCATION *pStreamSource = pDevice->aStreamSource[0];
2617 VBOXWDDMDISP_STREAM_SOURCE_INFO *pStreamSourceInfo = &pDevice->StreamSourceInfo[0];
2618
2619 Assert(pStreamSourceInfo->uiStride != 0);
2620
2621 VBOXWDDMDISP_LOCKINFO *pLock = &pStreamSource->LockInfo;
2622 if (pLock->cLocks)
2623 {
2624 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
2625
2626 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
2627 (void *)( (uintptr_t)pStreamSource->pvMem
2628 + pStreamSourceInfo->uiOffset + pData->FirstVertexOffset),
2629 pStreamSourceInfo->uiStride);
2630 Assert(hr == S_OK);
2631
2632 hr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9 *)pStreamSource->pD3DIf,
2633 pStreamSourceInfo->uiOffset,
2634 pStreamSourceInfo->uiStride);
2635 Assert(hr == S_OK);
2636 }
2637 else
2638 {
2639 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
2640 pData->FirstVertexOffset / pStreamSourceInfo->uiStride,
2641 pData->PrimitiveCount);
2642 Assert(hr == S_OK);
2643 }
2644 }
2645 else
2646 {
2647 hr = E_FAIL;
2648 }
2649
2650 Assert(hr == S_OK);
2651 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2652 return hr;
2653}
2654
2655
2656static UINT vboxWddmVertexCountFromPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
2657{
2658 Assert(PrimitiveCount > 0); /* Callers ensure this. */
2659
2660 UINT cVertices;
2661 switch (PrimitiveType)
2662 {
2663 case D3DPT_POINTLIST:
2664 cVertices = PrimitiveCount; /* Vertex per point. */
2665 break;
2666
2667 case D3DPT_LINELIST:
2668 cVertices = PrimitiveCount * 2; /* Two vertices for each line. */
2669 break;
2670
2671 case D3DPT_LINESTRIP:
2672 cVertices = PrimitiveCount + 1; /* Two vertices for the first line and one vertex for each subsequent. */
2673 break;
2674
2675 case D3DPT_TRIANGLELIST:
2676 cVertices = PrimitiveCount * 3; /* Three vertices for each triangle. */
2677 break;
2678
2679 case D3DPT_TRIANGLESTRIP:
2680 case D3DPT_TRIANGLEFAN:
2681 cVertices = PrimitiveCount + 2; /* Three vertices for the first triangle and one vertex for each subsequent. */
2682 break;
2683
2684 default:
2685 cVertices = 0; /* No such primitive in d3d9types.h. */
2686 break;
2687 }
2688
2689 return cVertices;
2690}
2691
2692
2693HRESULT APIENTRY GaDdiDrawIndexedPrimitive2(HANDLE hDevice, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2 *pData,
2694 UINT dwIndicesSize, const VOID *pIndexBuffer, const UINT *pFlagBuffer)
2695{
2696 VBOXVDBG_BREAK_DDI();
2697
2698 RT_NOREF(pFlagBuffer);
2699
2700 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2701
2702 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2703 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2704
2705 HRESULT hr = S_OK;
2706
2707 const uint8_t *pu8VertexBuffer = NULL;
2708 DWORD cbVertexStride = 0;
2709
2710 LOGF(("\n PrimitiveType %d, BaseVertexOffset %d, MinIndex %d, NumVertices %d, StartIndexOffset %d, PrimitiveCount %d,\n"
2711 " dwIndicesSize %d, pIndexBuffer %p, pFlagBuffer %p\n",
2712 pData->PrimitiveType,
2713 pData->BaseVertexOffset,
2714 pData->MinIndex,
2715 pData->NumVertices,
2716 pData->StartIndexOffset,
2717 pData->PrimitiveCount,
2718 dwIndicesSize,
2719 pIndexBuffer,
2720 pFlagBuffer));
2721
2722 if (dwIndicesSize != 2 && dwIndicesSize != 4)
2723 {
2724 WARN(("unsupported dwIndicesSize %d", dwIndicesSize));
2725 return E_INVALIDARG;
2726 }
2727
2728 if (pData->PrimitiveCount == 0)
2729 {
2730 /* Nothing to draw. */
2731 return S_OK;
2732 }
2733
2734 /* Fetch the appropriate stream source:
2735 * "Stream zero contains transform indices and is the only stream that should be accessed."
2736 */
2737 if (pDevice->aStreamSourceUm[0].pvBuffer)
2738 {
2739 Assert(pDevice->aStreamSourceUm[0].cbStride);
2740
2741 pu8VertexBuffer = (const uint8_t *)pDevice->aStreamSourceUm[0].pvBuffer;
2742 cbVertexStride = pDevice->aStreamSourceUm[0].cbStride;
2743 LOGF(("aStreamSourceUm %p, stride %d\n",
2744 pu8VertexBuffer, cbVertexStride));
2745 }
2746 else if (pDevice->aStreamSource[0])
2747 {
2748 PVBOXWDDMDISP_ALLOCATION pAlloc = pDevice->aStreamSource[0];
2749 if (pAlloc->pvMem)
2750 {
2751 Assert(pDevice->StreamSourceInfo[0].uiStride);
2752 pu8VertexBuffer = ((const uint8_t *)pAlloc->pvMem) + pDevice->StreamSourceInfo[0].uiOffset;
2753 cbVertexStride = pDevice->StreamSourceInfo[0].uiStride;
2754 LOGF(("aStreamSource %p, cbSize %d, stride %d, uiOffset %d (elements %d)\n",
2755 pu8VertexBuffer, pAlloc->SurfDesc.cbSize, cbVertexStride, pDevice->StreamSourceInfo[0].uiOffset,
2756 cbVertexStride? pAlloc->SurfDesc.cbSize / cbVertexStride: 0));
2757 }
2758 else
2759 {
2760 WARN(("unsupported!!"));
2761 hr = E_FAIL;
2762 }
2763 }
2764 else
2765 {
2766 WARN(("not expected!"));
2767 hr = E_FAIL;
2768 }
2769
2770 if (SUCCEEDED(hr))
2771 {
2772 hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
2773 pData->MinIndex,
2774 pData->NumVertices,
2775 pData->PrimitiveCount,
2776 (uint8_t *)pIndexBuffer + pData->StartIndexOffset,
2777 dwIndicesSize == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
2778 pu8VertexBuffer + pData->BaseVertexOffset,
2779 cbVertexStride);
2780
2781 if (SUCCEEDED(hr))
2782 hr = S_OK;
2783 else
2784 WARN(("DrawIndexedPrimitiveUP failed hr = 0x%x", hr));
2785
2786 /* Following any IDirect3DDevice9::DrawIndexedPrimitiveUP call, the stream 0 settings,
2787 * referenced by IDirect3DDevice9::GetStreamSource, are set to NULL. Also, the index
2788 * buffer setting for IDirect3DDevice9::SetIndices is set to NULL.
2789 */
2790 if (pDevice->aStreamSource[0])
2791 {
2792 HRESULT tmpHr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[0]->pD3DIf,
2793 pDevice->StreamSourceInfo[0].uiOffset,
2794 pDevice->StreamSourceInfo[0].uiStride);
2795 if(!SUCCEEDED(tmpHr))
2796 WARN(("SetStreamSource failed hr = 0x%x", tmpHr));
2797 }
2798
2799 if (pDevice->IndiciesInfo.pIndicesAlloc)
2800 {
2801 HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
2802 if(!SUCCEEDED(tmpHr))
2803 WARN(("SetIndices failed hr = 0x%x", tmpHr));
2804 }
2805 }
2806
2807 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2808 return hr;
2809}
2810
2811HRESULT APIENTRY GaDdiSetRenderState(HANDLE hDevice, const D3DDDIARG_RENDERSTATE *pData)
2812{
2813 VBOXVDBG_BREAK_DDI();
2814
2815 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2816
2817 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2818 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2819
2820 D3DRENDERSTATETYPE const enmD3DRenderStateType = vboxDDI2D3DRenderStateType(pData->State);
2821 HRESULT hr = pDevice9If->SetRenderState(enmD3DRenderStateType, pData->Value);
2822 Assert(hr == S_OK);
2823
2824 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2825 return hr;
2826}
2827
2828HRESULT APIENTRY GaDdiUpdateWInfo(HANDLE hDevice, const D3DDDIARG_WINFO *pData)
2829{
2830 VBOXVDBG_BREAK_DDI();
2831
2832 RT_NOREF(hDevice, pData);
2833
2834 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2835
2836 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2837 return S_OK;
2838}
2839
2840HRESULT APIENTRY GaDdiValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE *pData)
2841{
2842 VBOXVDBG_BREAK_DDI();
2843
2844 RT_NOREF(hDevice, pData);
2845
2846 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2847
2848 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2849 return S_OK;
2850}
2851
2852HRESULT APIENTRY GaDdiSetTextureStageState(HANDLE hDevice, const D3DDDIARG_TEXTURESTAGESTATE *pData)
2853{
2854 VBOXVDBG_BREAK_DDI();
2855
2856 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2857
2858 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2859 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2860
2861 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
2862
2863 HRESULT hr;
2864 if (lookup.bSamplerState)
2865 {
2866 hr = pDevice9If->SetSamplerState(pData->Stage, (D3DSAMPLERSTATETYPE)lookup.dType, pData->Value);
2867 }
2868 else
2869 {
2870 hr = pDevice9If->SetTextureStageState(pData->Stage, (D3DTEXTURESTAGESTATETYPE)lookup.dType, pData->Value);
2871 }
2872 Assert(hr == S_OK);
2873
2874 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2875 return hr;
2876}
2877
2878HRESULT APIENTRY GaDdiSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
2879{
2880 VBOXVDBG_BREAK_DDI();
2881
2882 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2883
2884 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2885 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2886
2887 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
2888
2889 int const idx = VBOXWDDMDISP_SAMPLER_IDX(Stage);
2890 AssertMsgReturn(idx >= 0 && idx < RT_ELEMENTS(pDevice->aSamplerTextures),
2891 ("Stage %d, idx %d, hTexture %p\n", Stage, idx, hTexture), E_FAIL);
2892
2893 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2894
2895 IDirect3DBaseTexture9 *pD3DIfTex = NULL;
2896 if (pRc)
2897 {
2898 // VBOXVDBG_CHECK_SMSYNC(pRc);
2899 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
2900 {
2901 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
2902 }
2903 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE)
2904 {
2905 pD3DIfTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
2906 }
2907 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
2908 {
2909 pD3DIfTex = (IDirect3DVolumeTexture9*)pRc->aAllocations[0].pD3DIf;
2910 }
2911 else
2912 {
2913 AssertFailed();
2914 }
2915
2916 if (pD3DIfTex && !pDevice->aSamplerTextures[idx])
2917 {
2918 ++pDevice->cSamplerTextures;
2919 }
2920 }
2921 else
2922 {
2923 if (pDevice->aSamplerTextures[idx])
2924 {
2925 Assert(pDevice->cSamplerTextures);
2926 --pDevice->cSamplerTextures;
2927 }
2928 }
2929
2930 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2931 pDevice->aSamplerTextures[idx] = pRc;
2932
2933 HRESULT hr = pDevice9If->SetTexture(Stage, pD3DIfTex);
2934 Assert(hr == S_OK);
2935
2936 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2937 return hr;
2938}
2939
2940HRESULT APIENTRY GaDdiSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
2941{
2942 VBOXVDBG_BREAK_DDI();
2943
2944 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2945
2946 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2947 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2948
2949 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9 *)hShaderHandle;
2950 HRESULT hr = pDevice9If->SetPixelShader(pShader);
2951 Assert(hr == S_OK);
2952
2953 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2954 return hr;
2955}
2956
2957HRESULT APIENTRY GaDdiSetPixelShaderConst(HANDLE hDevice, const D3DDDIARG_SETPIXELSHADERCONST *pData,
2958 const FLOAT *pRegisters)
2959{
2960 VBOXVDBG_BREAK_DDI();
2961
2962 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2963 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2964 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2965
2966 HRESULT hr = pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
2967 Assert(hr == S_OK);
2968
2969 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2970 return hr;
2971}
2972
2973HRESULT APIENTRY GaDdiSetStreamSourceUm(HANDLE hDevice, const D3DDDIARG_SETSTREAMSOURCEUM *pData,
2974 const VOID *pUMBuffer)
2975{
2976 VBOXVDBG_BREAK_DDI();
2977
2978 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
2979
2980 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2981 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
2982
2983 AssertReturn(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm), E_INVALIDARG);
2984
2985 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
2986 if (pStrSrcUm->pvBuffer && !pUMBuffer)
2987 {
2988 --pDevice->cStreamSourcesUm;
2989 Assert(pDevice->cStreamSourcesUm < UINT32_MAX/2);
2990 }
2991 else if (!pStrSrcUm->pvBuffer && pUMBuffer)
2992 {
2993 ++pDevice->cStreamSourcesUm;
2994 Assert(pDevice->cStreamSourcesUm <= RT_ELEMENTS(pDevice->aStreamSourceUm));
2995 }
2996
2997 pStrSrcUm->pvBuffer = pUMBuffer;
2998 pStrSrcUm->cbStride = pData->Stride;
2999
3000 HRESULT hr = S_OK;
3001 if (pDevice->aStreamSource[pData->Stream])
3002 {
3003 hr = pDevice9If->SetStreamSource(pData->Stream, NULL, 0, 0);
3004 pDevice->aStreamSource[pData->Stream] = NULL;
3005
3006 --pDevice->cStreamSources;
3007 Assert(pDevice->cStreamSources < UINT32_MAX/2);
3008 }
3009
3010 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3011 return hr;
3012}
3013
3014HRESULT APIENTRY GaDdiSetIndices(HANDLE hDevice, const D3DDDIARG_SETINDICES *pData)
3015{
3016 VBOXVDBG_BREAK_DDI();
3017
3018 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3019
3020 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3021 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3022
3023 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
3024 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3025 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
3026 if (pRc)
3027 {
3028 // VBOXVDBG_CHECK_SMSYNC(pRc);
3029 Assert(pRc->cAllocations == 1);
3030
3031 pAlloc = &pRc->aAllocations[0];
3032 Assert(pAlloc->pD3DIf);
3033
3034 pIndexBuffer = (IDirect3DIndexBuffer9 *)pAlloc->pD3DIf;
3035 }
3036
3037 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
3038 Assert(hr == S_OK);
3039 if (hr == S_OK)
3040 {
3041 pDevice->IndiciesInfo.pIndicesAlloc = pAlloc;
3042 pDevice->IndiciesInfo.uiStride = pData->Stride;
3043 pDevice->IndiciesInfo.pvIndicesUm = NULL;
3044 }
3045
3046 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3047 return hr;
3048}
3049
3050HRESULT APIENTRY GaDdiSetIndicesUm(HANDLE hDevice, UINT IndexSize, const VOID *pUMBuffer)
3051{
3052 VBOXVDBG_BREAK_DDI();
3053
3054 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3055
3056 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3057 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3058
3059 HRESULT hr = S_OK;
3060 if (pDevice->IndiciesInfo.pIndicesAlloc)
3061 {
3062 hr = pDevice9If->SetIndices(NULL);
3063 }
3064
3065 if (SUCCEEDED(hr))
3066 {
3067 pDevice->IndiciesInfo.pvIndicesUm = pUMBuffer;
3068 pDevice->IndiciesInfo.uiStride = IndexSize;
3069 pDevice->IndiciesInfo.pIndicesAlloc = NULL;
3070 hr = S_OK;
3071 }
3072 else
3073 {
3074 WARN(("SetIndices failed hr 0x%x", hr));
3075 }
3076
3077 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3078 return hr;
3079}
3080
3081HRESULT APIENTRY GaDdiBufBlt(HANDLE hDevice, const D3DDDIARG_BUFFERBLT *pData)
3082{
3083 VBOXVDBG_BREAK_DDI();
3084
3085 RT_NOREF(pData);
3086
3087 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3088 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3089 RT_NOREF(pDevice);
3090
3091 /// @todo Not implemented.
3092 AssertFailed();
3093
3094 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3095 return E_NOTIMPL;
3096}
3097
3098HRESULT APIENTRY GaDdiStateSet(HANDLE hDevice, D3DDDIARG_STATESET *pData)
3099{
3100 VBOXVDBG_BREAK_DDI();
3101
3102 RT_NOREF(pData);
3103
3104 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3105
3106 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3107 RT_NOREF(pDevice);
3108
3109 /// @todo Not implemented.
3110 AssertFailed();
3111
3112 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3113 return E_NOTIMPL;
3114}
3115
3116HRESULT APIENTRY GaDdiSetPriority(HANDLE hDevice, const D3DDDIARG_SETPRIORITY *pData)
3117{
3118 VBOXVDBG_BREAK_DDI();
3119
3120 RT_NOREF(pData);
3121
3122 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3123
3124 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3125 RT_NOREF(pDevice);
3126
3127 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3128
3129 return S_OK;
3130}
3131
3132AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
3133AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
3134AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
3135AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
3136AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
3137AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
3138AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
3139AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
3140AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
3141
3142HRESULT APIENTRY GaDdiClear(HANDLE hDevice, const D3DDDIARG_CLEAR *pData, UINT NumRect, const RECT *pRect)
3143{
3144 VBOXVDBG_BREAK_DDI();
3145
3146 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3147
3148 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3149 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3150
3151 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT *)pRect /* see AssertCompile above */,
3152 pData->Flags,
3153 pData->FillColor,
3154 pData->FillDepth,
3155 pData->FillStencil);
3156 Assert(hr == S_OK);
3157
3158 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3159 return hr;
3160}
3161
3162HRESULT APIENTRY GaDdiUpdatePalette(HANDLE hDevice, const D3DDDIARG_UPDATEPALETTE *pData,
3163 const PALETTEENTRY *pPaletteData)
3164{
3165 VBOXVDBG_BREAK_DDI();
3166
3167 RT_NOREF(pData, pPaletteData);
3168
3169 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3170
3171 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3172 RT_NOREF(pDevice);
3173
3174 /// @todo Not implemented.
3175 AssertFailed();
3176
3177 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3178 return E_NOTIMPL;
3179}
3180
3181HRESULT APIENTRY GaDdiSetPalette(HANDLE hDevice, const D3DDDIARG_SETPALETTE *pData)
3182{
3183 VBOXVDBG_BREAK_DDI();
3184
3185 RT_NOREF(pData);
3186
3187 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3188
3189 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3190 RT_NOREF(pDevice);
3191
3192 /// @todo Not implemented.
3193 AssertFailed();
3194
3195 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3196 return E_NOTIMPL;
3197}
3198
3199HRESULT APIENTRY GaDdiMultiplyTransform(HANDLE hDevice, const D3DDDIARG_MULTIPLYTRANSFORM *pData)
3200{
3201 VBOXVDBG_BREAK_DDI();
3202
3203 RT_NOREF(pData);
3204
3205 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3206
3207 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3208 RT_NOREF(pDevice);
3209
3210 /// @todo Not implemented.
3211 AssertFailed();
3212
3213 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3214 return E_NOTIMPL;
3215}
3216
3217HRESULT APIENTRY GaDdiSetTransform(HANDLE hDevice, const D3DDDIARG_SETTRANSFORM *pData)
3218{
3219 VBOXVDBG_BREAK_DDI();
3220
3221 RT_NOREF(pData);
3222
3223 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3224
3225 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3226 RT_NOREF(pDevice);
3227
3228 /// @todo Not implemented.
3229 AssertFailed();
3230
3231 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3232 return E_NOTIMPL;
3233}
3234
3235HRESULT APIENTRY GaDdiSetViewport(HANDLE hDevice, const D3DDDIARG_VIEWPORTINFO *pData)
3236{
3237 VBOXVDBG_BREAK_DDI();
3238
3239 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3240
3241 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3242 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3243
3244 pDevice->ViewPort.X = pData->X;
3245 pDevice->ViewPort.Y = pData->Y;
3246 pDevice->ViewPort.Width = pData->Width;
3247 pDevice->ViewPort.Height = pData->Height;
3248 pDevice->fViewPort = true;
3249
3250 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3251 Assert(hr == S_OK);
3252
3253 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3254 return hr;
3255}
3256
3257HRESULT APIENTRY GaDdiSetZRange(HANDLE hDevice, const D3DDDIARG_ZRANGE *pData)
3258{
3259 VBOXVDBG_BREAK_DDI();
3260
3261 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3262
3263 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3264 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3265
3266 pDevice->ViewPort.MinZ = pData->MinZ;
3267 pDevice->ViewPort.MaxZ = pData->MaxZ;
3268 pDevice->fViewPort = true;
3269
3270 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3271 Assert(hr == S_OK);
3272
3273 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3274 return hr;
3275}
3276
3277HRESULT APIENTRY GaDdiSetMaterial(HANDLE hDevice, const D3DDDIARG_SETMATERIAL *pData)
3278{
3279 VBOXVDBG_BREAK_DDI();
3280
3281 RT_NOREF(pData);
3282
3283 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3284
3285 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3286 RT_NOREF(pDevice);
3287
3288 /// @todo Not implemented.
3289 AssertFailed();
3290
3291 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3292 return E_NOTIMPL;
3293}
3294
3295HRESULT APIENTRY GaDdiSetLight(HANDLE hDevice, const D3DDDIARG_SETLIGHT *pData, const D3DDDI_LIGHT *pLightProperties)
3296{
3297 VBOXVDBG_BREAK_DDI();
3298
3299 RT_NOREF(pData, pLightProperties);
3300
3301 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3302
3303 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3304 RT_NOREF(pDevice);
3305
3306 /// @todo Not implemented.
3307 AssertFailed();
3308
3309 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3310 return E_NOTIMPL;
3311}
3312
3313HRESULT APIENTRY GaDdiCreateLight(HANDLE hDevice, const D3DDDIARG_CREATELIGHT *pData)
3314{
3315 VBOXVDBG_BREAK_DDI();
3316
3317 RT_NOREF(pData);
3318
3319 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3320
3321 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3322 RT_NOREF(pDevice);
3323
3324 /// @todo Not implemented.
3325 AssertFailed();
3326
3327 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3328 return E_NOTIMPL;
3329}
3330
3331HRESULT APIENTRY GaDdiDestroyLight(HANDLE hDevice, const D3DDDIARG_DESTROYLIGHT *pData)
3332{
3333 VBOXVDBG_BREAK_DDI();
3334
3335 RT_NOREF(pData);
3336
3337 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3338
3339 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3340 RT_NOREF(pDevice);
3341
3342 /// @todo Not implemented.
3343 AssertFailed();
3344
3345 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3346 return E_NOTIMPL;
3347}
3348
3349HRESULT APIENTRY GaDdiSetClipPlane(HANDLE hDevice, const D3DDDIARG_SETCLIPPLANE *pData)
3350{
3351 VBOXVDBG_BREAK_DDI();
3352
3353 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3354
3355 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3356 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3357
3358 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
3359 Assert(hr == S_OK);
3360
3361 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3362 return hr;
3363}
3364
3365HRESULT APIENTRY GaDdiGetInfo(HANDLE hDevice, UINT DevInfoID, VOID *pDevInfoStruct, UINT DevInfoSize)
3366{
3367 VBOXVDBG_BREAK_DDI();
3368
3369 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3370
3371 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3372 RT_NOREF(pDevice);
3373
3374 HRESULT hr = S_OK;
3375 switch (DevInfoID)
3376 {
3377 case D3DDDIDEVINFOID_VCACHE:
3378 {
3379 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
3380 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
3381 {
3382 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
3383 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
3384 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
3385 pVCache->CacheSize = 0;
3386 pVCache->MagicNumber = 0;
3387 }
3388 else
3389 hr = E_INVALIDARG;
3390 break;
3391 }
3392
3393 default:
3394 AssertFailed();
3395 hr = E_NOTIMPL;
3396 }
3397
3398 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3399 return hr;
3400}
3401
3402HRESULT APIENTRY GaDdiSetDisplayMode(HANDLE hDevice, const D3DDDIARG_SETDISPLAYMODE *pData)
3403{
3404 VBOXVDBG_BREAK_DDI();
3405
3406 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3407
3408 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3409 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
3410
3411 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3412 Assert(pRc);
3413 Assert(pRc->cAllocations > pData->SubResourceIndex);
3414
3415 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3416 Assert(pRc->RcDesc.fFlags.RenderTarget);
3417 Assert(pRc->RcDesc.fFlags.Primary);
3418 Assert(pAlloc->hAllocation);
3419
3420 D3DDDICB_SETDISPLAYMODE DdiDm;
3421 RT_ZERO(DdiDm);
3422 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
3423
3424 HRESULT hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
3425 Assert(hr == S_OK);
3426
3427 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3428 return hr;
3429}
3430
3431AssertCompile(sizeof(D3DDDIVERTEXELEMENT) == sizeof(D3DVERTEXELEMENT9));
3432AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
3433AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
3434AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
3435AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
3436AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
3437AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
3438AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
3439AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
3440AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
3441AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
3442AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
3443AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
3444
3445HRESULT APIENTRY GaDdiCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL *pData,
3446 const D3DDDIVERTEXELEMENT *pVertexElements)
3447{
3448 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
3449
3450 VBOXVDBG_BREAK_DDI();
3451
3452 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3453
3454 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3455 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3456
3457 HRESULT hr = S_OK;
3458
3459 D3DVERTEXELEMENT9 *pVe = NULL;
3460 if (memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof(DeclEnd)) != 0)
3461 {
3462 pVe = (D3DVERTEXELEMENT9 *)RTMemAlloc(sizeof(D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
3463 if (pVe)
3464 {
3465 memcpy(pVe, pVertexElements, sizeof(D3DVERTEXELEMENT9) * pData->NumVertexElements);
3466 pVe[pData->NumVertexElements] = DeclEnd;
3467 }
3468 else
3469 hr = E_OUTOFMEMORY;
3470 }
3471 else
3472 pVe = (D3DVERTEXELEMENT9 *)pVertexElements;
3473
3474 if (hr == S_OK)
3475 {
3476 IDirect3DVertexDeclaration9 *pDecl = NULL;
3477 hr = pDevice9If->CreateVertexDeclaration(pVe, &pDecl);
3478 Assert(hr == S_OK);
3479 if (hr == S_OK)
3480 {
3481 Assert(pDecl);
3482 pData->ShaderHandle = pDecl;
3483 }
3484 }
3485
3486 if (pVe && pVe != (D3DVERTEXELEMENT9 *)pVertexElements)
3487 RTMemFree(pVe);
3488
3489 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3490 return hr;
3491}
3492
3493HRESULT APIENTRY GaDdiSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
3494{
3495 VBOXVDBG_BREAK_DDI();
3496
3497 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3498
3499 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3500 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3501
3502 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9 *)hShaderHandle;
3503
3504 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
3505 Assert(hr == S_OK);
3506
3507 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3508 return hr;
3509}
3510
3511HRESULT APIENTRY GaDdiDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
3512{
3513 VBOXVDBG_BREAK_DDI();
3514
3515 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3516
3517 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3518 RT_NOREF(pDevice);
3519
3520 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9 *)hShaderHandle;
3521
3522 pDecl->Release();
3523
3524 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, S_OK));
3525 return S_OK;
3526}
3527
3528HRESULT APIENTRY GaDdiSetScissorRect(HANDLE hDevice, const RECT *pRect)
3529{
3530 VBOXVDBG_BREAK_DDI();
3531
3532 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3533
3534 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3535 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3536
3537 pDevice->ScissorRect = *pRect;
3538 pDevice->fScissorRect = true;
3539
3540 HRESULT hr = pDevice9If->SetScissorRect(pRect);
3541 Assert(hr == S_OK);
3542
3543 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3544 return hr;
3545}
3546
3547HRESULT APIENTRY GaDdiSetStreamSource(HANDLE hDevice, const D3DDDIARG_SETSTREAMSOURCE *pData)
3548{
3549 VBOXVDBG_BREAK_DDI();
3550
3551 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3552
3553 AssertReturn(pData->Stream < VBOXWDDMDISP_MAX_VERTEX_STREAMS, E_INVALIDARG);
3554
3555 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3556 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3557
3558 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3559 IDirect3DVertexBuffer9 *pStreamData = NULL;
3560
3561 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
3562 if (pRc)
3563 {
3564 // VBOXVDBG_CHECK_SMSYNC(pRc);
3565 Assert(pRc->cAllocations == 1);
3566 pAlloc = &pRc->aAllocations[0];
3567
3568 Assert(pAlloc->pD3DIf);
3569 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
3570 }
3571
3572 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
3573 Assert(hr == S_OK);
3574 if (hr == S_OK)
3575 {
3576 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
3577 {
3578 --pDevice->cStreamSources;
3579 Assert(pDevice->cStreamSources < UINT32_MAX/2);
3580 }
3581 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
3582 {
3583 ++pDevice->cStreamSources;
3584 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
3585 }
3586
3587 pDevice->aStreamSource[pData->Stream] = pAlloc;
3588 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
3589 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
3590
3591 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
3592 if (pStrSrcUm->pvBuffer)
3593 {
3594 --pDevice->cStreamSourcesUm;
3595 Assert(pDevice->cStreamSourcesUm < UINT32_MAX/2);
3596
3597 pStrSrcUm->pvBuffer = NULL;
3598 pStrSrcUm->cbStride = 0;
3599 }
3600 }
3601
3602 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3603 return hr;
3604}
3605
3606HRESULT APIENTRY GaDdiSetStreamSourceFreq(HANDLE hDevice, const D3DDDIARG_SETSTREAMSOURCEFREQ *pData)
3607{
3608 VBOXVDBG_BREAK_DDI();
3609
3610 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3611
3612 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3613 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3614
3615 HRESULT hr = pDevice9If->SetStreamSourceFreq(pData->Stream, pData->Divider);
3616 Assert(hr == S_OK);
3617
3618 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3619 return hr;
3620}
3621
3622HRESULT APIENTRY GaDdiSetConvolutionKernelMono(HANDLE hDevice, const D3DDDIARG_SETCONVOLUTIONKERNELMONO *pData)
3623{
3624 VBOXVDBG_BREAK_DDI();
3625
3626 RT_NOREF(pData);
3627
3628 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3629
3630 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3631 RT_NOREF(pDevice);
3632
3633 /// @todo Not implemented.
3634 AssertFailed();
3635
3636 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3637 return E_NOTIMPL;
3638}
3639
3640HRESULT APIENTRY GaDdiComposeRects(HANDLE hDevice, const D3DDDIARG_COMPOSERECTS *pData)
3641{
3642 VBOXVDBG_BREAK_DDI();
3643
3644 RT_NOREF(pData);
3645
3646 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3647
3648 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3649 RT_NOREF(pDevice);
3650
3651 /// @todo Not implemented.
3652 AssertFailed();
3653
3654 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3655 return E_NOTIMPL;
3656}
3657
3658HRESULT APIENTRY GaDdiColorFill(HANDLE hDevice, const D3DDDIARG_COLORFILL *pData)
3659{
3660 VBOXVDBG_BREAK_DDI();
3661
3662 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3663
3664 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3665 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3666
3667 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3668 Assert(pRc);
3669
3670 IDirect3DSurface9 *pSurfIf = NULL;
3671 HRESULT hr = VBoxD3DIfSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
3672 Assert(hr == S_OK);
3673 if (hr == S_OK)
3674 {
3675 // VBOXVDBG_CHECK_SMSYNC(pRc);
3676 Assert(pSurfIf);
3677
3678 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
3679 Assert(hr == S_OK);
3680
3681 /** @todo check what need to do when PresentToDwm flag is set */
3682 Assert(pData->Flags.Value == 0);
3683
3684 pSurfIf->Release();
3685 }
3686
3687 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3688 return hr;
3689}
3690
3691HRESULT APIENTRY GaDdiDepthFill(HANDLE hDevice, const D3DDDIARG_DEPTHFILL *pData)
3692{
3693 VBOXVDBG_BREAK_DDI();
3694
3695 RT_NOREF(pData);
3696
3697 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3698
3699 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3700 RT_NOREF(pDevice);
3701
3702 /// @todo Not implemented.
3703 AssertFailed();
3704
3705 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3706 return E_NOTIMPL;
3707}
3708
3709HRESULT APIENTRY GaDdiCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY *pData)
3710{
3711 VBOXVDBG_BREAK_DDI();
3712
3713 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3714
3715 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3716 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3717
3718 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof(VBOXWDDMDISP_QUERY));
3719 AssertReturn(pQuery, E_OUTOFMEMORY);
3720
3721 D3DQUERYTYPE const d3dQueryType = vboxDDI2D3DQueryType(pData->QueryType);
3722 HRESULT hr = pDevice9If->CreateQuery(d3dQueryType, &pQuery->pQueryIf);
3723 if (hr == S_OK)
3724 {
3725 pQuery->enmType = pData->QueryType;
3726 pData->hQuery = pQuery;
3727 }
3728 else
3729 {
3730 WARN(("CreateQuery failed, hr 0x%x", hr));
3731 RTMemFree(pQuery);
3732 }
3733
3734 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3735 return hr;
3736}
3737
3738HRESULT APIENTRY GaDdiDestroyQuery(HANDLE hDevice, HANDLE hQuery)
3739{
3740 VBOXVDBG_BREAK_DDI();
3741
3742 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3743
3744 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3745 RT_NOREF(pDevice);
3746
3747 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
3748 Assert(pQuery);
3749 if (pQuery)
3750 {
3751 Assert(pQuery->pQueryIf);
3752 if (pQuery->pQueryIf)
3753 {
3754 pQuery->pQueryIf->Release();
3755 }
3756 RTMemFree(pQuery);
3757 }
3758
3759 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3760 return S_OK;
3761}
3762
3763HRESULT APIENTRY GaDdiIssueQuery(HANDLE hDevice, const D3DDDIARG_ISSUEQUERY *pData)
3764{
3765 VBOXVDBG_BREAK_DDI();
3766
3767 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3768
3769 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3770 RT_NOREF(pDevice);
3771
3772 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
3773 AssertReturn(pQuery, E_INVALIDARG);
3774
3775 pQuery->fQueryState.Value |= pData->Flags.Value;
3776
3777 DWORD const d3dQueryFlags = vboxDDI2D3DIssueQueryFlags(pData->Flags);
3778 HRESULT hr = pQuery->pQueryIf->Issue(d3dQueryFlags);
3779 Assert(hr == S_OK);
3780
3781 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3782 return hr;
3783}
3784
3785HRESULT APIENTRY GaDdiGetQueryData(HANDLE hDevice, const D3DDDIARG_GETQUERYDATA *pData)
3786{
3787 VBOXVDBG_BREAK_DDI();
3788
3789 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3790
3791 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3792 RT_NOREF(pDevice);
3793
3794 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
3795 AssertReturn(pQuery && pQuery->pQueryIf, E_INVALIDARG);
3796
3797 DWORD const cbData = pQuery->pQueryIf->GetDataSize();
3798#ifdef DEBUG
3799 switch (pQuery->enmType)
3800 {
3801 case D3DDDIQUERYTYPE_EVENT:
3802 Assert(cbData == sizeof (BOOL));
3803 break;
3804 case D3DDDIQUERYTYPE_OCCLUSION:
3805 Assert(cbData == sizeof (UINT));
3806 break;
3807 default:
3808 AssertFailed();
3809 break;
3810 }
3811#endif
3812
3813 HRESULT hr = pQuery->pQueryIf->GetData(pData->pData, cbData, 0);
3814 Assert(hr == S_OK || hr == S_FALSE);
3815
3816#ifdef DEBUG
3817 switch (pQuery->enmType)
3818 {
3819 case D3DDDIQUERYTYPE_EVENT:
3820 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) D3DDDIQUERYTYPE_EVENT %d\n", hDevice, *(BOOL *)pData->pData));
3821 break;
3822 case D3DDDIQUERYTYPE_OCCLUSION:
3823 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p) D3DDDIQUERYTYPE_OCCLUSION %d\n", hDevice, *(UINT *)pData->pData));
3824 break;
3825 default:
3826 break;
3827 }
3828#endif
3829
3830 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3831 return hr;
3832}
3833
3834#if 0
3835static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc)
3836{
3837 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3838 HRESULT hr = S_OK;
3839 IDirect3DSurface9 *pD3D9Surf = NULL;
3840 if (pAlloc)
3841 {
3842 hr = VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
3843 if (FAILED(hr))
3844 {
3845 WARN(("VBoxD3DIfSurfGet failed, hr(0x%x)",hr));
3846 return hr;
3847 }
3848
3849 Assert(pD3D9Surf);
3850 }
3851
3852 hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
3853 if (hr == S_OK)
3854 {
3855 pDevice->apRTs[iRt] = pAlloc;
3856 }
3857 else
3858 {
3859 /** @todo This is workaround for wine 1 render target. */
3860 if (!pAlloc)
3861 {
3862 pDevice->apRTs[iRt] = NULL;
3863 hr = S_OK;
3864 }
3865 else
3866 {
3867 AssertFailed();
3868 }
3869 }
3870
3871 if (pD3D9Surf)
3872 {
3873 pD3D9Surf->Release();
3874 }
3875
3876 return hr;
3877}
3878#endif
3879
3880HRESULT APIENTRY GaDdiSetRenderTarget(HANDLE hDevice, const D3DDDIARG_SETRENDERTARGET *pData)
3881{
3882 VBOXVDBG_BREAK_DDI();
3883
3884 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3885
3886 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3887 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3888
3889 AssertReturn(pData->RenderTargetIndex < pDevice->cRTs, E_INVALIDARG);
3890
3891 HRESULT hr = S_OK;
3892 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
3893 IDirect3DSurface9 *pD3D9Surf = NULL;
3894 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
3895 if (pRc)
3896 {
3897 // VBOXVDBG_CHECK_SMSYNC(pRc);
3898 Assert(pData->SubResourceIndex < pRc->cAllocations);
3899
3900 pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3901 hr = VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
3902 if (FAILED(hr))
3903 {
3904 WARN(("VBoxD3DIfSurfGet failed, hr(0x%x)",hr));
3905 return hr;
3906 }
3907
3908 Assert(pD3D9Surf);
3909 }
3910
3911 hr = pDevice9If->SetRenderTarget(pData->RenderTargetIndex, pD3D9Surf);
3912 Assert(hr == S_OK);
3913 if (hr == S_OK)
3914 {
3915 pDevice->apRTs[pData->RenderTargetIndex] = pAlloc;
3916
3917 /* IDirect3DDevice9::SetRenderTarget method resets the viewport and the scissor rectangle. */
3918 if (pDevice->fViewPort)
3919 {
3920 pDevice9If->SetViewport(&pDevice->ViewPort);
3921 }
3922 if (pDevice->fScissorRect)
3923 {
3924 pDevice9If->SetScissorRect(&pDevice->ScissorRect);
3925 }
3926 }
3927
3928 if (pD3D9Surf)
3929 {
3930 pD3D9Surf->Release();
3931 }
3932
3933 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3934 return hr;
3935}
3936
3937HRESULT APIENTRY GaDdiSetDepthStencil(HANDLE hDevice, const D3DDDIARG_SETDEPTHSTENCIL *pData)
3938{
3939 VBOXVDBG_BREAK_DDI();
3940
3941 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3942
3943 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3944 IDirect3DDevice9 *pDevice9If = VBOXDISP_D3DEV(pDevice);
3945
3946 HRESULT hr = S_OK;
3947 IDirect3DSurface9 *pD3D9Surf = NULL;
3948
3949 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
3950 if (pRc)
3951 {
3952 // VBOXVDBG_CHECK_SMSYNC(pRc);
3953 Assert(pRc->cAllocations == 1);
3954
3955 hr = VBoxD3DIfSurfGet(pRc, 0, &pD3D9Surf);
3956 if (FAILED(hr))
3957 WARN(("VBoxD3DIfSurfGet failed, hr (0x%x)",hr));
3958 else
3959 Assert(pD3D9Surf);
3960 }
3961
3962 if (SUCCEEDED(hr))
3963 {
3964 hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
3965 if (SUCCEEDED(hr))
3966 {
3967 pDevice->pDepthStencilRc = pRc;
3968 }
3969 else
3970 WARN(("VBoxD3DIfSurfGet failed, hr (0x%x)",hr));
3971
3972 if (pD3D9Surf)
3973 pD3D9Surf->Release();
3974 }
3975
3976 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3977 return hr;
3978}
3979
3980HRESULT APIENTRY GaDdiGenerateMipSubLevels(HANDLE hDevice, const D3DDDIARG_GENERATEMIPSUBLEVELS *pData)
3981{
3982 VBOXVDBG_BREAK_DDI();
3983
3984 RT_NOREF(pData);
3985
3986 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3987
3988 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3989 RT_NOREF(pDevice);
3990
3991 /// @todo Not implemented.
3992 AssertFailed();
3993
3994 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
3995 return E_NOTIMPL;
3996}
3997
3998HRESULT APIENTRY GaDdiCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE *pData)
3999{
4000 VBOXVDBG_BREAK_DDI();
4001
4002 RT_NOREF(pData);
4003
4004 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4005
4006 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4007 RT_NOREF(pDevice);
4008
4009 /// @todo Not implemented.
4010 AssertFailed();
4011
4012 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4013 return E_NOTIMPL;
4014}
4015
4016HRESULT APIENTRY GaDdiDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
4017{
4018 VBOXVDBG_BREAK_DDI();
4019
4020 RT_NOREF(hDecodeDevice);
4021
4022 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4023
4024 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4025 RT_NOREF(pDevice);
4026
4027 /// @todo Not implemented.
4028 AssertFailed();
4029
4030 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4031 return E_NOTIMPL;
4032}
4033
4034HRESULT APIENTRY GaDdiSetDecodeRenderTarget(HANDLE hDevice, const D3DDDIARG_SETDECODERENDERTARGET *pData)
4035{
4036 VBOXVDBG_BREAK_DDI();
4037
4038 RT_NOREF(pData);
4039
4040 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4041
4042 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4043 RT_NOREF(pDevice);
4044
4045 /// @todo Not implemented.
4046 AssertFailed();
4047
4048 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4049 return E_NOTIMPL;
4050}
4051
4052HRESULT APIENTRY GaDdiDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
4053{
4054 VBOXVDBG_BREAK_DDI();
4055
4056 RT_NOREF(pData);
4057
4058 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4059
4060 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4061 RT_NOREF(pDevice);
4062
4063 /// @todo Not implemented.
4064 AssertFailed();
4065
4066 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4067 return E_NOTIMPL;
4068}
4069
4070HRESULT APIENTRY GaDdiDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
4071{
4072 VBOXVDBG_BREAK_DDI();
4073
4074 RT_NOREF(pData);
4075
4076 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4077
4078 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4079 RT_NOREF(pDevice);
4080
4081 /// @todo Not implemented.
4082 AssertFailed();
4083
4084 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4085 return E_NOTIMPL;
4086}
4087
4088HRESULT APIENTRY GaDdiDecodeExecute(HANDLE hDevice, const D3DDDIARG_DECODEEXECUTE *pData)
4089{
4090 VBOXVDBG_BREAK_DDI();
4091
4092 RT_NOREF(pData);
4093
4094 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4095
4096 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4097 RT_NOREF(pDevice);
4098
4099 /// @todo Not implemented.
4100 AssertFailed();
4101
4102 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4103 return E_NOTIMPL;
4104}
4105
4106HRESULT APIENTRY GaDdiDecodeExtensionExecute(HANDLE hDevice, const D3DDDIARG_DECODEEXTENSIONEXECUTE *pData)
4107{
4108 VBOXVDBG_BREAK_DDI();
4109
4110 RT_NOREF(pData);
4111
4112 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4113
4114 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4115 RT_NOREF(pDevice);
4116
4117 /// @todo Not implemented.
4118 AssertFailed();
4119
4120 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4121 return E_NOTIMPL;
4122}
4123
4124HRESULT APIENTRY GaDdiCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE *pData)
4125{
4126 VBOXVDBG_BREAK_DDI();
4127
4128 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4129
4130 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4131 HRESULT hr;
4132 if (pDevice)
4133 hr = VBoxDxvaCreateVideoProcessDevice(pDevice, pData);
4134 else
4135 hr = E_INVALIDARG;
4136
4137 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4138 return hr;
4139}
4140
4141HRESULT APIENTRY GaDdiDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
4142{
4143 VBOXVDBG_BREAK_DDI();
4144
4145 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4146
4147 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4148 HRESULT hr = VBoxDxvaDestroyVideoProcessDevice(pDevice, hVideoProcessor);
4149
4150 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4151 return hr;
4152}
4153
4154HRESULT APIENTRY GaDdiVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcessor)
4155{
4156 VBOXVDBG_BREAK_DDI();
4157
4158 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4159
4160 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4161 HRESULT hr = VBoxDxvaVideoProcessBeginFrame(pDevice, hVideoProcessor);
4162
4163 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4164 return hr;
4165}
4166
4167HRESULT APIENTRY GaDdiVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
4168{
4169 VBOXVDBG_BREAK_DDI();
4170
4171 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4172
4173 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4174 HRESULT hr = VBoxDxvaVideoProcessEndFrame(pDevice, pData);
4175
4176 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4177 return hr;
4178}
4179
4180HRESULT APIENTRY GaDdiSetVideoProcessRenderTarget(HANDLE hDevice,
4181 const D3DDDIARG_SETVIDEOPROCESSRENDERTARGET *pData)
4182{
4183 VBOXVDBG_BREAK_DDI();
4184
4185 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4186
4187 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4188 HRESULT hr = VBoxDxvaSetVideoProcessRenderTarget(pDevice, pData);
4189
4190 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4191 return hr;
4192}
4193
4194HRESULT APIENTRY GaDdiVideoProcessBlt(HANDLE hDevice, const D3DDDIARG_VIDEOPROCESSBLT *pData)
4195{
4196 VBOXVDBG_BREAK_DDI();
4197
4198 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4199
4200 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4201 HRESULT hr = VBoxDxvaVideoProcessBlt(pDevice, pData);
4202
4203 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4204 return hr;
4205}
4206
4207HRESULT APIENTRY GaDdiCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE *pData)
4208{
4209 VBOXVDBG_BREAK_DDI();
4210
4211 RT_NOREF(pData);
4212
4213 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4214
4215 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4216 RT_NOREF(pDevice);
4217
4218 /// @todo Not implemented.
4219 AssertFailed();
4220
4221 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4222 return E_NOTIMPL;
4223}
4224
4225HRESULT APIENTRY GaDdiDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
4226{
4227 VBOXVDBG_BREAK_DDI();
4228
4229 RT_NOREF(hExtension);
4230
4231 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4232
4233 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4234 RT_NOREF(pDevice);
4235
4236 /// @todo Not implemented.
4237 AssertFailed();
4238
4239 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4240 return E_NOTIMPL;
4241}
4242
4243HRESULT APIENTRY GaDdiExtensionExecute(HANDLE hDevice, const D3DDDIARG_EXTENSIONEXECUTE *pData)
4244{
4245 VBOXVDBG_BREAK_DDI();
4246
4247 RT_NOREF(pData);
4248
4249 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4250
4251 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4252 RT_NOREF(pDevice);
4253
4254 /// @todo Not implemented.
4255 AssertFailed();
4256
4257 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4258 return E_NOTIMPL;
4259}
4260
4261AssertCompile(sizeof(RECT) == sizeof(D3DDDIRECT));
4262AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
4263AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
4264AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
4265AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
4266AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
4267AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
4268AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
4269AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
4270
4271HRESULT APIENTRY GaDdiCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY *pData)
4272{
4273 VBOXVDBG_BREAK_DDI();
4274
4275 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4276
4277 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4278
4279 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
4280 AssertReturn(pData->OverlayInfo.SubResourceIndex < pRc->cAllocations, E_INVALIDARG);
4281
4282 HRESULT hr = S_OK;
4283 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof(VBOXWDDMDISP_OVERLAY));
4284 Assert(pOverlay);
4285 if (pOverlay)
4286 {
4287 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
4288
4289 VBOXWDDM_OVERLAY_INFO OurInfo;
4290 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
4291 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
4292 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
4293 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
4294 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
4295
4296 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
4297
4298 Assert(!pAlloc->LockInfo.cLocks);
4299 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
4300
4301 D3DDDICB_CREATEOVERLAY OverInfo;
4302 OverInfo.VidPnSourceId = pData->VidPnSourceId;
4303 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
4304 Assert(pAlloc->hAllocation);
4305 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
4306 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
4307 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
4308 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
4309 OverInfo.hKernelOverlay = NULL; /* <-- out */
4310
4311 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
4312 Assert(hr == S_OK);
4313 if (hr == S_OK)
4314 {
4315 Assert(OverInfo.hKernelOverlay);
4316 pOverlay->hOverlay = OverInfo.hKernelOverlay;
4317 pOverlay->VidPnSourceId = pData->VidPnSourceId;
4318
4319 Assert(!pAlloc->LockInfo.cLocks);
4320 if (!pAlloc->LockInfo.cLocks)
4321 {
4322 /* we have reported the dirty rect, may clear it if no locks are pending currently */
4323 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
4324 }
4325
4326 pData->hOverlay = pOverlay;
4327 }
4328 else
4329 {
4330 RTMemFree(pOverlay);
4331 }
4332 }
4333 else
4334 hr = E_OUTOFMEMORY;
4335
4336 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4337 return hr;
4338}
4339
4340HRESULT APIENTRY GaDdiUpdateOverlay(HANDLE hDevice, const D3DDDIARG_UPDATEOVERLAY *pData)
4341{
4342 VBOXVDBG_BREAK_DDI();
4343
4344 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4345
4346 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4347
4348 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
4349 Assert(pRc);
4350 AssertReturn(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex, E_INVALIDARG);
4351
4352 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
4353
4354 HRESULT hr = S_OK;
4355 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
4356
4357 VBOXWDDM_OVERLAY_INFO OurInfo;
4358 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
4359 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
4360 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
4361 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
4362 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
4363 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
4364
4365 Assert(!pAlloc->LockInfo.cLocks);
4366 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
4367
4368 D3DDDICB_UPDATEOVERLAY OverInfo;
4369 OverInfo.hKernelOverlay = pOverlay->hOverlay;
4370 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
4371 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
4372 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
4373 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
4374 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
4375
4376 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
4377 Assert(hr == S_OK);
4378 if (hr == S_OK)
4379 {
4380 Assert(!pAlloc->LockInfo.cLocks);
4381 if (!pAlloc->LockInfo.cLocks)
4382 {
4383 /* we have reported the dirty rect, may clear it if no locks are pending currently */
4384 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
4385 }
4386 }
4387
4388 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4389 return hr;
4390}
4391
4392HRESULT APIENTRY GaDdiFlipOverlay(HANDLE hDevice, const D3DDDIARG_FLIPOVERLAY *pData)
4393{
4394 VBOXVDBG_BREAK_DDI();
4395
4396 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4397
4398 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4399
4400 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
4401 Assert(pRc);
4402 Assert(pRc->cAllocations > pData->SourceIndex);
4403
4404 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
4405
4406 HRESULT hr = S_OK;
4407 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
4408
4409 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
4410 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
4411 Assert(!pAlloc->LockInfo.cLocks);
4412 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
4413
4414 D3DDDICB_FLIPOVERLAY OverInfo;
4415 OverInfo.hKernelOverlay = pOverlay->hOverlay;
4416 OverInfo.hSource = pAlloc->hAllocation;
4417 OverInfo.pPrivateDriverData = &OurInfo;
4418 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
4419
4420 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
4421 Assert(hr == S_OK);
4422 if (hr == S_OK)
4423 {
4424 Assert(!pAlloc->LockInfo.cLocks);
4425 if (!pAlloc->LockInfo.cLocks)
4426 {
4427 /* we have reported the dirty rect, may clear it if no locks are pending currently */
4428 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
4429 }
4430 }
4431
4432 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4433 return hr;
4434}
4435
4436HRESULT APIENTRY GaDdiGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS *pData)
4437{
4438 VBOXVDBG_BREAK_DDI();
4439
4440 RT_NOREF(pData);
4441
4442 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4443
4444 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4445 RT_NOREF(pDevice);
4446
4447 /// @todo Not implemented.
4448 AssertFailed();
4449
4450 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4451 return E_NOTIMPL;
4452}
4453
4454HRESULT APIENTRY GaDdiSetOverlayColorControls(HANDLE hDevice, const D3DDDIARG_SETOVERLAYCOLORCONTROLS *pData)
4455{
4456 VBOXVDBG_BREAK_DDI();
4457
4458 RT_NOREF(pData);
4459
4460 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4461
4462 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4463 RT_NOREF(pDevice);
4464
4465 /// @todo Not implemented.
4466 AssertFailed();
4467
4468 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4469 return E_NOTIMPL;
4470}
4471
4472HRESULT APIENTRY GaDdiDestroyOverlay(HANDLE hDevice, const D3DDDIARG_DESTROYOVERLAY *pData)
4473{
4474 VBOXVDBG_BREAK_DDI();
4475
4476 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4477
4478 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4479
4480 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
4481
4482 D3DDDICB_DESTROYOVERLAY OverInfo;
4483 OverInfo.hKernelOverlay = pOverlay->hOverlay;
4484
4485 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
4486 Assert(hr == S_OK);
4487 if (hr == S_OK)
4488 {
4489 RTMemFree(pOverlay);
4490 }
4491
4492 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4493 return hr;
4494}
4495
4496HRESULT APIENTRY GaDdiQueryResourceResidency(HANDLE hDevice, const D3DDDIARG_QUERYRESOURCERESIDENCY *pData)
4497{
4498 VBOXVDBG_BREAK_DDI();
4499
4500 RT_NOREF(pData);
4501
4502 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4503
4504 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4505 RT_NOREF(pDevice);
4506
4507 HRESULT hr = S_OK;
4508 /** @todo check residency for the "real" allocations */
4509
4510 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4511 return hr;
4512}
4513
4514HRESULT APIENTRY GaDdiGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE *pData)
4515{
4516 VBOXVDBG_BREAK_DDI();
4517
4518 RT_NOREF(pData);
4519
4520 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4521
4522 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4523 RT_NOREF(pDevice);
4524
4525 /// @todo Not implemented.
4526 AssertFailed();
4527
4528 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4529 return E_NOTIMPL;
4530}
4531
4532HRESULT APIENTRY GaDdiCaptureToSysMem(HANDLE hDevice, const D3DDDIARG_CAPTURETOSYSMEM *pData)
4533{
4534 VBOXVDBG_BREAK_DDI();
4535
4536 RT_NOREF(pData);
4537
4538 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4539
4540 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4541 RT_NOREF(pDevice);
4542
4543 /// @todo Not implemented.
4544 AssertFailed();
4545
4546 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4547 return E_NOTIMPL;
4548}
4549
4550HRESULT APIENTRY GaDdiDrawRectPatch(HANDLE hDevice, const D3DDDIARG_DRAWRECTPATCH *pData,
4551 const D3DDDIRECTPATCH_INFO *pInfo, const FLOAT *pPatch)
4552{
4553 VBOXVDBG_BREAK_DDI();
4554
4555 RT_NOREF3(pData, pInfo, pPatch);
4556
4557 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4558
4559 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4560 RT_NOREF(pDevice);
4561
4562 /// @todo Not implemented.
4563 AssertFailed();
4564
4565 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4566 return E_NOTIMPL;
4567}
4568
4569HRESULT APIENTRY GaDdiDrawTriPatch(HANDLE hDevice, const D3DDDIARG_DRAWTRIPATCH *pData,
4570 const D3DDDITRIPATCH_INFO *pInfo, const FLOAT *pPatch)
4571{
4572 VBOXVDBG_BREAK_DDI();
4573
4574 RT_NOREF3(pData, pInfo, pPatch);
4575
4576 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4577
4578 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4579 RT_NOREF(pDevice);
4580
4581 /// @todo Not implemented.
4582 AssertFailed();
4583
4584 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4585 return E_NOTIMPL;
4586}
4587
4588HRESULT APIENTRY GaDdiDestroyDevice(HANDLE hDevice)
4589{
4590 VBOXVDBG_BREAK_DDI();
4591
4592 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4593
4594 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4595 AssertReturn(pDevice->pAdapter->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA, E_FAIL);
4596
4597 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
4598 if (VBOXDISPMODE_IS_3D(pAdapter))
4599 {
4600 if (pDevice->pDevice9If)
4601 {
4602 pDevice->pDevice9If->Release();
4603 pDevice->pDevice9If = NULL;
4604 }
4605 }
4606
4607 RTMemFree(pDevice);
4608
4609 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4610 return S_OK;
4611}
4612
4613HRESULT APIENTRY GaDdiDXVAHDCreateVideoProcessor(HANDLE hDevice,
4614 D3DDDIARG_DXVAHD_CREATEVIDEOPROCESSOR *pData)
4615{
4616 VBOXVDBG_BREAK_DDI();
4617
4618 RT_NOREF(pData);
4619
4620 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4621
4622 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4623 RT_NOREF(pDevice);
4624
4625 /// @todo Not implemented.
4626 AssertFailed();
4627
4628 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4629 return E_NOTIMPL;
4630}
4631
4632HRESULT APIENTRY GaDdiDXVAHDSetVideoProcessBltState(HANDLE hDevice,
4633 CONST D3DDDIARG_DXVAHD_SETVIDEOPROCESSBLTSTATE *pData)
4634{
4635 VBOXVDBG_BREAK_DDI();
4636
4637 RT_NOREF(pData);
4638
4639 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4640
4641 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4642 RT_NOREF(pDevice);
4643
4644 /// @todo Not implemented.
4645 AssertFailed();
4646
4647 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4648 return E_NOTIMPL;
4649}
4650
4651HRESULT APIENTRY GaDdiDXVAHDGetVideoProcessBltStatePrivate(HANDLE hDevice,
4652 D3DDDIARG_DXVAHD_GETVIDEOPROCESSBLTSTATEPRIVATE *pData)
4653{
4654 VBOXVDBG_BREAK_DDI();
4655
4656 RT_NOREF(pData);
4657
4658 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4659
4660 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4661 RT_NOREF(pDevice);
4662
4663 /// @todo Not implemented.
4664 AssertFailed();
4665
4666 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4667 return E_NOTIMPL;
4668}
4669
4670HRESULT APIENTRY GaDdiDXVAHDSetVideoProcessStreamState(HANDLE hDevice,
4671 CONST D3DDDIARG_DXVAHD_SETVIDEOPROCESSSTREAMSTATE *pData)
4672{
4673 VBOXVDBG_BREAK_DDI();
4674
4675 RT_NOREF(pData);
4676
4677 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4678
4679 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4680 RT_NOREF(pDevice);
4681
4682 /// @todo Not implemented.
4683 AssertFailed();
4684
4685 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4686 return E_NOTIMPL;
4687}
4688
4689HRESULT APIENTRY GaDdiDXVAHDGetVideoProcessStreamStatePrivate(HANDLE hDevice,
4690 D3DDDIARG_DXVAHD_GETVIDEOPROCESSSTREAMSTATEPRIVATE *pData)
4691{
4692 VBOXVDBG_BREAK_DDI();
4693
4694 RT_NOREF(pData);
4695
4696 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4697
4698 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4699 RT_NOREF(pDevice);
4700
4701 /// @todo Not implemented.
4702 AssertFailed();
4703
4704 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4705 return E_NOTIMPL;
4706}
4707
4708HRESULT APIENTRY GaDdiDXVAHDVideoProcessBltHD(HANDLE hDevice,
4709 CONST D3DDDIARG_DXVAHD_VIDEOPROCESSBLTHD *pData)
4710{
4711 VBOXVDBG_BREAK_DDI();
4712
4713 RT_NOREF(pData);
4714
4715 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4716
4717 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4718 RT_NOREF(pDevice);
4719
4720 /// @todo Not implemented.
4721 AssertFailed();
4722
4723 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4724 return E_NOTIMPL;
4725}
4726
4727HRESULT APIENTRY GaDdiDXVAHDDestroyVideoProcessor(HANDLE hDevice,
4728 HANDLE hProcessor)
4729{
4730 VBOXVDBG_BREAK_DDI();
4731
4732 RT_NOREF(hProcessor);
4733
4734 vboxVDbgPrintF(("<== " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4735
4736 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4737 RT_NOREF(pDevice);
4738
4739 /// @todo Not implemented.
4740 AssertFailed();
4741
4742 vboxVDbgPrintF(("==> " __FUNCTION__ ", hDevice(0x%p)\n", hDevice));
4743 return E_NOTIMPL;
4744}
4745
4746HRESULT APIENTRY GaDdiAdapterCreateDevice(HANDLE hAdapter, D3DDDIARG_CREATEDEVICE *pCreateData)
4747{
4748 VBOXVDBG_BREAK_DDI();
4749
4750 HRESULT hr = S_OK;
4751
4752 vboxVDbgPrint(("==> " __FUNCTION__ ", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
4753
4754 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
4755 AssertReturn(pAdapter->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA, E_INVALIDARG);
4756
4757 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_UOFFSETOF_DYN(VBOXWDDMDISP_DEVICE,
4758 apRTs[pAdapter->D3D.cMaxSimRTs]));
4759 if (pDevice)
4760 {
4761 /*
4762 * Initialize our device object.
4763 */
4764 pDevice->cRTs = pAdapter->D3D.cMaxSimRTs;
4765 pDevice->pfnCreateDirect3DDevice = GaD3DIfDeviceCreate;
4766 pDevice->pfnCreateSharedPrimary = GaD3DIfCreateSharedPrimary;
4767 pDevice->hDevice = pCreateData->hDevice;
4768 pDevice->pAdapter = pAdapter;
4769 pDevice->u32IfVersion = pCreateData->Interface;
4770 pDevice->uRtVersion = pCreateData->Version;
4771 pDevice->RtCallbacks = *pCreateData->pCallbacks;
4772 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
4773 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
4774 pDevice->fFlags = pCreateData->Flags;
4775
4776 /* Set Viewport to some default values */
4777 pDevice->ViewPort.X = 0;
4778 pDevice->ViewPort.Y = 0;
4779 pDevice->ViewPort.Width = 1;
4780 pDevice->ViewPort.Height = 1;
4781 pDevice->ViewPort.MinZ = 0.;
4782 pDevice->ViewPort.MaxZ = 1.;
4783 pDevice->fViewPort = false;
4784 pDevice->fScissorRect = false;
4785
4786 /*
4787 * Set data for the DX runtime.
4788 */
4789 pCreateData->hDevice = pDevice;
4790
4791 pCreateData->pDeviceFuncs->pfnSetRenderState = GaDdiSetRenderState;
4792 pCreateData->pDeviceFuncs->pfnUpdateWInfo = GaDdiUpdateWInfo;
4793 pCreateData->pDeviceFuncs->pfnValidateDevice = GaDdiValidateDevice;
4794 pCreateData->pDeviceFuncs->pfnSetTextureStageState = GaDdiSetTextureStageState;
4795 pCreateData->pDeviceFuncs->pfnSetTexture = GaDdiSetTexture;
4796 pCreateData->pDeviceFuncs->pfnSetPixelShader = GaDdiSetPixelShader;
4797 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = GaDdiSetPixelShaderConst;
4798 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = GaDdiSetStreamSourceUm;
4799 pCreateData->pDeviceFuncs->pfnSetIndices = GaDdiSetIndices;
4800 pCreateData->pDeviceFuncs->pfnSetIndicesUm = GaDdiSetIndicesUm;
4801 pCreateData->pDeviceFuncs->pfnDrawPrimitive = GaDdiDrawPrimitive;
4802 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = GaDdiDrawIndexedPrimitive;
4803 pCreateData->pDeviceFuncs->pfnDrawRectPatch = GaDdiDrawRectPatch;
4804 pCreateData->pDeviceFuncs->pfnDrawTriPatch = GaDdiDrawTriPatch;
4805 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = GaDdiDrawPrimitive2;
4806 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = GaDdiDrawIndexedPrimitive2;
4807 pCreateData->pDeviceFuncs->pfnVolBlt = GaDdiVolBlt;
4808 pCreateData->pDeviceFuncs->pfnBufBlt = GaDdiBufBlt;
4809 pCreateData->pDeviceFuncs->pfnTexBlt = GaDdiTexBlt;
4810 pCreateData->pDeviceFuncs->pfnStateSet = GaDdiStateSet;
4811 pCreateData->pDeviceFuncs->pfnSetPriority = GaDdiSetPriority;
4812 pCreateData->pDeviceFuncs->pfnClear = GaDdiClear;
4813 pCreateData->pDeviceFuncs->pfnUpdatePalette = GaDdiUpdatePalette;
4814 pCreateData->pDeviceFuncs->pfnSetPalette = GaDdiSetPalette;
4815 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = GaDdiSetVertexShaderConst;
4816 pCreateData->pDeviceFuncs->pfnMultiplyTransform = GaDdiMultiplyTransform;
4817 pCreateData->pDeviceFuncs->pfnSetTransform = GaDdiSetTransform;
4818 pCreateData->pDeviceFuncs->pfnSetViewport = GaDdiSetViewport;
4819 pCreateData->pDeviceFuncs->pfnSetZRange = GaDdiSetZRange;
4820 pCreateData->pDeviceFuncs->pfnSetMaterial = GaDdiSetMaterial;
4821 pCreateData->pDeviceFuncs->pfnSetLight = GaDdiSetLight;
4822 pCreateData->pDeviceFuncs->pfnCreateLight = GaDdiCreateLight;
4823 pCreateData->pDeviceFuncs->pfnDestroyLight = GaDdiDestroyLight;
4824 pCreateData->pDeviceFuncs->pfnSetClipPlane = GaDdiSetClipPlane;
4825 pCreateData->pDeviceFuncs->pfnGetInfo = GaDdiGetInfo;
4826 pCreateData->pDeviceFuncs->pfnLock = GaDdiLock;
4827 pCreateData->pDeviceFuncs->pfnUnlock = GaDdiUnlock;
4828 pCreateData->pDeviceFuncs->pfnCreateResource = GaDdiCreateResource;
4829 pCreateData->pDeviceFuncs->pfnDestroyResource = GaDdiDestroyResource;
4830 pCreateData->pDeviceFuncs->pfnSetDisplayMode = GaDdiSetDisplayMode;
4831 pCreateData->pDeviceFuncs->pfnPresent = GaDdiPresent;
4832 pCreateData->pDeviceFuncs->pfnFlush = GaDdiFlush;
4833 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = GaDdiCreateVertexShaderFunc;
4834 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = GaDdiDeleteVertexShaderFunc;
4835 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = GaDdiSetVertexShaderFunc;
4836 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = GaDdiCreateVertexShaderDecl;
4837 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = GaDdiDeleteVertexShaderDecl;
4838 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = GaDdiSetVertexShaderDecl;
4839 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = GaDdiSetVertexShaderConstI;
4840 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = GaDdiSetVertexShaderConstB;
4841 pCreateData->pDeviceFuncs->pfnSetScissorRect = GaDdiSetScissorRect;
4842 pCreateData->pDeviceFuncs->pfnSetStreamSource = GaDdiSetStreamSource;
4843 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = GaDdiSetStreamSourceFreq;
4844 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = GaDdiSetConvolutionKernelMono;
4845 pCreateData->pDeviceFuncs->pfnComposeRects = GaDdiComposeRects;
4846 pCreateData->pDeviceFuncs->pfnBlt = GaDdiBlt;
4847 pCreateData->pDeviceFuncs->pfnColorFill = GaDdiColorFill;
4848 pCreateData->pDeviceFuncs->pfnDepthFill = GaDdiDepthFill;
4849 pCreateData->pDeviceFuncs->pfnCreateQuery = GaDdiCreateQuery;
4850 pCreateData->pDeviceFuncs->pfnDestroyQuery = GaDdiDestroyQuery;
4851 pCreateData->pDeviceFuncs->pfnIssueQuery = GaDdiIssueQuery;
4852 pCreateData->pDeviceFuncs->pfnGetQueryData = GaDdiGetQueryData;
4853 pCreateData->pDeviceFuncs->pfnSetRenderTarget = GaDdiSetRenderTarget;
4854 pCreateData->pDeviceFuncs->pfnSetDepthStencil = GaDdiSetDepthStencil;
4855 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = GaDdiGenerateMipSubLevels;
4856 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = GaDdiSetPixelShaderConstI;
4857 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = GaDdiSetPixelShaderConstB;
4858 pCreateData->pDeviceFuncs->pfnCreatePixelShader = GaDdiCreatePixelShader;
4859 pCreateData->pDeviceFuncs->pfnDeletePixelShader = GaDdiDeletePixelShader;
4860 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = GaDdiCreateDecodeDevice;
4861 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = GaDdiDestroyDecodeDevice;
4862 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = GaDdiSetDecodeRenderTarget;
4863 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = GaDdiDecodeBeginFrame;
4864 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = GaDdiDecodeEndFrame;
4865 pCreateData->pDeviceFuncs->pfnDecodeExecute = GaDdiDecodeExecute;
4866 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = GaDdiDecodeExtensionExecute;
4867 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = GaDdiCreateVideoProcessDevice;
4868 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = GaDdiDestroyVideoProcessDevice;
4869 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = GaDdiVideoProcessBeginFrame;
4870 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = GaDdiVideoProcessEndFrame;
4871 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = GaDdiSetVideoProcessRenderTarget;
4872 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = GaDdiVideoProcessBlt;
4873 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = GaDdiCreateExtensionDevice;
4874 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = GaDdiDestroyExtensionDevice;
4875 pCreateData->pDeviceFuncs->pfnExtensionExecute = GaDdiExtensionExecute;
4876 pCreateData->pDeviceFuncs->pfnCreateOverlay = GaDdiCreateOverlay;
4877 pCreateData->pDeviceFuncs->pfnUpdateOverlay = GaDdiUpdateOverlay;
4878 pCreateData->pDeviceFuncs->pfnFlipOverlay = GaDdiFlipOverlay;
4879 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = GaDdiGetOverlayColorControls;
4880 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = GaDdiSetOverlayColorControls;
4881 pCreateData->pDeviceFuncs->pfnDestroyOverlay = GaDdiDestroyOverlay;
4882 pCreateData->pDeviceFuncs->pfnDestroyDevice = GaDdiDestroyDevice;
4883 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = GaDdiQueryResourceResidency;
4884 pCreateData->pDeviceFuncs->pfnOpenResource = GaDdiOpenResource;
4885 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = GaDdiGetCaptureAllocationHandle;
4886 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = GaDdiCaptureToSysMem;
4887 // pCreateData->pDeviceFuncs->pfnLockAsync = NULL; /* Optional. */
4888 // pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; /* Optional. */
4889 // pCreateData->pDeviceFuncs->pfnRename = NULL; /* Optional. */
4890
4891 // pCreateData->pDeviceFuncs->pfnCreateVideoProcessor = GaDdiDXVAHDCreateVideoProcessor;
4892 // pCreateData->pDeviceFuncs->pfnSetVideoProcessBltState = GaDdiDXVAHDSetVideoProcessBltState;
4893 // pCreateData->pDeviceFuncs->pfnGetVideoProcessBltStatePrivate = GaDdiDXVAHDGetVideoProcessBltStatePrivate;
4894 // pCreateData->pDeviceFuncs->pfnSetVideoProcessStreamState = GaDdiDXVAHDSetVideoProcessStreamState;
4895 // pCreateData->pDeviceFuncs->pfnGetVideoProcessStreamStatePrivate = GaDdiDXVAHDGetVideoProcessStreamStatePrivate;
4896 // pCreateData->pDeviceFuncs->pfnVideoProcessBltHD = GaDdiDXVAHDVideoProcessBltHD;
4897 // pCreateData->pDeviceFuncs->pfnDestroyVideoProcessor = GaDdiDXVAHDDestroyVideoProcessor;
4898 }
4899 else
4900 {
4901 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
4902 hr = E_OUTOFMEMORY;
4903 }
4904
4905#ifdef VBOX_WITH_MESA3D_D3DTEST
4906 /* Built-in gallium backend test for early development stages.
4907 * Use it only with kernel debugger attached to the VM.
4908 */
4909 extern void GaDrvTest(IGalliumStack *pGalliumStack, PVBOXWDDMDISP_DEVICE pDevice);
4910 if (SUCCEEDED(hr))
4911 GaDrvTest(pAdapter->D3D.pGalliumStack, pDevice);
4912#endif
4913
4914 vboxVDbgPrint(("<== " __FUNCTION__ ", hAdapter(0x%p)\n", hAdapter));
4915 return hr;
4916}
4917
4918HRESULT APIENTRY GaDdiAdapterCloseAdapter(IN HANDLE hAdapter)
4919{
4920 VBOXVDBG_BREAK_DDI();
4921
4922 vboxVDbgPrint(("==> " __FUNCTION__ ", hAdapter(0x%p)\n", hAdapter));
4923
4924 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
4925 if (VBOXDISPMODE_IS_3D(pAdapter))
4926 {
4927 VBoxDispD3DGlobalClose(&pAdapter->D3D, &pAdapter->Formats);
4928 }
4929#ifdef VBOX_WITH_VIDEOHWACCEL
4930 else
4931 {
4932 VBoxDispD3DGlobal2DFormatsTerm(pAdapter);
4933 }
4934#endif
4935
4936 RTMemFree(pAdapter);
4937
4938 vboxVDbgPrint(("<== " __FUNCTION__ ", hAdapter(0x%p)\n", hAdapter));
4939
4940 return S_OK;
4941}
4942
4943static D3DDDIQUERYTYPE const gVBoxQueryTypes[] = {
4944 D3DDDIQUERYTYPE_EVENT,
4945 D3DDDIQUERYTYPE_OCCLUSION
4946};
4947
4948#ifdef VBOX_WITH_VIDEOHWACCEL
4949static bool vboxVhwaHasCKeying(PVBOXWDDMDISP_ADAPTER pAdapter)
4950{
4951 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
4952 {
4953 VBOXVHWA_INFO* pSettings = &pAdapter->aHeads[i].Vhwa.Settings;
4954 if ( (pSettings->fFlags & VBOXVHWA_F_ENABLED)
4955 && ( (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
4956 || (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)))
4957 return true;
4958 }
4959 return false;
4960}
4961#endif
4962
4963HRESULT APIENTRY GaDdiAdapterGetCaps(HANDLE hAdapter, const D3DDDIARG_GETCAPS *pData)
4964{
4965 VBOXVDBG_BREAK_DDI();
4966
4967 vboxVDbgPrint(("==> " __FUNCTION__ ", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
4968
4969 HRESULT hr = S_OK;
4970 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
4971
4972 switch (pData->Type)
4973 {
4974 case D3DDDICAPS_DDRAW:
4975 {
4976 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
4977 Assert(pData->DataSize == sizeof(DDRAW_CAPS));
4978 if (pData->DataSize >= sizeof(DDRAW_CAPS))
4979 {
4980 memset(pData->pData, 0, sizeof(DDRAW_CAPS));
4981#ifdef VBOX_WITH_VIDEOHWACCEL
4982 if (!VBOXDISPMODE_IS_3D(pAdapter))
4983 {
4984 if (vboxVhwaHasCKeying(pAdapter))
4985 {
4986 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
4987 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
4988// pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
4989 }
4990 }
4991 else
4992 {
4993 WARN(("D3DDDICAPS_DDRAW query for D3D mode!"));
4994 }
4995#endif
4996 }
4997 else
4998 hr = E_INVALIDARG;
4999 break;
5000 }
5001
5002 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
5003 {
5004 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
5005 Assert(pData->DataSize == sizeof(DDRAW_MODE_SPECIFIC_CAPS));
5006 if (pData->DataSize >= sizeof(DDRAW_MODE_SPECIFIC_CAPS))
5007 {
5008 DDRAW_MODE_SPECIFIC_CAPS *pCaps = (DDRAW_MODE_SPECIFIC_CAPS *)pData->pData;
5009 /* Do not overwrite the first "Head" field, zero starting with the one following "Head", i.e. Caps. */
5010 memset(&pCaps->Caps, 0, sizeof(DDRAW_MODE_SPECIFIC_CAPS) - RT_UOFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
5011#ifdef VBOX_WITH_VIDEOHWACCEL
5012 if (!VBOXDISPMODE_IS_3D(pAdapter))
5013 {
5014 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
5015 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
5016 {
5017 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
5018
5019 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
5020 {
5021 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
5022 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
5023 ;
5024 }
5025
5026 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
5027 {
5028 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
5029 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
5030 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
5031 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
5032 ;
5033 }
5034
5035 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
5036 | MODE_FXCAPS_OVERLAYSHRINKY
5037 | MODE_FXCAPS_OVERLAYSTRETCHX
5038 | MODE_FXCAPS_OVERLAYSTRETCHY;
5039
5040
5041 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
5042 pCaps->MinOverlayStretch = 1;
5043 pCaps->MaxOverlayStretch = 32000;
5044 }
5045 }
5046 else
5047 {
5048 WARN(("D3DDDICAPS_DDRAW_MODE_SPECIFIC query for D3D mode!"));
5049 }
5050#endif
5051 }
5052 else
5053 hr = E_INVALIDARG;
5054 break;
5055 }
5056
5057 case D3DDDICAPS_GETFORMATCOUNT:
5058 *((uint32_t*)pData->pData) = pAdapter->Formats.cFormatOps;
5059 break;
5060
5061 case D3DDDICAPS_GETFORMATDATA:
5062 Assert(pData->DataSize == pAdapter->Formats.cFormatOps * sizeof(FORMATOP));
5063 memcpy(pData->pData, pAdapter->Formats.paFormatOps, pAdapter->Formats.cFormatOps * sizeof(FORMATOP));
5064 break;
5065
5066 case D3DDDICAPS_GETD3DQUERYCOUNT:
5067 *((uint32_t*)pData->pData) = RT_ELEMENTS(gVBoxQueryTypes);
5068 break;
5069
5070 case D3DDDICAPS_GETD3DQUERYDATA:
5071 Assert(pData->DataSize == RT_ELEMENTS(gVBoxQueryTypes) * sizeof(D3DDDIQUERYTYPE));
5072 memcpy(pData->pData, gVBoxQueryTypes, RT_ELEMENTS(gVBoxQueryTypes) * sizeof(D3DDDIQUERYTYPE));
5073 break;
5074
5075 case D3DDDICAPS_GETD3D3CAPS:
5076 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
5077 Assert(pData->DataSize == sizeof(D3DHAL_GLOBALDRIVERDATA));
5078 if (pData->DataSize >= sizeof(D3DHAL_GLOBALDRIVERDATA))
5079 {
5080 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
5081 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
5082 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
5083 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
5084 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
5085 | D3DDD_DEVCAPS
5086 | D3DDD_DEVICERENDERBITDEPTH;
5087
5088 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
5089 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
5090// | D3DDEVCAPS_DRAWPRIMTLVERTEX
5091 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
5092 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
5093// | D3DDEVCAPS_FLOATTLVERTEX
5094 | D3DDEVCAPS_HWRASTERIZATION
5095// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
5096// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
5097// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
5098 ;
5099 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
5100 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
5101 pCaps->hwCaps.bClipping = FALSE;
5102 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
5103 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
5104 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
5105 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
5106 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
5107 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
5108 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
5109 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
5110 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
5111 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
5112 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
5113 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
5114 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
5115 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
5116 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
5117 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
5118 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
5119 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
5120
5121 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
5122 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
5123 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
5124 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
5125 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
5126 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
5127 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
5128 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
5129 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
5130 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
5131 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
5132 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
5133 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
5134 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
5135 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
5136 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
5137 pCaps->hwCaps.dwMaxBufferSize = 0;
5138 pCaps->hwCaps.dwMaxVertexCount = 0;
5139
5140
5141 pCaps->dwNumVertices = 0;
5142 pCaps->dwNumClipVertices = 0;
5143 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
5144 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
5145 }
5146 else
5147 hr = E_INVALIDARG;
5148 break;
5149
5150 case D3DDDICAPS_GETD3D7CAPS:
5151 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
5152 Assert(pData->DataSize == sizeof(D3DHAL_D3DEXTENDEDCAPS));
5153 if (pData->DataSize >= sizeof(D3DHAL_D3DEXTENDEDCAPS))
5154 {
5155 memset(pData->pData, 0, sizeof(D3DHAL_D3DEXTENDEDCAPS));
5156 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS *)pData->pData;
5157 pCaps->dwSize = sizeof(D3DHAL_D3DEXTENDEDCAPS);
5158 }
5159 else
5160 hr = E_INVALIDARG;
5161 break;
5162
5163 case D3DDDICAPS_GETD3D9CAPS:
5164 {
5165 Assert(pData->DataSize == sizeof(D3DCAPS9));
5166 if (pData->DataSize >= sizeof(D3DCAPS9))
5167 {
5168 if (VBOXDISPMODE_IS_3D(pAdapter))
5169 {
5170 memcpy(pData->pData, &pAdapter->D3D.Caps, sizeof(D3DCAPS9));
5171 }
5172 else
5173 {
5174 memset(pData->pData, 0, sizeof (D3DCAPS9));
5175 }
5176 }
5177 else
5178 hr = E_INVALIDARG;
5179 break;
5180 }
5181
5182 case D3DDDICAPS_GETD3D8CAPS:
5183 {
5184 Assert(pData->DataSize == RT_UOFFSETOF(D3DCAPS9, DevCaps2));
5185 if (pData->DataSize == RT_UOFFSETOF(D3DCAPS9, DevCaps2))
5186 {
5187 if (VBOXDISPMODE_IS_3D(pAdapter))
5188 {
5189 memcpy(pData->pData, &pAdapter->D3D.Caps, RT_UOFFSETOF(D3DCAPS9, DevCaps2));
5190 }
5191 else
5192 {
5193 AssertFailed();
5194 memset(pData->pData, 0, RT_UOFFSETOF(D3DCAPS9, DevCaps2));
5195 }
5196 }
5197 else
5198 hr = E_INVALIDARG;
5199 break;
5200 }
5201
5202 case D3DDDICAPS_GETGAMMARAMPCAPS:
5203 *((uint32_t*)pData->pData) = 0;
5204 break;
5205
5206 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
5207 {
5208 if (pData->DataSize >= sizeof(UINT))
5209 {
5210 if (pAdapter->AdapterInfo.u32AdapterCaps & VBOXWDDM_QAI_CAP_DXVA)
5211 hr = VBoxDxvaGetDeviceGuidCount((UINT *)pData->pData);
5212 else
5213 *(UINT *)pData->pData = 0;
5214 }
5215 else
5216 hr = E_INVALIDARG;
5217 break;
5218 }
5219
5220 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
5221 {
5222 hr = VBoxDxvaGetDeviceGuids((GUID *)pData->pData, pData->DataSize);
5223 break;
5224 }
5225
5226 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
5227 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
5228 {
5229 if (pData->DataSize >= sizeof(UINT))
5230 if (pAdapter->AdapterInfo.u32AdapterCaps & VBOXWDDM_QAI_CAP_DXVA)
5231 hr = VBoxDxvaGetOutputFormatCount((UINT *)pData->pData, (DXVADDI_VIDEOPROCESSORINPUT *)pData->pInfo,
5232 pData->Type == D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT);
5233 else
5234 *(UINT *)pData->pData = 0;
5235 else
5236 hr = E_INVALIDARG;
5237 break;
5238 }
5239
5240 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
5241 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
5242 {
5243 hr = VBoxDxvaGetOutputFormats((D3DDDIFORMAT *)pData->pData, pData->DataSize,
5244 (DXVADDI_VIDEOPROCESSORINPUT *)pData->pInfo,
5245 pData->Type == D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS);
5246 break;
5247 }
5248
5249 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
5250 {
5251 if (pData->DataSize >= sizeof(DXVADDI_VIDEOPROCESSORCAPS))
5252 hr = VBoxDxvaGetCaps((DXVADDI_VIDEOPROCESSORCAPS *)pData->pData,
5253 (DXVADDI_VIDEOPROCESSORINPUT *)pData->pInfo);
5254 else
5255 hr = E_INVALIDARG;
5256 break;
5257 }
5258
5259 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
5260 case D3DDDICAPS_GETDECODEGUIDCOUNT:
5261 case D3DDDICAPS_GETCONTENTPROTECTIONCAPS:
5262 if (pData->pData && pData->DataSize)
5263 memset(pData->pData, 0, pData->DataSize);
5264 break;
5265
5266 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
5267 case D3DDDICAPS_GETD3D5CAPS:
5268 case D3DDDICAPS_GETD3D6CAPS:
5269 case D3DDDICAPS_GETDECODEGUIDS:
5270 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
5271 case D3DDDICAPS_GETDECODERTFORMATS:
5272 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
5273 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
5274 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
5275 case D3DDDICAPS_GETDECODECONFIGURATIONS:
5276 case D3DDDICAPS_GETPROCAMPRANGE:
5277 case D3DDDICAPS_FILTERPROPERTYRANGE:
5278 case D3DDDICAPS_GETEXTENSIONGUIDS:
5279 case D3DDDICAPS_GETEXTENSIONCAPS:
5280 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
5281 AssertFailed();
5282 if (pData->pData && pData->DataSize)
5283 memset(pData->pData, 0, pData->DataSize);
5284 break;
5285
5286 default:
5287 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
5288 AssertFailed();
5289 }
5290
5291 vboxVDbgPrint(("<== " __FUNCTION__ ", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
5292 return S_OK;
5293}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use