VirtualBox

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

Last change on this file was 98907, checked in by vboxsync, 14 months ago

WDDM: make sure that textures are always updated in D3D9 driver

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

© 2023 Oracle
ContactPrivacy policyTerms of Use