VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp@ 49244

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

wddm: fix 3D rendering to primary

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.8 KB
Line 
1/* $Id: VBoxD3DIf.cpp 49244 2013-10-22 20:08:34Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18#include "VBoxDispD3DCmn.h"
19
20/* DDI2D3D */
21
22D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format)
23{
24 /* @todo: check they are all equal */
25 return (D3DFORMAT)format;
26}
27
28D3DMULTISAMPLE_TYPE vboxDDI2D3DMultiSampleType(D3DDDIMULTISAMPLE_TYPE enmType)
29{
30 /* @todo: check they are all equal */
31 return (D3DMULTISAMPLE_TYPE)enmType;
32}
33
34D3DPOOL vboxDDI2D3DPool(D3DDDI_POOL enmPool)
35{
36 /* @todo: check they are all equal */
37 switch (enmPool)
38 {
39 case D3DDDIPOOL_SYSTEMMEM:
40 return D3DPOOL_SYSTEMMEM;
41 case D3DDDIPOOL_VIDEOMEMORY:
42 case D3DDDIPOOL_LOCALVIDMEM:
43 case D3DDDIPOOL_NONLOCALVIDMEM:
44 /* @todo: what would be proper here? */
45 return D3DPOOL_DEFAULT;
46 default:
47 Assert(0);
48 }
49 return D3DPOOL_DEFAULT;
50}
51
52D3DRENDERSTATETYPE vboxDDI2D3DRenderStateType(D3DDDIRENDERSTATETYPE enmType)
53{
54 /* @todo: @fixme: not entirely correct, need to check */
55 return (D3DRENDERSTATETYPE)enmType;
56}
57
58VBOXWDDMDISP_TSS_LOOKUP vboxDDI2D3DTestureStageStateType(D3DDDITEXTURESTAGESTATETYPE enmType)
59{
60 static const VBOXWDDMDISP_TSS_LOOKUP lookup[] =
61 {
62 {FALSE, D3DTSS_FORCE_DWORD}, /* 0, D3DDDITSS_TEXTUREMAP */
63 {FALSE, D3DTSS_COLOROP}, /* 1, D3DDDITSS_COLOROP */
64 {FALSE, D3DTSS_COLORARG1}, /* 2, D3DDDITSS_COLORARG1 */
65 {FALSE, D3DTSS_COLORARG2}, /* 3, D3DDDITSS_COLORARG2 */
66 {FALSE, D3DTSS_ALPHAOP}, /* 4, D3DDDITSS_ALPHAOP */
67 {FALSE, D3DTSS_ALPHAARG1}, /* 5, D3DDDITSS_ALPHAARG1 */
68 {FALSE, D3DTSS_ALPHAARG2}, /* 6, D3DDDITSS_ALPHAARG2 */
69 {FALSE, D3DTSS_BUMPENVMAT00}, /* 7, D3DDDITSS_BUMPENVMAT00 */
70 {FALSE, D3DTSS_BUMPENVMAT01}, /* 8, D3DDDITSS_BUMPENVMAT01 */
71 {FALSE, D3DTSS_BUMPENVMAT10}, /* 9, D3DDDITSS_BUMPENVMAT10 */
72 {FALSE, D3DTSS_BUMPENVMAT11}, /* 10, D3DDDITSS_BUMPENVMAT11 */
73 {FALSE, D3DTSS_TEXCOORDINDEX}, /* 11, D3DDDITSS_TEXCOORDINDEX */
74 {FALSE, D3DTSS_FORCE_DWORD}, /* 12, unused */
75 {TRUE, D3DSAMP_ADDRESSU}, /* 13, D3DDDITSS_ADDRESSU */
76 {TRUE, D3DSAMP_ADDRESSV}, /* 14, D3DDDITSS_ADDRESSV */
77 {TRUE, D3DSAMP_BORDERCOLOR}, /* 15, D3DDDITSS_BORDERCOLOR */
78 {TRUE, D3DSAMP_MAGFILTER}, /* 16, D3DDDITSS_MAGFILTER */
79 {TRUE, D3DSAMP_MINFILTER}, /* 17, D3DDDITSS_MINFILTER */
80 {TRUE, D3DSAMP_MIPFILTER}, /* 18, D3DDDITSS_MIPFILTER */
81 {TRUE, D3DSAMP_MIPMAPLODBIAS}, /* 19, D3DDDITSS_MIPMAPLODBIAS */
82 {TRUE, D3DSAMP_MAXMIPLEVEL}, /* 20, D3DDDITSS_MAXMIPLEVEL */
83 {TRUE, D3DSAMP_MAXANISOTROPY}, /* 21, D3DDDITSS_MAXANISOTROPY */
84 {FALSE, D3DTSS_BUMPENVLSCALE}, /* 22, D3DDDITSS_BUMPENVLSCALE */
85 {FALSE, D3DTSS_BUMPENVLOFFSET}, /* 23, D3DDDITSS_BUMPENVLOFFSET */
86 {FALSE, D3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DDDITSS_TEXTURETRANSFORMFLAGS */
87 {TRUE, D3DSAMP_ADDRESSW}, /* 25, D3DDDITSS_ADDRESSW */
88 {FALSE, D3DTSS_COLORARG0}, /* 26, D3DDDITSS_COLORARG0 */
89 {FALSE, D3DTSS_ALPHAARG0}, /* 27, D3DDDITSS_ALPHAARG0 */
90 {FALSE, D3DTSS_RESULTARG}, /* 28, D3DDDITSS_RESULTARG */
91 {TRUE, D3DSAMP_SRGBTEXTURE}, /* 29, D3DDDITSS_SRGBTEXTURE */
92 {TRUE, D3DSAMP_ELEMENTINDEX}, /* 30, D3DDDITSS_ELEMENTINDEX */
93 {TRUE, D3DSAMP_DMAPOFFSET}, /* 31, D3DDDITSS_DMAPOFFSET */
94 {FALSE, D3DTSS_CONSTANT}, /* 32, D3DDDITSS_CONSTANT */
95 {FALSE, D3DTSS_FORCE_DWORD}, /* 33, D3DDDITSS_DISABLETEXTURECOLORKEY */
96 {FALSE, D3DTSS_FORCE_DWORD}, /* 34, D3DDDITSS_TEXTURECOLORKEYVAL */
97 };
98
99 Assert(enmType > 0);
100 Assert(enmType < RT_ELEMENTS(lookup));
101 Assert(lookup[enmType].dType != D3DTSS_FORCE_DWORD);
102
103 return lookup[enmType];
104}
105
106DWORD vboxDDI2D3DUsage(D3DDDI_RESOURCEFLAGS fFlags)
107{
108 DWORD fUsage = 0;
109 if (fFlags.Dynamic)
110 fUsage |= D3DUSAGE_DYNAMIC;
111 if (fFlags.AutogenMipmap)
112 fUsage |= D3DUSAGE_AUTOGENMIPMAP;
113 if (fFlags.DMap)
114 fUsage |= D3DUSAGE_DMAP;
115 if (fFlags.WriteOnly)
116 fUsage |= D3DUSAGE_WRITEONLY;
117 if (fFlags.NPatches)
118 fUsage |= D3DUSAGE_NPATCHES;
119 if (fFlags.Points)
120 fUsage |= D3DUSAGE_POINTS;
121 if (fFlags.RenderTarget)
122 fUsage |= D3DUSAGE_RENDERTARGET;
123 if (fFlags.RtPatches)
124 fUsage |= D3DUSAGE_RTPATCHES;
125 if (fFlags.TextApi)
126 fUsage |= D3DUSAGE_TEXTAPI;
127 if (fFlags.WriteOnly)
128 fUsage |= D3DUSAGE_WRITEONLY;
129 //below are wddm 1.1-specific
130// if (fFlags.RestrictedContent)
131// fUsage |= D3DUSAGE_RESTRICTED_CONTENT;
132// if (fFlags.RestrictSharedAccess)
133// fUsage |= D3DUSAGE_RESTRICT_SHARED_RESOURCE;
134 return fUsage;
135}
136
137DWORD vboxDDI2D3DLockFlags(D3DDDI_LOCKFLAGS fLockFlags)
138{
139 DWORD fFlags = 0;
140 if (fLockFlags.Discard)
141 fFlags |= D3DLOCK_DISCARD;
142 if (fLockFlags.NoOverwrite)
143 fFlags |= D3DLOCK_NOOVERWRITE;
144 if (fLockFlags.ReadOnly)
145 fFlags |= D3DLOCK_READONLY;
146 if (fLockFlags.DoNotWait)
147 fFlags |= D3DLOCK_DONOTWAIT;
148 return fFlags;
149}
150
151D3DTEXTUREFILTERTYPE vboxDDI2D3DBltFlags(D3DDDI_BLTFLAGS fFlags)
152{
153 if (fFlags.Point)
154 {
155 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
156 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 1);
157 return D3DTEXF_POINT;
158 }
159 if (fFlags.Linear)
160 {
161 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
162 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 2);
163 return D3DTEXF_LINEAR;
164 }
165 /* no flags other than [Begin|Continue|End]PresentToDwm are set */
166 Assert((fFlags.Value & (~(0x00000100 | 0x00000200 | 0x00000400))) == 0);
167 return D3DTEXF_NONE;
168}
169
170D3DQUERYTYPE vboxDDI2D3DQueryType(D3DDDIQUERYTYPE enmType)
171{
172 return (D3DQUERYTYPE)enmType;
173}
174
175DWORD vboxDDI2D3DIssueQueryFlags(D3DDDI_ISSUEQUERYFLAGS Flags)
176{
177 DWORD fFlags = 0;
178 if (Flags.Begin)
179 fFlags |= D3DISSUE_BEGIN;
180 if (Flags.End)
181 fFlags |= D3DISSUE_END;
182 return fFlags;
183}
184
185/**/
186
187/* D3DIf API */
188static HRESULT vboxDispD3DIfSurfSynchMem(PVBOXWDDMDISP_RESOURCE pRc)
189{
190 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
191 {
192 return S_OK;
193 }
194
195 for (UINT i = 0; i < pRc->cAllocations; ++i)
196 {
197 D3DLOCKED_RECT Rect;
198 HRESULT hr = VBoxD3DIfLockRect(pRc, i, &Rect, NULL, D3DLOCK_DISCARD);
199 if (FAILED(hr))
200 {
201 WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
202 return hr;
203 }
204
205 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
206 Assert(pAlloc->pvMem);
207
208 VBoxD3DIfLockUnlockMemSynch(pAlloc, &Rect, NULL, true /*bool bToLockInfo*/);
209
210 hr = VBoxD3DIfUnlockRect(pRc, i);
211 Assert(SUCCEEDED(hr));
212 }
213 return S_OK;
214}
215
216void VBoxD3DIfLockUnlockMemSynch(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo)
217{
218 Assert(pAlloc->SurfDesc.pitch);
219 Assert(pAlloc->pvMem);
220
221 if (!pRect)
222 {
223 if (pAlloc->SurfDesc.pitch == pLockInfo->Pitch)
224 {
225 Assert(pAlloc->SurfDesc.cbSize);
226 if (bToLockInfo)
227 memcpy(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.cbSize);
228 else
229 memcpy(pAlloc->pvMem, pLockInfo->pBits, pAlloc->SurfDesc.cbSize);
230 }
231 else
232 {
233 uint8_t *pvSrc, *pvDst;
234 uint32_t srcPitch, dstPitch;
235 if (bToLockInfo)
236 {
237 pvSrc = (uint8_t *)pAlloc->pvMem;
238 pvDst = (uint8_t *)pLockInfo->pBits;
239 srcPitch = pAlloc->SurfDesc.pitch;
240 dstPitch = pLockInfo->Pitch;
241 }
242 else
243 {
244 pvDst = (uint8_t *)pAlloc->pvMem;
245 pvSrc = (uint8_t *)pLockInfo->pBits;
246 dstPitch = pAlloc->SurfDesc.pitch;
247 srcPitch = (uint32_t)pLockInfo->Pitch;
248 }
249
250 uint32_t cRows = vboxWddmCalcNumRows(0, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format);
251 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
252 Assert(pitch);
253 for (UINT j = 0; j < cRows; ++j)
254 {
255 memcpy(pvDst, pvSrc, pitch);
256 pvSrc += srcPitch;
257 pvDst += dstPitch;
258 }
259 }
260 }
261 else
262 {
263 uint8_t *pvSrc, *pvDst;
264 uint32_t srcPitch, dstPitch;
265 uint8_t * pvAllocMemStart = (uint8_t *)pAlloc->pvMem;
266 uint32_t offAllocMemStart = vboxWddmCalcOffXYrd(pRect->left, pRect->top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
267 pvAllocMemStart += offAllocMemStart;
268
269 if (bToLockInfo)
270 {
271 pvSrc = (uint8_t *)pvAllocMemStart;
272 pvDst = (uint8_t *)pLockInfo->pBits;
273 srcPitch = pAlloc->SurfDesc.pitch;
274 dstPitch = pLockInfo->Pitch;
275 }
276 else
277 {
278 pvDst = (uint8_t *)pvAllocMemStart;
279 pvSrc = (uint8_t *)pLockInfo->pBits;
280 dstPitch = pAlloc->SurfDesc.pitch;
281 srcPitch = (uint32_t)pLockInfo->Pitch;
282 }
283
284 if (pRect->right - pRect->left == pAlloc->SurfDesc.width && srcPitch == dstPitch)
285 {
286 uint32_t cbSize = vboxWddmCalcSize(pAlloc->SurfDesc.pitch, pRect->bottom - pRect->top, pAlloc->SurfDesc.format);
287 memcpy(pvDst, pvSrc, cbSize);
288 }
289 else
290 {
291 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
292 uint32_t cbCopyLine = vboxWddmCalcRowSize(pRect->left, pRect->right, pAlloc->SurfDesc.format);
293 Assert(pitch);
294 uint32_t cRows = vboxWddmCalcNumRows(pRect->top, pRect->bottom, pAlloc->SurfDesc.format);
295 for (UINT j = 0; j < cRows; ++j)
296 {
297 memcpy(pvDst, pvSrc, cbCopyLine);
298 pvSrc += srcPitch;
299 pvDst += dstPitch;
300 }
301 }
302 }
303}
304
305HRESULT VBoxD3DIfLockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc,
306 D3DLOCKED_RECT * pLockedRect,
307 CONST RECT *pRect,
308 DWORD fLockFlags)
309{
310 HRESULT hr = E_FAIL;
311 Assert(!pRc->aAllocations[iAlloc].LockInfo.cLocks);
312 Assert(pRc->cAllocations > iAlloc);
313 switch (pRc->aAllocations[0].enmD3DIfType)
314 {
315 case VBOXDISP_D3DIFTYPE_SURFACE:
316 {
317 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
318 Assert(pD3DIfSurf);
319 hr = pD3DIfSurf->LockRect(pLockedRect, pRect, fLockFlags);
320 Assert(hr == S_OK);
321 break;
322 }
323 case VBOXDISP_D3DIFTYPE_TEXTURE:
324 {
325 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
326 Assert(pD3DIfTex);
327 hr = pD3DIfTex->LockRect(iAlloc, pLockedRect, pRect, fLockFlags);
328 Assert(hr == S_OK);
329 break;
330 }
331 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
332 {
333 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
334 Assert(pD3DIfCubeTex);
335 hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, iAlloc),
336 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, iAlloc), pLockedRect, pRect, fLockFlags);
337 Assert(hr == S_OK);
338 break;
339 }
340 case VBOXDISP_D3DIFTYPE_VERTEXBUFFER:
341 {
342 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pRc->aAllocations[iAlloc].pD3DIf;
343 Assert(pD3D9VBuf);
344 hr = pD3D9VBuf->Lock(pRect ? pRect->left : 0/* offset */,
345 pRect ? pRect->right : 0 /* size 2 lock - 0 means all */,
346 &pLockedRect->pBits, fLockFlags);
347 Assert(hr == S_OK);
348 pLockedRect->Pitch = pRc->aAllocations[iAlloc].SurfDesc.pitch;
349 break;
350 }
351 case VBOXDISP_D3DIFTYPE_INDEXBUFFER:
352 {
353 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pRc->aAllocations[iAlloc].pD3DIf;
354 Assert(pD3D9IBuf);
355 hr = pD3D9IBuf->Lock(pRect ? pRect->left : 0/* offset */,
356 pRect ? pRect->right : 0 /* size 2 lock - 0 means all */,
357 &pLockedRect->pBits, fLockFlags);
358 Assert(hr == S_OK);
359 pLockedRect->Pitch = pRc->aAllocations[iAlloc].SurfDesc.pitch;
360 break;
361 }
362 default:
363 WARN(("uknown if type %d", pRc->aAllocations[0].enmD3DIfType));
364 break;
365 }
366 return hr;
367}
368
369HRESULT VBoxD3DIfUnlockRect(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc)
370{
371 HRESULT hr = S_OK;
372 Assert(pRc->cAllocations > iAlloc);
373 switch (pRc->aAllocations[0].enmD3DIfType)
374 {
375 case VBOXDISP_D3DIFTYPE_SURFACE:
376 {
377 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pRc->aAllocations[iAlloc].pD3DIf;
378 Assert(pD3DIfSurf);
379 hr = pD3DIfSurf->UnlockRect();
380 Assert(hr == S_OK);
381 break;
382 }
383 case VBOXDISP_D3DIFTYPE_TEXTURE:
384 {
385 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
386 Assert(pD3DIfTex);
387 hr = pD3DIfTex->UnlockRect(iAlloc);
388 Assert(hr == S_OK);
389 break;
390 }
391 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
392 {
393 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
394 Assert(pD3DIfCubeTex);
395 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, iAlloc),
396 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, iAlloc));
397 Assert(hr == S_OK);
398 break;
399 }
400 case VBOXDISP_D3DIFTYPE_VERTEXBUFFER:
401 {
402 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pRc->aAllocations[iAlloc].pD3DIf;
403 Assert(pD3D9VBuf);
404 hr = pD3D9VBuf->Unlock();
405 Assert(hr == S_OK);
406 break;
407 }
408 case VBOXDISP_D3DIFTYPE_INDEXBUFFER:
409 {
410 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pRc->aAllocations[iAlloc].pD3DIf;
411 Assert(pD3D9IBuf);
412 hr = pD3D9IBuf->Unlock();
413 Assert(hr == S_OK);
414 break;
415 }
416 default:
417 WARN(("uknown if type %d", pRc->aAllocations[0].enmD3DIfType));
418 hr = E_FAIL;
419 break;
420 }
421 return hr;
422}
423
424HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
425{
426 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
427 HRESULT hr = E_FAIL;
428 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
429
430 if (VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags))
431 {
432 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
433 IDirect3DBaseTexture9 *pD3DIfTex;
434 HANDLE hSharedHandle = pAllocation->hSharedHandle;
435 void **pavClientMem = NULL;
436 VBOXDISP_D3DIFTYPE enmD3DIfType = VBOXDISP_D3DIFTYPE_UNDEFINED;
437 hr = S_OK;
438 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
439 {
440 pavClientMem = (void**)RTMemAlloc(sizeof (pavClientMem[0]) * pRc->cAllocations);
441 Assert(pavClientMem);
442 if (pavClientMem)
443 {
444 for (UINT i = 0; i < pRc->cAllocations; ++i)
445 {
446 Assert(pRc->aAllocations[i].pvMem);
447 pavClientMem[i] = pRc->aAllocations[i].pvMem;
448 }
449 }
450 else
451 hr = E_FAIL;
452 }
453
454#ifdef DEBUG
455 if (!pRc->RcDesc.fFlags.CubeMap)
456 {
457 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[0];
458 uint32_t tstW = pAlloc->SurfDesc.width;
459 uint32_t tstH = pAlloc->SurfDesc.height;
460 for (UINT i = 1; i < pRc->cAllocations; ++i)
461 {
462 tstW /= 2;
463 tstH /= 2;
464 pAlloc = &pRc->aAllocations[i];
465 Assert((pAlloc->SurfDesc.width == tstW) || (!tstW && (pAlloc->SurfDesc.width==1)));
466 Assert((pAlloc->SurfDesc.height == tstH) || (!tstH && (pAlloc->SurfDesc.height==1)));
467 }
468 }
469#endif
470
471 if (SUCCEEDED(hr))
472 {
473 if (pRc->RcDesc.fFlags.CubeMap)
474 {
475 if ( (pAllocation->SurfDesc.width!=pAllocation->SurfDesc.height)
476 || (pRc->cAllocations%6!=0))
477 {
478 WARN(("unexpected cubemap texture config: (%d ; %d), allocs: %d",
479 pAllocation->SurfDesc.width, pAllocation->SurfDesc.height, pRc->cAllocations));
480 hr = E_INVALIDARG;
481 }
482 else
483 {
484 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateCubeTexture((IDirect3DDevice9Ex *)pDevice9If,
485 pAllocation->SurfDesc.d3dWidth,
486 VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc),
487 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
488 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
489 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
490 (IDirect3DCubeTexture9**)&pD3DIfTex,
491#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
492 NULL,
493#else
494 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
495#endif
496 pavClientMem);
497 Assert(hr == S_OK);
498 Assert(pD3DIfTex);
499 enmD3DIfType = VBOXDISP_D3DIFTYPE_CUBE_TEXTURE;
500 }
501 }
502 else if (pRc->RcDesc.fFlags.Volume)
503 {
504 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateVolumeTexture((IDirect3DDevice9Ex *)pDevice9If,
505 pAllocation->SurfDesc.d3dWidth,
506 pAllocation->SurfDesc.height,
507 pAllocation->SurfDesc.depth,
508 pRc->cAllocations,
509 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
510 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
511 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
512 (IDirect3DVolumeTexture9**)&pD3DIfTex,
513#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
514 NULL,
515#else
516 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
517#endif
518 pavClientMem);
519 Assert(hr == S_OK);
520 Assert(pD3DIfTex);
521 enmD3DIfType = VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE;
522 }
523 else
524 {
525 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
526 pAllocation->SurfDesc.d3dWidth,
527 pAllocation->SurfDesc.height,
528 pRc->cAllocations,
529 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
530 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
531 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
532 (IDirect3DTexture9**)&pD3DIfTex,
533#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
534 NULL,
535#else
536 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
537#endif
538 pavClientMem);
539 Assert(hr == S_OK);
540 Assert(pD3DIfTex);
541 enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
542 }
543
544 if (SUCCEEDED(hr))
545 {
546 Assert(pD3DIfTex);
547 Assert(enmD3DIfType != VBOXDISP_D3DIFTYPE_UNDEFINED);
548#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
549 Assert(!!(pRc->RcDesc.fFlags.SharedResource) == !!(hSharedHandle));
550#endif
551 for (UINT i = 0; i < pRc->cAllocations; ++i)
552 {
553 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
554 pAlloc->enmD3DIfType = enmD3DIfType;
555 pAlloc->pD3DIf = pD3DIfTex;
556 pAlloc->hSharedHandle = hSharedHandle;
557 if (i > 0)
558 pD3DIfTex->AddRef();
559 }
560 }
561 }
562
563 if (pavClientMem)
564 RTMemFree(pavClientMem);
565 }
566 else if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary)
567 {
568 for (UINT i = 0; i < pRc->cAllocations; ++i)
569 {
570 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
571 HANDLE hSharedHandle = pAllocation->hSharedHandle;
572 IDirect3DSurface9* pD3D9Surf;
573 if ((pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) || pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
574 {
575 hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
576 pAllocation->SurfDesc.height,
577 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
578 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
579 pRc->RcDesc.MultisampleQuality,
580 !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */,
581 &pD3D9Surf,
582#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
583 NULL
584#else
585 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL
586#endif
587 );
588 Assert(hr == S_OK);
589 }
590 else if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
591 {
592 do {
593 BOOL bNeedPresent;
594 if (pRc->cAllocations != 1)
595 {
596 WARN(("unexpected config: more than one (%d) shared primary for rc", pRc->cAllocations));
597 hr = E_FAIL;
598 break;
599 }
600 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pAllocation, &bNeedPresent);
601 Assert(bNeedPresent);
602 if (!pSwapchain)
603 {
604 WARN(("vboxWddmSwapchainFindCreate failed"));
605 hr = E_OUTOFMEMORY;
606 break;
607 }
608
609 hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
610 if (!SUCCEEDED(hr))
611 {
612 WARN(("vboxWddmSwapchainChkCreateIf failed hr 0x%x", hr));
613 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_UNDEFINED);
614 Assert(!pAllocation->pD3DIf);
615 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
616 break;
617 }
618
619 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
620 Assert(pAllocation->pD3DIf);
621 pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
622 break;
623 } while (0);
624 }
625 else
626 {
627 WARN(("unexpected alloc type %d", pAllocation->enmType));
628 hr = E_FAIL;
629 }
630
631 if (SUCCEEDED(hr))
632 {
633 Assert(pD3D9Surf);
634 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
635 pAllocation->pD3DIf = pD3D9Surf;
636#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
637 Assert(!!(pRc->RcDesc.fFlags.SharedResource) == !!(hSharedHandle));
638#endif
639 pAllocation->hSharedHandle = hSharedHandle;
640 hr = S_OK;
641 continue;
642
643 /* fail branch */
644 pD3D9Surf->Release();
645 }
646
647 for (UINT j = 0; j < i; ++j)
648 {
649 pRc->aAllocations[j].pD3DIf->Release();
650 }
651 break;
652 }
653
654 if (SUCCEEDED(hr))
655 {
656 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
657 {
658 Assert(0);
659 vboxDispD3DIfSurfSynchMem(pRc);
660 }
661 }
662 }
663 else if (pRc->RcDesc.fFlags.ZBuffer)
664 {
665 for (UINT i = 0; i < pRc->cAllocations; ++i)
666 {
667 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
668 IDirect3DSurface9 *pD3D9Surf;
669 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
670 pAllocation->SurfDesc.height,
671 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
672 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
673 pRc->RcDesc.MultisampleQuality,
674 TRUE /* @todo: BOOL Discard */,
675 &pD3D9Surf,
676 NULL /*HANDLE* pSharedHandle*/);
677 Assert(hr == S_OK);
678 if (hr == S_OK)
679 {
680 Assert(pD3D9Surf);
681 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
682 pAllocation->pD3DIf = pD3D9Surf;
683 }
684 else
685 {
686 for (UINT j = 0; j < i; ++j)
687 {
688 pRc->aAllocations[j].pD3DIf->Release();
689 }
690 break;
691 }
692 }
693
694 if (SUCCEEDED(hr))
695 {
696 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
697 {
698 vboxDispD3DIfSurfSynchMem(pRc);
699 }
700 }
701 }
702 else if (pRc->RcDesc.fFlags.VertexBuffer)
703 {
704 for (UINT i = 0; i < pRc->cAllocations; ++i)
705 {
706 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
707 IDirect3DVertexBuffer9 *pD3D9VBuf;
708 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
709 vboxDDI2D3DUsage(pRc->RcDesc.fFlags)
710#ifdef VBOX_WITH_NEW_WINE
711 & (~D3DUSAGE_DYNAMIC) /* <- avoid using dynamic to ensure wine does not switch do user buffer */
712#endif
713 ,
714 pRc->RcDesc.Fvf,
715 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
716 &pD3D9VBuf,
717 NULL /*HANDLE* pSharedHandle*/);
718 Assert(hr == S_OK);
719 if (hr == S_OK)
720 {
721 Assert(pD3D9VBuf);
722 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
723 pAllocation->pD3DIf = pD3D9VBuf;
724 }
725 else
726 {
727 for (UINT j = 0; j < i; ++j)
728 {
729 pRc->aAllocations[j].pD3DIf->Release();
730 }
731 break;
732 }
733 }
734
735 if (SUCCEEDED(hr))
736 {
737 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
738 {
739 vboxDispD3DIfSurfSynchMem(pRc);
740 }
741 }
742 }
743 else if (pRc->RcDesc.fFlags.IndexBuffer)
744 {
745 for (UINT i = 0; i < pRc->cAllocations; ++i)
746 {
747 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
748 IDirect3DIndexBuffer9 *pD3D9IBuf;
749 hr = pDevice9If->CreateIndexBuffer(pAllocation->SurfDesc.width,
750 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
751 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
752 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
753 &pD3D9IBuf,
754 NULL /*HANDLE* pSharedHandle*/
755 );
756 Assert(hr == S_OK);
757 if (hr == S_OK)
758 {
759 Assert(pD3D9IBuf);
760 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
761 pAllocation->pD3DIf = pD3D9IBuf;
762 }
763 else
764 {
765 for (UINT j = 0; j < i; ++j)
766 {
767 pRc->aAllocations[j].pD3DIf->Release();
768 }
769 break;
770 }
771 }
772
773 if (SUCCEEDED(hr))
774 {
775 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
776 {
777 vboxDispD3DIfSurfSynchMem(pRc);
778 }
779 }
780 }
781 else
782 {
783 hr = E_FAIL;
784 WARN(("unsupported rc flags, %d", pRc->RcDesc.fFlags.Value));
785 }
786
787 return hr;
788}
789
790VOID VBoxD3DIfFillPresentParams(D3DPRESENT_PARAMETERS *pParams, PVBOXWDDMDISP_RESOURCE pRc, UINT cRTs)
791{
792 Assert(cRTs);
793 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
794 pParams->BackBufferWidth = pRc->aAllocations[0].SurfDesc.width;
795 pParams->BackBufferHeight = pRc->aAllocations[0].SurfDesc.height;
796 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRc->aAllocations[0].SurfDesc.format);
797 pParams->BackBufferCount = cRTs - 1;
798 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
799 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
800#if 0 //def VBOXDISP_WITH_WINE_BB_WORKAROUND /* this does not work so far any way :( */
801 if (cRTs == 1)
802 pParams->SwapEffect = D3DSWAPEFFECT_COPY;
803 else
804#endif
805 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
806 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
807 pParams->Windowed = TRUE;
808}
809
810HRESULT VBoxD3DIfDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
811{
812 VBOXWDDMDISP_RESOURCE Rc;
813 vboxWddmResourceInit(&Rc, 1);
814
815 Rc.RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
816 Rc.RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
817 Rc.RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
818 Rc.RcDesc.MultisampleQuality = 0;
819 PVBOXWDDMDISP_ALLOCATION pAlloc = &Rc.aAllocations[0];
820 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
821 pAlloc->SurfDesc.width = 0x4;
822 pAlloc->SurfDesc.height = 0x4;
823 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
824 Assert(!pDevice->pDevice9If);
825 VBOXWINEEX_D3DPRESENT_PARAMETERS Params;
826 VBoxD3DIfFillPresentParams(&Params.Base, &Rc, 2);
827 Params.pHgsmi = &pDevice->Uhgsmi.BasePrivate.Base;
828 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
829 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
830 IDirect3DDevice9 * pDevice9If = NULL;
831
832 HRESULT hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
833 if (SUCCEEDED(hr))
834 {
835 int32_t hostId = 0;
836 hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9GetHostId((IDirect3DDevice9Ex*)pDevice9If, &hostId);
837 if (SUCCEEDED(hr))
838 {
839 Assert(hostId);
840
841 VBOXDISPIFESCAPE Data;
842 Data.escapeCode = VBOXESC_SETCTXHOSTID;
843 Data.u32CmdSpecific = (uint32_t)hostId;
844 D3DDDICB_ESCAPE DdiEscape = {0};
845 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
846 DdiEscape.hDevice = pDevice->hDevice;
847 // DdiEscape.Flags.Value = 0;
848 DdiEscape.pPrivateDriverData = &Data;
849 DdiEscape.PrivateDriverDataSize = sizeof (Data);
850 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
851 if (SUCCEEDED(hr))
852 {
853 pDevice->pDevice9If = pDevice9If;
854 return S_OK;
855 }
856 else
857 WARN(("pfnEscapeCb VBOXESC_SETCTXHOSTID failed hr 0x%x", hr));
858 }
859 else
860 WARN(("pfnVBoxWineExD3DDev9GetHostId failed hr 0x%x", hr));
861
862 pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Term((IDirect3DDevice9Ex *)pDevice9If);
863 }
864 else
865 WARN(("CreateDevice failed hr 0x%x", hr));
866
867 return hr;
868}
869
870int vboxD3DIfSetHostId(PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t hostID, uint32_t *pHostID)
871{
872 struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
873 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
874
875 VBOXDISPIFESCAPE_SETALLOCHOSTID SetHostID = {0};
876 SetHostID.EscapeHdr.escapeCode = VBOXESC_SETALLOCHOSTID;
877 SetHostID.hostID = hostID;
878 SetHostID.hAlloc = pAlloc->hAllocation;
879
880 D3DDDICB_ESCAPE DdiEscape = {0};
881 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
882 DdiEscape.hDevice = pDevice->hDevice;
883// DdiEscape.Flags.Value = 0;
884 DdiEscape.pPrivateDriverData = &SetHostID;
885 DdiEscape.PrivateDriverDataSize = sizeof (SetHostID);
886 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
887 if (SUCCEEDED(hr))
888 {
889 if (pHostID)
890 *pHostID = SetHostID.EscapeHdr.u32CmdSpecific;
891
892 return SetHostID.rc;
893 }
894 else
895 WARN(("pfnEscapeCb VBOXESC_SETALLOCHOSTID failed hr 0x%x", hr));
896
897 return VERR_GENERAL_FAILURE;
898}
899
900IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc)
901{
902 IDirect3DSurface9 *pSurfIf;
903 struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
904 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
905
906 HRESULT hr = VBoxD3DIfCreateForRc(pRc);
907 if (!SUCCEEDED(hr))
908 {
909 WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
910 return NULL;
911 }
912
913 Assert(pAlloc->pD3DIf);
914 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
915 Assert(pAlloc->pRc->RcDesc.fFlags.SharedResource);
916
917 hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
918 if (!SUCCEEDED(hr))
919 {
920 WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
921 return NULL;
922 }
923
924 uint32_t hostID, usedHostId;
925 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &hostID);
926 if (SUCCEEDED(hr))
927 {
928 Assert(hostID);
929 int rc = vboxD3DIfSetHostId(pAlloc, hostID, &usedHostId);
930 if (!RT_SUCCESS(rc))
931 {
932 if (rc == VERR_NOT_EQUAL)
933 {
934 WARN(("another hostId % is in use, using it instead", usedHostId));
935 Assert(hostID != usedHostId);
936 Assert(usedHostId);
937 pSurfIf->Release();
938 pSurfIf = NULL;
939 for (UINT i = 0; i < pRc->cAllocations; ++i)
940 {
941 PVBOXWDDMDISP_ALLOCATION pCurAlloc = &pRc->aAllocations[i];
942 if (pCurAlloc->pD3DIf)
943 {
944 pCurAlloc->pD3DIf->Release();
945 pCurAlloc->pD3DIf = NULL;
946 }
947 }
948
949 pAlloc->hSharedHandle = (HANDLE)usedHostId;
950
951 hr = VBoxD3DIfCreateForRc(pRc);
952 if (!SUCCEEDED(hr))
953 {
954 WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
955 return NULL;
956 }
957
958 hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
959 if (!SUCCEEDED(hr))
960 {
961 WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
962 return NULL;
963 }
964 }
965 else
966 {
967 WARN(("vboxD3DIfSetHostId failed %#x, ignoring", hr));
968 hr = S_OK;
969 hostID = 0;
970 usedHostId = 0;
971 }
972 }
973 else
974 {
975 Assert(hostID == usedHostId);
976 }
977
978 pSurfIf->Release();
979 pSurfIf = NULL;
980 }
981 else
982 WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr));
983
984 return pAlloc->pD3DIf;
985}
Note: See TracBrowser for help on using the repository browser.

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