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 |
|
---|
22 | D3DFORMAT vboxDDI2D3DFormat(D3DDDIFORMAT format)
|
---|
23 | {
|
---|
24 | /* @todo: check they are all equal */
|
---|
25 | return (D3DFORMAT)format;
|
---|
26 | }
|
---|
27 |
|
---|
28 | D3DMULTISAMPLE_TYPE vboxDDI2D3DMultiSampleType(D3DDDIMULTISAMPLE_TYPE enmType)
|
---|
29 | {
|
---|
30 | /* @todo: check they are all equal */
|
---|
31 | return (D3DMULTISAMPLE_TYPE)enmType;
|
---|
32 | }
|
---|
33 |
|
---|
34 | D3DPOOL 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 |
|
---|
52 | D3DRENDERSTATETYPE vboxDDI2D3DRenderStateType(D3DDDIRENDERSTATETYPE enmType)
|
---|
53 | {
|
---|
54 | /* @todo: @fixme: not entirely correct, need to check */
|
---|
55 | return (D3DRENDERSTATETYPE)enmType;
|
---|
56 | }
|
---|
57 |
|
---|
58 | VBOXWDDMDISP_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 |
|
---|
106 | DWORD 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 |
|
---|
137 | DWORD 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 |
|
---|
151 | D3DTEXTUREFILTERTYPE 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 |
|
---|
170 | D3DQUERYTYPE vboxDDI2D3DQueryType(D3DDDIQUERYTYPE enmType)
|
---|
171 | {
|
---|
172 | return (D3DQUERYTYPE)enmType;
|
---|
173 | }
|
---|
174 |
|
---|
175 | DWORD 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 */
|
---|
188 | static 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 |
|
---|
216 | void 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 |
|
---|
305 | HRESULT 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 |
|
---|
369 | HRESULT 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 |
|
---|
424 | HRESULT 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 |
|
---|
792 | VOID 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 |
|
---|
812 | HRESULT 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 |
|
---|
877 | int 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 |
|
---|
908 | IUnknown* 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 | }
|
---|