VirtualBox

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

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

(C) 2016

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