VirtualBox

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

Last change on this file since 43334 was 43334, checked in by vboxsync, 12 years ago

wddm/3d: volume texture func impl; fixes & cleanup

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.0 KB
Line 
1/* $Id: VBoxD3DIf.cpp 43334 2012-09-14 17:34:33Z 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 if (pRc->RcDesc.fFlags.ZBuffer)
430 {
431 for (UINT i = 0; i < pRc->cAllocations; ++i)
432 {
433 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
434 IDirect3DSurface9 *pD3D9Surf;
435 hr = pDevice9If->CreateDepthStencilSurface(pAllocation->SurfDesc.width,
436 pAllocation->SurfDesc.height,
437 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
438 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
439 pRc->RcDesc.MultisampleQuality,
440 TRUE /* @todo: BOOL Discard */,
441 &pD3D9Surf,
442 NULL /*HANDLE* pSharedHandle*/);
443 Assert(hr == S_OK);
444 if (hr == S_OK)
445 {
446 Assert(pD3D9Surf);
447 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
448 pAllocation->pD3DIf = pD3D9Surf;
449 }
450 else
451 {
452 for (UINT j = 0; j < i; ++j)
453 {
454 pRc->aAllocations[j].pD3DIf->Release();
455 }
456 break;
457 }
458 }
459
460 if (SUCCEEDED(hr))
461 {
462 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
463 {
464 vboxDispD3DIfSurfSynchMem(pRc);
465 }
466 }
467 }
468 else if (pRc->RcDesc.fFlags.VertexBuffer)
469 {
470 for (UINT i = 0; i < pRc->cAllocations; ++i)
471 {
472 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
473 IDirect3DVertexBuffer9 *pD3D9VBuf;
474 hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
475 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
476 pRc->RcDesc.Fvf,
477 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
478 &pD3D9VBuf,
479 NULL /*HANDLE* pSharedHandle*/);
480 Assert(hr == S_OK);
481 if (hr == S_OK)
482 {
483 Assert(pD3D9VBuf);
484 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_VERTEXBUFFER;
485 pAllocation->pD3DIf = pD3D9VBuf;
486 }
487 else
488 {
489 for (UINT j = 0; j < i; ++j)
490 {
491 pRc->aAllocations[j].pD3DIf->Release();
492 }
493 break;
494 }
495 }
496
497 if (SUCCEEDED(hr))
498 {
499 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
500 {
501 vboxDispD3DIfSurfSynchMem(pRc);
502 }
503 }
504 }
505 else if (pRc->RcDesc.fFlags.IndexBuffer)
506 {
507 for (UINT i = 0; i < pRc->cAllocations; ++i)
508 {
509 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
510 IDirect3DIndexBuffer9 *pD3D9IBuf;
511 hr = pDevice9If->CreateIndexBuffer(pAllocation->SurfDesc.width,
512 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
513 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
514 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
515 &pD3D9IBuf,
516 NULL /*HANDLE* pSharedHandle*/
517 );
518 Assert(hr == S_OK);
519 if (hr == S_OK)
520 {
521 Assert(pD3D9IBuf);
522 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_INDEXBUFFER;
523 pAllocation->pD3DIf = pD3D9IBuf;
524 }
525 else
526 {
527 for (UINT j = 0; j < i; ++j)
528 {
529 pRc->aAllocations[j].pD3DIf->Release();
530 }
531 break;
532 }
533 }
534
535 if (SUCCEEDED(hr))
536 {
537 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
538 {
539 vboxDispD3DIfSurfSynchMem(pRc);
540 }
541 }
542 }
543 else if (VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags))
544 {
545 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[0];
546 IDirect3DBaseTexture9 *pD3DIfTex;
547 HANDLE hSharedHandle = pAllocation->hSharedHandle;
548 void **pavClientMem = NULL;
549 VBOXDISP_D3DIFTYPE enmD3DIfType = VBOXDISP_D3DIFTYPE_UNDEFINED;
550 hr = S_OK;
551 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
552 {
553 pavClientMem = (void**)RTMemAlloc(sizeof (pavClientMem[0]) * pRc->cAllocations);
554 Assert(pavClientMem);
555 if (pavClientMem)
556 {
557 for (UINT i = 0; i < pRc->cAllocations; ++i)
558 {
559 Assert(pRc->aAllocations[i].pvMem);
560 pavClientMem[i] = pRc->aAllocations[i].pvMem;
561 }
562 }
563 else
564 hr = E_FAIL;
565 }
566
567#ifdef DEBUG
568 if (!pRc->RcDesc.fFlags.CubeMap)
569 {
570 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[0];
571 uint32_t tstW = pAlloc->SurfDesc.width;
572 uint32_t tstH = pAlloc->SurfDesc.height;
573 for (UINT i = 1; i < pRc->cAllocations; ++i)
574 {
575 tstW /= 2;
576 tstH /= 2;
577 pAlloc = &pRc->aAllocations[i];
578 Assert((pAlloc->SurfDesc.width == tstW) || (!tstW && (pAlloc->SurfDesc.width==1)));
579 Assert((pAlloc->SurfDesc.height == tstH) || (!tstH && (pAlloc->SurfDesc.height==1)));
580 }
581 }
582#endif
583
584 if (SUCCEEDED(hr))
585 {
586 if (pRc->RcDesc.fFlags.CubeMap)
587 {
588 if ( (pAllocation->SurfDesc.width!=pAllocation->SurfDesc.height)
589 || (pRc->cAllocations%6!=0))
590 {
591 WARN(("unexpected cubemap texture config: (%d ; %d), allocs: %d",
592 pAllocation->SurfDesc.width, pAllocation->SurfDesc.height, pRc->cAllocations));
593 hr = E_INVALIDARG;
594 }
595 else
596 {
597 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateCubeTexture((IDirect3DDevice9Ex *)pDevice9If,
598 pAllocation->D3DWidth,
599 VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc),
600 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
601 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
602 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
603 (IDirect3DCubeTexture9**)&pD3DIfTex,
604#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
605 NULL,
606#else
607 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
608#endif
609 pavClientMem);
610 Assert(hr == S_OK);
611 Assert(pD3DIfTex);
612 enmD3DIfType = VBOXDISP_D3DIFTYPE_CUBE_TEXTURE;
613 }
614 }
615 else if (pRc->RcDesc.fFlags.Volume)
616 {
617 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateVolumeTexture((IDirect3DDevice9Ex *)pDevice9If,
618 pAllocation->D3DWidth,
619 pAllocation->SurfDesc.height,
620 pAllocation->SurfDesc.depth,
621 pRc->cAllocations,
622 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
623 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
624 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
625 (IDirect3DVolumeTexture9**)&pD3DIfTex,
626#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
627 NULL,
628#else
629 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
630#endif
631 pavClientMem);
632 Assert(hr == S_OK);
633 Assert(pD3DIfTex);
634 enmD3DIfType = VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE;
635 }
636 else
637 {
638 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
639 pAllocation->D3DWidth,
640 pAllocation->SurfDesc.height,
641 pRc->cAllocations,
642 vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
643 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
644 vboxDDI2D3DPool(pRc->RcDesc.enmPool),
645 (IDirect3DTexture9**)&pD3DIfTex,
646#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
647 NULL,
648#else
649 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL,
650#endif
651 pavClientMem);
652 Assert(hr == S_OK);
653 Assert(pD3DIfTex);
654 enmD3DIfType = VBOXDISP_D3DIFTYPE_TEXTURE;
655 }
656
657 if (SUCCEEDED(hr))
658 {
659 Assert(pD3DIfTex);
660 Assert(enmD3DIfType != VBOXDISP_D3DIFTYPE_UNDEFINED);
661#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
662 Assert(!!(pRc->RcDesc.fFlags.SharedResource) == !!(hSharedHandle));
663#endif
664 for (UINT i = 0; i < pRc->cAllocations; ++i)
665 {
666 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
667 pAlloc->enmD3DIfType = enmD3DIfType;
668 pAlloc->pD3DIf = pD3DIfTex;
669 pAlloc->hSharedHandle = hSharedHandle;
670 if (i > 0)
671 pD3DIfTex->AddRef();
672 }
673 }
674 }
675
676 if (pavClientMem)
677 RTMemFree(pavClientMem);
678 }
679 else if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary)
680 {
681 for (UINT i = 0; i < pRc->cAllocations; ++i)
682 {
683 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
684 HANDLE hSharedHandle = pAllocation->hSharedHandle;
685 IDirect3DSurface9* pD3D9Surf;
686 switch (pAllocation->enmType)
687 {
688 case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
689 {
690 hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
691 pAllocation->SurfDesc.height,
692 vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
693 vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
694 pRc->RcDesc.MultisampleQuality,
695 !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */,
696 &pD3D9Surf,
697#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
698 NULL
699#else
700 pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL
701#endif
702 );
703 Assert(hr == S_OK);
704 break;
705 }
706 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
707 {
708 BOOL bNeedPresent;
709 if (pRc->cAllocations != 1)
710 {
711 WARN(("unexpected config: more than one (%d) shared primary for rc", pRc->cAllocations));
712 hr = E_FAIL;
713 break;
714 }
715 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pAllocation, &bNeedPresent);
716 Assert(bNeedPresent);
717 if (!pSwapchain)
718 {
719 WARN(("vboxWddmSwapchainFindCreate failed"));
720 hr = E_OUTOFMEMORY;
721 break;
722 }
723
724 hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
725 if (!SUCCEEDED(hr))
726 {
727 WARN(("vboxWddmSwapchainChkCreateIf failed hr 0x%x", hr));
728 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_UNDEFINED);
729 Assert(!pAllocation->pD3DIf);
730 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
731 break;
732 }
733
734 Assert(pAllocation->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
735 Assert(pAllocation->pD3DIf);
736 pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
737 break;
738 }
739 default:
740 {
741 WARN(("unexpected alloc type %d", pAllocation->enmType));
742 hr = E_FAIL;
743 break;
744 }
745 }
746
747 if (SUCCEEDED(hr))
748 {
749 Assert(pD3D9Surf);
750 pAllocation->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
751 pAllocation->pD3DIf = pD3D9Surf;
752#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
753 Assert(!!(pRc->RcDesc.fFlags.SharedResource) == !!(hSharedHandle));
754#endif
755 pAllocation->hSharedHandle = hSharedHandle;
756 hr = S_OK;
757 continue;
758
759 /* fail branch */
760 pD3D9Surf->Release();
761 }
762
763 for (UINT j = 0; j < i; ++j)
764 {
765 pRc->aAllocations[j].pD3DIf->Release();
766 }
767 break;
768 }
769
770 if (SUCCEEDED(hr))
771 {
772 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
773 {
774 Assert(0);
775 vboxDispD3DIfSurfSynchMem(pRc);
776 }
777 }
778 }
779 else
780 {
781 hr = E_FAIL;
782 WARN(("unsupported rc flags, %d", pRc->RcDesc.fFlags.Value));
783 }
784
785 return hr;
786}
787
788VOID VBoxD3DIfFillPresentParams(D3DPRESENT_PARAMETERS *pParams, PVBOXWDDMDISP_RESOURCE pRc, UINT cRTs)
789{
790 Assert(cRTs);
791 memset(pParams, 0, sizeof (D3DPRESENT_PARAMETERS));
792 pParams->BackBufferWidth = pRc->aAllocations[0].SurfDesc.width;
793 pParams->BackBufferHeight = pRc->aAllocations[0].SurfDesc.height;
794 pParams->BackBufferFormat = vboxDDI2D3DFormat(pRc->aAllocations[0].SurfDesc.format);
795 pParams->BackBufferCount = cRTs - 1;
796 pParams->MultiSampleType = vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType);
797 pParams->MultiSampleQuality = pRc->RcDesc.MultisampleQuality;
798#if 0 //def VBOXDISP_WITH_WINE_BB_WORKAROUND /* this does not work so far any way :( */
799 if (cRTs == 1)
800 pParams->SwapEffect = D3DSWAPEFFECT_COPY;
801 else
802#endif
803 if (pRc->RcDesc.fFlags.DiscardRenderTarget)
804 pParams->SwapEffect = D3DSWAPEFFECT_DISCARD;
805 pParams->Windowed = TRUE;
806}
807
808HRESULT VBoxD3DIfDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
809{
810 VBOXWDDMDISP_RESOURCE Rc;
811 vboxWddmResourceInit(&Rc, 1);
812
813 Rc.RcDesc.enmFormat = D3DDDIFMT_A8R8G8B8;
814 Rc.RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
815 Rc.RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
816 Rc.RcDesc.MultisampleQuality = 0;
817 PVBOXWDDMDISP_ALLOCATION pAlloc = &Rc.aAllocations[0];
818 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
819 pAlloc->SurfDesc.width = 0x4;
820 pAlloc->SurfDesc.height = 0x4;
821 pAlloc->SurfDesc.format = D3DDDIFMT_A8R8G8B8;
822 Assert(!pDevice->pDevice9If);
823 VBOXWINEEX_D3DPRESENT_PARAMETERS Params;
824 VBoxD3DIfFillPresentParams(&Params.Base, &Rc, 2);
825 Params.pHgsmi = &pDevice->Uhgsmi.BasePrivate.Base;
826 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
827 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
828 IDirect3DDevice9 * pDevice9If = NULL;
829
830 HRESULT hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
831 if (!SUCCEEDED(hr))
832 {
833 WARN(("CreateDevice failed hr 0x%x", hr));
834 return hr;
835 }
836
837 pDevice->pDevice9If = pDevice9If;
838 return S_OK;
839}
840
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