VirtualBox

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

Last change on this file since 66507 was 63570, checked in by vboxsync, 8 years ago

doxy fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.1 KB
Line 
1/* $Id: VBoxD3DIf.cpp 63570 2016-08-16 16:37:19Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2012-2016 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 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 == (UINT)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 == (LONG)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); NOREF(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 = NULL; /* Shut up MSC. */
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 = NULL; /* Shut up MSC. */
573 if (
574#ifdef VBOX_WITH_CROGL
575 (pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) ||
576#endif
577 pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
578 {
579 hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
580 pAllocation->SurfDesc.height,
581 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
582 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
583 pRc->RcDesc.MultisampleQuality,
584 !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */,
585 &pD3D9Surf,
586#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
587 NULL
588#else
589 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL
590#endif
591 );
592 Assert(hr == S_OK);
593 }
594 else if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
595 {
596 do {
597 BOOL bNeedPresent;
598 if (pRc->cAllocations != 1)
599 {
600 WARN(("unexpected config: more than one (%d) shared primary for rc", pRc->cAllocations));
601 hr = E_FAIL;
602 break;
603 }
604 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pAllocation, &bNeedPresent);
605 Assert(bNeedPresent);
606 if (!pSwapchain)
607 {
608 WARN(("vboxWddmSwapchainFindCreate failed"));
609 hr = E_OUTOFMEMORY;
610 break;
611 }
612
613 hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
614 if (!SUCCEEDED(hr))
615 {
616 WARN(("vboxWddmSwapchainChkCreateIf failed hr 0x%x", hr));
617 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_UNDEFINED);
618 Assert(!pAllocation->pD3DIf);
619 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
620 break;
621 }
622
623 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
624 Assert(pAllocation->pD3DIf);
625 pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
626 break;
627 } while (0);
628 }
629 else
630 {
631 WARN(("unexpected alloc type %d", pAllocation->enmType));
632 hr = E_FAIL;
633 }
634
635 if (SUCCEEDED(hr))
636 {
637 Assert(pD3D9Surf);
638 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
639 pAllocation->pD3DIf = pD3D9Surf;
640#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
641 Assert(!!(pRc->RcDesc.fFlags.SharedResource) == !!(hSharedHandle));
642#endif
643 pAllocation->hSharedHandle = hSharedHandle;
644 hr = S_OK;
645 continue;
646#if 0 /* unreachable */
647 /* fail branch */
648 pD3D9Surf->Release();
649#endif
650 }
651
652 for (UINT j = 0; j < i; ++j)
653 {
654 pRc->aAllocations[j].pD3DIf->Release();
655 }
656 break;
657 }
658
659 if (SUCCEEDED(hr))
660 {
661 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
662 {
663 Assert(0);
664 vboxDispD3DIfSurfSynchMem(pRc);
665 }
666 }
667 }
668 else if (pRc->RcDesc.fFlags.ZBuffer)
669 {
670 for (UINT i = 0; i < pRc->cAllocations; ++i)
671 {
672 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
673 IDirect3DSurface9 *pD3D9Surf;
674 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
675 pAllocation->SurfDesc.height,
676 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
677 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
678 pRc->RcDesc.MultisampleQuality,
679 TRUE /** @todo BOOL Discard */,
680 &pD3D9Surf,
681 NULL /*HANDLE* pSharedHandle*/);
682 Assert(hr == S_OK);
683 if (hr == S_OK)
684 {
685 Assert(pD3D9Surf);
686 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
687 pAllocation->pD3DIf = pD3D9Surf;
688 }
689 else
690 {
691 for (UINT j = 0; j < i; ++j)
692 {
693 pRc->aAllocations[j].pD3DIf->Release();
694 }
695 break;
696 }
697 }
698
699 if (SUCCEEDED(hr))
700 {
701 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
702 {
703 vboxDispD3DIfSurfSynchMem(pRc);
704 }
705 }
706 }
707 else if (pRc->RcDesc.fFlags.VertexBuffer)
708 {
709 for (UINT i = 0; i < pRc->cAllocations; ++i)
710 {
711 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
712 IDirect3DVertexBuffer9 *pD3D9VBuf;
713 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
714 vboxDDI2D3DUsage(pRc->RcDesc.fFlags)
715 & (~D3DUSAGE_DYNAMIC) /* <- avoid using dynamic to ensure wine does not switch do user buffer */
716 ,
717 pRc->RcDesc.Fvf,
718 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
719 &pD3D9VBuf,
720 NULL /*HANDLE* pSharedHandle*/);
721 Assert(hr == S_OK);
722 if (hr == S_OK)
723 {
724 Assert(pD3D9VBuf);
725 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
726 pAllocation->pD3DIf = pD3D9VBuf;
727 }
728 else
729 {
730 for (UINT j = 0; j < i; ++j)
731 {
732 pRc->aAllocations[j].pD3DIf->Release();
733 }
734 break;
735 }
736 }
737
738 if (SUCCEEDED(hr))
739 {
740 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
741 {
742 vboxDispD3DIfSurfSynchMem(pRc);
743 }
744 }
745 }
746 else if (pRc->RcDesc.fFlags.IndexBuffer)
747 {
748 for (UINT i = 0; i < pRc->cAllocations; ++i)
749 {
750 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
751 IDirect3DIndexBuffer9 *pD3D9IBuf;
752 hr = pDevice9If->CreateIndexBuffer(pAllocation->SurfDesc.width,
753 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
754 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
755 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
756 &pD3D9IBuf,
757 NULL /*HANDLE* pSharedHandle*/
758 );
759 Assert(hr == S_OK);
760 if (hr == S_OK)
761 {
762 Assert(pD3D9IBuf);
763 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
764 pAllocation->pD3DIf = pD3D9IBuf;
765 }
766 else
767 {
768 for (UINT j = 0; j < i; ++j)
769 {
770 pRc->aAllocations[j].pD3DIf->Release();
771 }
772 break;
773 }
774 }
775
776 if (SUCCEEDED(hr))
777 {
778 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
779 {
780 vboxDispD3DIfSurfSynchMem(pRc);
781 }
782 }
783 }
784 else
785 {
786 hr = E_FAIL;
787 WARN(("unsupported rc flags, %d", pRc->RcDesc.fFlags.Value));
788 }
789
790 return hr;
791}
792
793VOID VBoxD3DIfFillPresentParams(D3DPRESENT_PARAMETERS *pParams, PVBOXWDDMDISP_RESOURCE pRc, UINT cRTs)
794{
795 Assert(cRTs);
796 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
797 pParams->BackBufferWidth = pRc->aAllocations[0].SurfDesc.width;
798 pParams->BackBufferHeight = pRc->aAllocations[0].SurfDesc.height;
799 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRc->aAllocations[0].SurfDesc.format);
800 pParams->BackBufferCount = cRTs - 1;
801 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
802 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
803#if 0 //def VBOXDISP_WITH_WINE_BB_WORKAROUND /* this does not work so far any way :( */
804 if (cRTs == 1)
805 pParams->SwapEffect = D3DSWAPEFFECT_COPY;
806 else
807#endif
808 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
809 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
810 pParams->Windowed = TRUE;
811}
812
813HRESULT VBoxD3DIfDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
814{
815 VBOXWDDMDISP_RESOURCE Rc;
816 vboxWddmResourceInit(&Rc, 1);
817
818 Rc.RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
819 Rc.RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
820 Rc.RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
821 Rc.RcDesc.MultisampleQuality = 0;
822 PVBOXWDDMDISP_ALLOCATION pAlloc = &Rc.aAllocations[0];
823 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
824 pAlloc->SurfDesc.width = 0x4;
825 pAlloc->SurfDesc.height = 0x4;
826 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
827 Assert(!pDevice->pDevice9If);
828 VBOXWINEEX_D3DPRESENT_PARAMETERS Params;
829 VBoxD3DIfFillPresentParams(&Params.Base, &Rc, 2);
830#ifdef VBOX_WITH_CRHGSMI
831 Params.pHgsmi = &pDevice->Uhgsmi.BasePrivate.Base;
832#else
833 Params.pHgsmi = NULL;
834#endif
835 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING
836 | D3DCREATE_FPU_PRESERVE; /* Do not allow Wine to mess with FPU control word. */
837 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
838 IDirect3DDevice9 * pDevice9If = NULL;
839
840 HRESULT hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
841 if (SUCCEEDED(hr))
842 {
843 int32_t hostId = 0;
844 hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9GetHostId((IDirect3DDevice9Ex*)pDevice9If, &hostId);
845 if (SUCCEEDED(hr))
846 {
847 Assert(hostId);
848
849 VBOXDISPIFESCAPE Data;
850 Data.escapeCode = VBOXESC_SETCTXHOSTID;
851 Data.u32CmdSpecific = (uint32_t)hostId;
852 D3DDDICB_ESCAPE DdiEscape = {0};
853 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
854 DdiEscape.hDevice = pDevice->hDevice;
855 // DdiEscape.Flags.Value = 0;
856 DdiEscape.pPrivateDriverData = &Data;
857 DdiEscape.PrivateDriverDataSize = sizeof (Data);
858 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
859 if (SUCCEEDED(hr))
860 {
861 pDevice->pDevice9If = pDevice9If;
862 return S_OK;
863 }
864 else
865 WARN(("pfnEscapeCb VBOXESC_SETCTXHOSTID failed hr 0x%x", hr));
866 }
867 else
868 WARN(("pfnVBoxWineExD3DDev9GetHostId failed hr 0x%x", hr));
869
870 pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Term((IDirect3DDevice9Ex *)pDevice9If);
871 }
872 else
873 WARN(("CreateDevice failed hr 0x%x", hr));
874
875 return hr;
876}
877
878int vboxD3DIfSetHostId(PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t hostID, uint32_t *pHostID)
879{
880 struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
881 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
882
883 VBOXDISPIFESCAPE_SETALLOCHOSTID SetHostID = {0};
884 SetHostID.EscapeHdr.escapeCode = VBOXESC_SETALLOCHOSTID;
885 SetHostID.hostID = hostID;
886 SetHostID.hAlloc = pAlloc->hAllocation;
887
888 D3DDDICB_ESCAPE DdiEscape = {0};
889 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
890 DdiEscape.hDevice = pDevice->hDevice;
891 DdiEscape.Flags.Value = 0;
892 DdiEscape.Flags.HardwareAccess = 1;
893 DdiEscape.pPrivateDriverData = &SetHostID;
894 DdiEscape.PrivateDriverDataSize = sizeof (SetHostID);
895 HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
896 if (SUCCEEDED(hr))
897 {
898 if (pHostID)
899 *pHostID = SetHostID.EscapeHdr.u32CmdSpecific;
900
901 return SetHostID.rc;
902 }
903 else
904 WARN(("pfnEscapeCb VBOXESC_SETALLOCHOSTID failed hr 0x%x", hr));
905
906 return VERR_GENERAL_FAILURE;
907}
908
909IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc)
910{
911 IDirect3DSurface9 *pSurfIf;
912 struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
913 PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
914
915 HRESULT hr = VBoxD3DIfCreateForRc(pRc);
916 if (!SUCCEEDED(hr))
917 {
918 WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
919 return NULL;
920 }
921
922 Assert(pAlloc->pD3DIf);
923 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
924 Assert(pAlloc->pRc->RcDesc.fFlags.SharedResource);
925
926 hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
927 if (!SUCCEEDED(hr))
928 {
929 WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
930 return NULL;
931 }
932
933 uint32_t hostID, usedHostId;
934 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &hostID);
935 if (SUCCEEDED(hr))
936 {
937 Assert(hostID);
938 int rc = vboxD3DIfSetHostId(pAlloc, hostID, &usedHostId);
939 if (!RT_SUCCESS(rc))
940 {
941 if (rc == VERR_NOT_EQUAL)
942 {
943 WARN(("another hostId % is in use, using it instead", usedHostId));
944 Assert(hostID != usedHostId);
945 Assert(usedHostId);
946 pSurfIf->Release();
947 pSurfIf = NULL;
948 for (UINT i = 0; i < pRc->cAllocations; ++i)
949 {
950 PVBOXWDDMDISP_ALLOCATION pCurAlloc = &pRc->aAllocations[i];
951 if (pCurAlloc->pD3DIf)
952 {
953 pCurAlloc->pD3DIf->Release();
954 pCurAlloc->pD3DIf = NULL;
955 }
956 }
957
958 pAlloc->hSharedHandle = (HANDLE)usedHostId;
959
960 hr = VBoxD3DIfCreateForRc(pRc);
961 if (!SUCCEEDED(hr))
962 {
963 WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
964 return NULL;
965 }
966
967 hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
968 if (!SUCCEEDED(hr))
969 {
970 WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
971 return NULL;
972 }
973 }
974 else
975 {
976 WARN(("vboxD3DIfSetHostId failed %#x, ignoring", hr));
977 hr = S_OK;
978 hostID = 0;
979 usedHostId = 0;
980 }
981 }
982 else
983 {
984 Assert(hostID == usedHostId);
985 }
986 }
987 else
988 WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr));
989
990 pSurfIf->Release();
991 pSurfIf = NULL;
992
993 return pAlloc->pD3DIf;
994}
Note: See TracBrowser for help on using the repository browser.

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