VirtualBox

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

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

wddm/3d: 1. DrawIndexedPrimitive fixes; 2. swapchain fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 235.5 KB
Line 
1/* $Id: VBoxDispD3D.cpp 43340 2012-09-18 11:13:49Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011 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
19#define INITGUID
20
21#include <iprt/initterm.h>
22#include <iprt/log.h>
23#include <iprt/mem.h>
24
25#include <VBox/Log.h>
26
27#include <VBox/VBoxGuestLib.h>
28
29#include "VBoxDispD3DCmn.h"
30#include "VBoxDispD3D.h"
31#include "VBoxScreen.h"
32#include <VBox/VBoxCrHgsmi.h>
33
34#include <Psapi.h>
35
36#ifdef VBOX_WDDMDISP_WITH_PROFILE
37
38volatile uint32_t g_u32VBoxDispProfileFunctionLoggerIndex = 0;
39
40struct VBOXDISPPROFILE_GLOBAL {
41 VBoxDispProfileFpsCounter ProfileDdiFps;
42 VBoxDispProfileSet ProfileDdiFunc;
43} g_VBoxDispProfile;
44
45/* uncomment to enable particular logging */
46/* allows dumping fps + how much time is spent in ddi functions in comparison with the rest time */
47//# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
48/* allows dumping time spent in each function and the number of calls made for any given function */
49# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE
50
51# ifdef VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE
52
53extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
54
55//static VBoxDispProfileSet g_VBoxDispProfileDDI("D3D_DDI");
56# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc)
57# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {\
58 (_pObj)->ProfileDdiFunc.dump(_pObj); \
59 } while (0)
60# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj) do {\
61 (_pObj)->ProfileDdiFunc.resetEntries();\
62 } while (0)
63# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {\
64 VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT();\
65 } while (0)
66
67# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT()
68
69# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pObj) do { \
70 if (!((_pObj)->ProfileDdiFunc.reportIteration() % 31) && !VBOXVDBG_IS_DWM()) {\
71 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj); \
72 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj); \
73 } \
74 } while (0)
75
76# else
77# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) do {} while(0)
78# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {} while(0)
79# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj) do {} while(0)
80# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {} while (0)
81# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() do {} while (0)
82# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev) do {} while (0)
83# endif
84
85# ifdef VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
86//static VBoxDispProfileFpsCounter g_VBoxDispFpsDDI(64);
87# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps)
88# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {\
89 VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT();\
90 } while (0)
91
92# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj) do { \
93 double fps = (_pObj)->ProfileDdiFps.GetFps(); \
94 double cps = (_pObj)->ProfileDdiFps.GetCps(); \
95 double tup = (_pObj)->ProfileDdiFps.GetTimeProcPercent(); \
96 VBOXDISPPROFILE_DUMP(("[0x%p]: fps: %f, cps: %.1f, host %.1f%%", (_pObj), fps, cps, tup)); \
97 } while (0)
98
99# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pObj) do { \
100 (_pObj)->ProfileDdiFps.ReportFrame(); \
101 if(!((_pObj)->ProfileDdiFps.GetNumFrames() % 31)) \
102 { \
103 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj); \
104 } \
105 } while (0)
106
107# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT()
108# else
109# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) do {} while(0)
110# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {} while (0)
111# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() do {} while (0)
112# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev) do {} while (0)
113# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj) do {} while (0)
114# endif
115
116# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) \
117 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj); \
118 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj);
119
120# define VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT() \
121 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT(); \
122 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT();
123
124# define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {\
125 VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT(); \
126 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev); \
127 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \
128 } while (0)
129
130# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {\
131 VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT(); \
132 VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev); \
133 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \
134 } while (0)
135
136# define VBOXDISPPROFILE_DDI_INIT_CMN(_pObj, _name, _cEntries) do { \
137 (_pObj)->ProfileDdiFps = VBoxDispProfileFpsCounter(); \
138 (_pObj)->ProfileDdiFps.init(_cEntries); \
139 (_pObj)->ProfileDdiFunc = VBoxDispProfileSet(_name); \
140 } while (0)
141
142# define VBOXDISPPROFILE_DDI_TERM_CMN(_pObj) do { \
143 (_pObj)->ProfileDdiFps.term(); \
144 } while (0)
145
146# define VBOXDISPPROFILE_DDI_TERM(_pObj) do {\
147 VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT(); \
148 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj); \
149 VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj); \
150 VBOXDISPPROFILE_DDI_TERM_CMN(_pObj); \
151 } while (0)
152
153# define VBOXDISPPROFILE_DDI_PRINT(_m) VBOXDISPPROFILE_DUMP(_m)
154
155# define VBOXDISPPROFILE_DDI_INIT_GLBL() VBOXDISPPROFILE_DDI_INIT_CMN(&g_VBoxDispProfile, "DDI_Adp", 64)
156# define VBOXDISPPROFILE_DDI_INIT_ADP(_pAdp) VBOXDISPPROFILE_DDI_INIT_CMN(_pAdp, "DDI_Adp", 64)
157# define VBOXDISPPROFILE_DDI_INIT_DEV(_pDev) VBOXDISPPROFILE_DDI_INIT_CMN(_pDev, "DDI_Dev", 64)
158#else
159# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) do {} while (0)
160# define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {} while (0)
161# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {} while (0)
162# define VBOXDISPPROFILE_DDI_INIT_GLBL() do {} while (0)
163# define VBOXDISPPROFILE_DDI_INIT_ADP(_pAdp) do {} while (0)
164# define VBOXDISPPROFILE_DDI_INIT_DEV(_pDev) do {} while (0)
165# define VBOXDISPPROFILE_DDI_TERM(_pObj) do {} while (0)
166# define VBOXDISPPROFILE_DDI_PRINT(_m) do {} while (0)
167#endif
168
169/* debugging/profiling stuff could go here.
170 * NOP in release */
171#define VBOXDISP_DDI_PROLOGUE_CMN() \
172 VBOXVDBG_BREAK_DDI(); \
173 VBOXVDBG_CREATE_CHECK_SWAPCHAIN();
174
175#define VBOXDISP_DDI_PROLOGUE_DEV(_hDevice) \
176 VBOXDISP_DDI_PROLOGUE_CMN(); \
177 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_DEVICE)(_hDevice));
178
179#define VBOXDISP_DDI_PROLOGUE_ADP(_hAdapter) \
180 VBOXDISP_DDI_PROLOGUE_CMN(); \
181 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_ADAPTER)(_hAdapter));
182
183#define VBOXDISP_DDI_PROLOGUE_GLBL() \
184 VBOXDISP_DDI_PROLOGUE_CMN(); \
185 VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(&g_VBoxDispProfile);
186
187#ifdef VBOXDISPMP_TEST
188HRESULT vboxDispMpTstStart();
189HRESULT vboxDispMpTstStop();
190#endif
191
192#define VBOXDISP_WITH_WINE_BB_WORKAROUND
193
194static VBOXSCREENMONRUNNER g_VBoxScreenMonRunner;
195
196//#define VBOXWDDMOVERLAY_TEST
197
198static D3DDDIQUERYTYPE gVBoxQueryTypes[] = {
199 D3DDDIQUERYTYPE_EVENT,
200// D3DDDIQUERYTYPE_OCCLUSION
201};
202
203#define VBOX_QUERYTYPE_COUNT() RT_ELEMENTS(gVBoxQueryTypes)
204
205static CRITICAL_SECTION g_VBoxCritSect;
206
207void vboxDispLock()
208{
209 EnterCriticalSection(&g_VBoxCritSect);
210}
211
212void vboxDispUnlock()
213{
214 LeaveCriticalSection(&g_VBoxCritSect);
215}
216
217void vboxDispLockInit()
218{
219 InitializeCriticalSection(&g_VBoxCritSect);
220}
221
222
223#define VBOXDISPCRHGSMI_SCOPE_SET_DEV(_pDev) do {} while(0)
224#define VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL() do {} while(0)
225
226
227typedef struct VBOXWDDMDISP_NSCADD
228{
229 VOID* pvCommandBuffer;
230 UINT cbCommandBuffer;
231 D3DDDI_ALLOCATIONLIST* pAllocationList;
232 UINT cAllocationList;
233 D3DDDI_PATCHLOCATIONLIST* pPatchLocationList;
234 UINT cPatchLocationList;
235 UINT cAllocations;
236}VBOXWDDMDISP_NSCADD, *PVBOXWDDMDISP_NSCADD;
237
238static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc)
239{
240 HRESULT hr = S_OK;
241 if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
242 {
243 memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
244 pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
245 if (pAlloc->fDirtyWrite)
246 pData->pAllocationList[0].WriteOperation = 1;
247
248 memset(pData->pPatchLocationList, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
249 pData->pPatchLocationList[0].PatchOffset = pData->cAllocations*4;
250 pData->pPatchLocationList[0].AllocationIndex = pData->cAllocations;
251
252 pData->cbCommandBuffer -= 4;
253 --pData->cAllocationList;
254 --pData->cPatchLocationList;
255 ++pData->cAllocations;
256
257 ++pData->pAllocationList;
258 ++pData->pPatchLocationList;
259 pData->pvCommandBuffer = (VOID*)(((uint8_t*)pData->pvCommandBuffer) + 4);
260
261 }
262 else
263 hr = S_FALSE;
264
265 return hr;
266}
267
268static BOOLEAN vboxWddmDalCheckRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
269{
270 BOOLEAN fRemoved = FALSE;
271
272 if (pAlloc->DirtyAllocListEntry.pNext)
273 {
274 RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
275 pAlloc->fDirtyWrite = FALSE;
276 fRemoved = TRUE;
277 }
278
279 return fRemoved;
280}
281
282static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice)
283{
284 VBOXWDDMDISP_NSCADD NscAdd;
285 BOOL bReinitRenderData = TRUE;
286
287 do
288 {
289 if (bReinitRenderData)
290 {
291 NscAdd.pvCommandBuffer = pDevice->DefaultContext.ContextInfo.pCommandBuffer;
292 NscAdd.cbCommandBuffer = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
293 NscAdd.pAllocationList = pDevice->DefaultContext.ContextInfo.pAllocationList;
294 NscAdd.cAllocationList = pDevice->DefaultContext.ContextInfo.AllocationListSize;
295 NscAdd.pPatchLocationList = pDevice->DefaultContext.ContextInfo.pPatchLocationList;
296 NscAdd.cPatchLocationList = pDevice->DefaultContext.ContextInfo.PatchLocationListSize;
297 NscAdd.cAllocations = 0;
298 Assert(NscAdd.cbCommandBuffer >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
299 if (NscAdd.cbCommandBuffer < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
300 return E_FAIL;
301
302 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)NscAdd.pvCommandBuffer;
303 pHdr->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
304 NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr));
305 NscAdd.cbCommandBuffer -= sizeof (*pHdr);
306 bReinitRenderData = FALSE;
307 }
308
309 PVBOXWDDMDISP_ALLOCATION pAlloc = RTListGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
310 if (pAlloc)
311 {
312 HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc);
313 Assert(tmpHr == S_OK || tmpHr == S_FALSE);
314 if (tmpHr == S_OK)
315 {
316 vboxWddmDalCheckRemove(pDevice, pAlloc);
317 continue;
318 }
319 }
320 else
321 {
322 if (!NscAdd.cAllocations)
323 break;
324 }
325
326 D3DDDICB_RENDER RenderData = {0};
327 RenderData.CommandLength = pDevice->DefaultContext.ContextInfo.CommandBufferSize - NscAdd.cbCommandBuffer;
328 Assert(RenderData.CommandLength);
329 Assert(RenderData.CommandLength < UINT32_MAX/2);
330 RenderData.CommandOffset = 0;
331 RenderData.NumAllocations = pDevice->DefaultContext.ContextInfo.AllocationListSize - NscAdd.cAllocationList;
332 Assert(RenderData.NumAllocations == NscAdd.cAllocations);
333 RenderData.NumPatchLocations = pDevice->DefaultContext.ContextInfo.PatchLocationListSize - NscAdd.cPatchLocationList;
334 Assert(RenderData.NumPatchLocations == NscAdd.cAllocations);
335// RenderData.NewCommandBufferSize = sizeof (VBOXVDMACMD) + 4 * (100);
336// RenderData.NewAllocationListSize = 100;
337// RenderData.NewPatchLocationListSize = 100;
338 RenderData.hContext = pDevice->DefaultContext.ContextInfo.hContext;
339
340 HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &RenderData);
341 Assert(hr == S_OK);
342 if (hr == S_OK)
343 {
344 pDevice->DefaultContext.ContextInfo.CommandBufferSize = RenderData.NewCommandBufferSize;
345 pDevice->DefaultContext.ContextInfo.pCommandBuffer = RenderData.pNewCommandBuffer;
346 pDevice->DefaultContext.ContextInfo.AllocationListSize = RenderData.NewAllocationListSize;
347 pDevice->DefaultContext.ContextInfo.pAllocationList = RenderData.pNewAllocationList;
348 pDevice->DefaultContext.ContextInfo.PatchLocationListSize = RenderData.NewPatchLocationListSize;
349 pDevice->DefaultContext.ContextInfo.pPatchLocationList = RenderData.pNewPatchLocationList;
350 bReinitRenderData = TRUE;
351 }
352 else
353 break;
354 } while (1);
355
356 return S_OK;
357}
358
359//#define VBOX_WDDM_SHRC_WO_NOTIFY
360static BOOLEAN vboxWddmDalCheckAdd(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOLEAN fWrite)
361{
362 if (!pAlloc->hAllocation /* only shared resources matter */
363#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
364 || !fWrite /* only write op matter */
365#endif
366 )
367 {
368#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
369 Assert(!pAlloc->DirtyAllocListEntry.pNext || (!fWrite && pAlloc->hSharedHandle && pAlloc->fDirtyWrite));
370#else
371 Assert(!pAlloc->DirtyAllocListEntry.pNext);
372#endif
373 Assert(!pAlloc->hSharedHandle);
374
375 return FALSE;
376 }
377
378 if (!pAlloc->DirtyAllocListEntry.pNext)
379 {
380 Assert(!pAlloc->fDirtyWrite);
381 RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
382 }
383 pAlloc->fDirtyWrite |= fWrite;
384
385 return TRUE;
386}
387
388static DECLINLINE(BOOLEAN) vboxWddmDalCheckAddRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, BOOLEAN fWrite)
389{
390 BOOLEAN fChanged = FALSE;
391 for (UINT i = 0; i < pRc->cAllocations; ++i)
392 {
393 PVBOXWDDMDISP_ALLOCATION pDAlloc = &pRc->aAllocations[i];
394 fChanged |= vboxWddmDalCheckAdd(pDevice, pDAlloc, fWrite);
395 }
396 return fChanged;
397}
398
399static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice)
400{
401 for (UINT i = 0; i < pDevice->cRTs; ++i)
402 {
403 if (pDevice->apRTs[i])
404 {
405 vboxWddmDalCheckAdd(pDevice, pDevice->apRTs[i], TRUE);
406 }
407 }
408
409 for (UINT i = 0, iSampler = 0; iSampler < pDevice->cSamplerTextures; ++i)
410 {
411 Assert(i < RT_ELEMENTS(pDevice->aSamplerTextures));
412 if (!pDevice->aSamplerTextures[i]) continue;
413 vboxWddmDalCheckAddRc(pDevice, pDevice->aSamplerTextures[i], FALSE);
414 ++iSampler;
415 }
416}
417
418#ifdef VBOX_WITH_VIDEOHWACCEL
419
420static bool vboxVhwaIsEnabled(PVBOXWDDMDISP_ADAPTER pAdapter)
421{
422 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
423 {
424 if (pAdapter->aHeads[i].Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)
425 return true;
426 }
427 return false;
428}
429
430static bool vboxVhwaHasCKeying(PVBOXWDDMDISP_ADAPTER pAdapter)
431{
432 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
433 {
434 VBOXVHWA_INFO* pSettings = &pAdapter->aHeads[i].Vhwa.Settings;
435 if ((pSettings->fFlags & VBOXVHWA_F_ENABLED)
436 && ((pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
437 || (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC))
438 )
439 return true;
440 }
441 return false;
442}
443
444#endif
445
446static void vboxResourceFree(PVBOXWDDMDISP_RESOURCE pRc)
447{
448 RTMemFree(pRc);
449}
450
451void vboxWddmResourceInit(PVBOXWDDMDISP_RESOURCE pRc, UINT cAllocs)
452{
453 memset(pRc, 0, RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
454 pRc->cAllocations = cAllocs;
455 for (UINT i = 0; i < cAllocs; ++i)
456 {
457 pRc->aAllocations[i].iAlloc = i;
458 pRc->aAllocations[i].pRc = pRc;
459 }
460}
461
462static PVBOXWDDMDISP_RESOURCE vboxResourceAlloc(UINT cAllocs)
463{
464 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)RTMemAlloc(RT_OFFSETOF(VBOXWDDMDISP_RESOURCE, aAllocations[cAllocs]));
465 Assert(pRc);
466 if (pRc)
467 {
468 vboxWddmResourceInit(pRc, cAllocs);
469 return pRc;
470 }
471 return NULL;
472}
473
474#ifdef VBOXWDDMDISP_DEBUG
475static void vboxWddmDbgSynchMemCheck(PVBOXWDDMDISP_ALLOCATION pAlloc, D3DLOCKED_RECT *pLockInfo)
476{
477 Assert(pAlloc->SurfDesc.pitch);
478 Assert(pAlloc->pvMem);
479 int iRc = 0;
480
481 if (pAlloc->SurfDesc.pitch == pLockInfo->Pitch)
482 {
483 Assert(pAlloc->SurfDesc.cbSize);
484 iRc = memcmp(pLockInfo->pBits, pAlloc->pvMem, pAlloc->SurfDesc.cbSize);
485 Assert(!iRc);
486 }
487 else
488 {
489 uint8_t *pvSrc, *pvDst;
490 uint32_t srcPitch, dstPitch;
491 if (1)
492 {
493 pvSrc = (uint8_t *)pAlloc->pvMem;
494 pvDst = (uint8_t *)pLockInfo->pBits;
495 srcPitch = pAlloc->SurfDesc.pitch;
496 dstPitch = pLockInfo->Pitch;
497 }
498 else
499 {
500 pvDst = (uint8_t *)pAlloc->pvMem;
501 pvSrc = (uint8_t *)pLockInfo->pBits;
502 dstPitch = pAlloc->SurfDesc.pitch;
503 srcPitch = (uint32_t)pLockInfo->Pitch;
504 }
505
506 Assert(pAlloc->SurfDesc.pitch <= (UINT)pLockInfo->Pitch);
507 uint32_t pitch = RT_MIN(srcPitch, dstPitch);
508 Assert(pitch);
509 uint32_t cRows = vboxWddmCalcNumRows(0, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format);
510 for (UINT j = 0; j < cRows; ++j)
511 {
512 iRc = memcmp(pvDst, pvSrc, pitch);
513 Assert(!iRc);
514 pvSrc += srcPitch;
515 pvDst += dstPitch;
516 }
517 }
518}
519
520static VOID vboxWddmDbgRcSynchMemCheck(PVBOXWDDMDISP_RESOURCE pRc)
521{
522 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
523 {
524 return;
525 }
526
527 for (UINT i = 0; i < pRc->cAllocations; ++i)
528 {
529 D3DLOCKED_RECT Rect;
530 HRESULT hr = VBoxD3DIfLockRect(pRc, i, &Rect, NULL, D3DLOCK_READONLY);
531 if (FAILED(hr))
532 {
533 WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
534 return;
535 }
536
537 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
538 Assert(pAlloc->pvMem);
539
540 vboxWddmDbgSynchMemCheck(pAlloc, &Rect);
541
542 hr = VBoxD3DIfUnlockRect(pRc, i);
543 Assert(SUCCEEDED(hr));
544 }
545}
546#endif
547
548
549/******/
550static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch);
551
552DECLINLINE(VOID) vboxWddmSwapchainInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
553{
554 RTLISTNODE ListEntry = pSwapchain->ListEntry;
555 memset(pSwapchain, 0, sizeof (VBOXWDDMDISP_SWAPCHAIN));
556 pSwapchain->ListEntry = ListEntry;
557 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
558}
559
560static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
561{
562 struct
563 {
564 VBOXDISPIFESCAPE_SWAPCHAININFO SwapchainInfo;
565 D3DKMT_HANDLE ahAllocs[VBOXWDDMDISP_MAX_SWAPCHAIN_SIZE];
566 } Buf;
567
568 memset(&Buf.SwapchainInfo, 0, sizeof (Buf.SwapchainInfo));
569 Buf.SwapchainInfo.EscapeHdr.escapeCode = VBOXESC_SWAPCHAININFO;
570 Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
571 Buf.SwapchainInfo.SwapchainInfo.hSwapchainUm = (VBOXDISP_UMHANDLE)pSwapchain;
572// Buf.SwapchainInfo.SwapchainInfo.Rect;
573// Buf.SwapchainInfo.SwapchainInfo.u32Reserved;
574 Buf.SwapchainInfo.SwapchainInfo.cAllocs = pSwapchain->cRTs;
575 UINT cAllocsKm = 0;
576 for (UINT i = 0; i < Buf.SwapchainInfo.SwapchainInfo.cAllocs; ++i)
577 {
578// Assert(pSwapchain->aRTs[i].pAlloc->hAllocation);
579 Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i] = pSwapchain->aRTs[i].pAlloc->hAllocation;
580 if (Buf.SwapchainInfo.SwapchainInfo.ahAllocs[i])
581 ++cAllocsKm;
582 }
583
584 Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm);
585 HRESULT hr = S_OK;
586 if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs)
587 {
588 D3DDDICB_ESCAPE DdiEscape = {0};
589 DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
590 DdiEscape.hDevice = pDevice->hDevice;
591 // DdiEscape.Flags.Value = 0;
592 DdiEscape.pPrivateDriverData = &Buf.SwapchainInfo;
593 DdiEscape.PrivateDriverDataSize = RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[Buf.SwapchainInfo.SwapchainInfo.cAllocs]);
594 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
595#ifdef DEBUG_misha
596 Assert(hr == S_OK);
597#endif
598 if (hr == S_OK)
599 {
600 pSwapchain->hSwapchainKm = Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm;
601 }
602 }
603
604 return S_OK;
605}
606
607static HRESULT vboxWddmSwapchainKmDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
608{
609 HRESULT hr = S_OK;
610 if (pSwapchain->hSwapchainKm)
611 {
612 /* submit empty swapchain to destroy the KM one */
613 UINT cOldRTc = pSwapchain->cRTs;
614 pSwapchain->cRTs = 0;
615 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
616 Assert(hr == S_OK);
617 Assert(!pSwapchain->hSwapchainKm);
618 pSwapchain->cRTs = cOldRTc;
619 }
620 return hr;
621}
622static HRESULT vboxWddmSwapchainDestroyIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
623{
624 if (pSwapchain->pSwapChainIf)
625 {
626#ifndef VBOXWDDM_WITH_VISIBLE_FB
627 if (pSwapchain->pRenderTargetFbCopy)
628 {
629 pSwapchain->pRenderTargetFbCopy->Release();
630 pSwapchain->pRenderTargetFbCopy = NULL;
631 pSwapchain->bRTFbCopyUpToDate = FALSE;
632 }
633#endif
634 pSwapchain->pSwapChainIf->Release();
635 Assert(pSwapchain->hWnd);
636 pSwapchain->pSwapChainIf = NULL;
637 pSwapchain->hWnd = NULL;
638 return S_OK;
639 }
640
641 Assert(!pSwapchain->hWnd);
642 return S_OK;
643}
644
645DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
646{
647 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
648 {
649 pSwapchain->aRTs[i].pAlloc->pSwapchain = NULL;
650 }
651
652 /* first do a Km destroy to ensure all km->um region submissions are completed */
653 vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
654 vboxDispMpInternalCancel(&pDevice->DefaultContext, pSwapchain);
655 vboxWddmSwapchainDestroyIf(pDevice, pSwapchain);
656 vboxWddmSwapchainInit(pSwapchain);
657}
658
659VOID vboxWddmSwapchainDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
660{
661 vboxWddmSwapchainClear(pDevice, pSwapchain);
662 RTListNodeRemove(&pSwapchain->ListEntry);
663 RTMemFree(pSwapchain);
664}
665
666static VOID vboxWddmSwapchainDestroyAll(PVBOXWDDMDISP_DEVICE pDevice)
667{
668 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
669 while (pCur)
670 {
671 PVBOXWDDMDISP_SWAPCHAIN pNext = NULL;
672 if (!RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
673 {
674 pNext = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
675 }
676
677 vboxWddmSwapchainDestroy(pDevice, pCur);
678
679 pCur = pNext;
680 }
681}
682
683static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainAlloc(PVBOXWDDMDISP_DEVICE pDevice)
684{
685 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)RTMemAllocZ(sizeof (VBOXWDDMDISP_SWAPCHAIN));
686 Assert(pSwapchain);
687 if (pSwapchain)
688 {
689 RTListAppend(&pDevice->SwapchainList, &pSwapchain->ListEntry);
690 vboxWddmSwapchainInit(pSwapchain);
691 return pSwapchain;
692 }
693 return NULL;
694}
695
696DECLINLINE(VOID) vboxWddmSwapchainRtInit(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRt, PVBOXWDDMDISP_ALLOCATION pAlloc)
697{
698 pSwapchain->fFlags.bChanged = 1;
699 pRt->pAlloc = pAlloc;
700 pRt->cNumFlips = 0;
701 pRt->fFlags.Value = 0;
702 pRt->fFlags.bAdded = 1;
703}
704
705DECLINLINE(VOID) vboxWddmSwapchainBbAddTail(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bAssignAsBb)
706{
707 pAlloc->pSwapchain = pSwapchain;
708 VBOXWDDMDISP_SWAPCHAIN_FLAGS fOldFlags = pSwapchain->fFlags;
709 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[pSwapchain->cRTs];
710 ++pSwapchain->cRTs;
711 vboxWddmSwapchainRtInit(pSwapchain, pRt, pAlloc);
712 if (pSwapchain->cRTs == 1)
713 {
714 Assert(pSwapchain->iBB == VBOXWDDMDISP_INDEX_UNDEFINED);
715 pSwapchain->iBB = 0;
716 }
717 else if (bAssignAsBb)
718 {
719 pSwapchain->iBB = pSwapchain->cRTs - 1;
720 }
721 else if (pSwapchain->cRTs == 2) /* the first one is a frontbuffer */
722 {
723 pSwapchain->iBB = 1;
724 }
725}
726
727DECLINLINE(VOID) vboxWddmSwapchainFlip(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
728{
729 pSwapchain->iBB = (pSwapchain->iBB + 1) % pSwapchain->cRTs;
730}
731
732DECLINLINE(UINT) vboxWddmSwapchainNumRTs(PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
733{
734 return pSwapchain->cRTs;
735}
736
737
738DECLINLINE(PVBOXWDDMDISP_RENDERTGT) vboxWddmSwapchainRtForAlloc(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc)
739{
740 if (pAlloc->pSwapchain != pSwapchain)
741 return NULL;
742
743 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
744 {
745 Assert(pSwapchain->aRTs[i].pAlloc->pSwapchain = pSwapchain);
746 if (pSwapchain->aRTs[i].pAlloc == pAlloc)
747 return &pSwapchain->aRTs[i];
748 }
749
750 /* should never happen */
751 Assert(0);
752 return NULL;
753}
754
755DECLINLINE(UINT) vboxWddmSwapchainRtIndex(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
756{
757 UINT offFirst = RT_OFFSETOF(VBOXWDDMDISP_SWAPCHAIN, aRTs);
758 UINT offRT = UINT((uintptr_t)pRT - (uintptr_t)pSwapchain);
759 Assert(offRT < sizeof (VBOXWDDMDISP_SWAPCHAIN));
760 Assert(offRT >= offFirst);
761 Assert(!((offRT - offFirst) % sizeof (VBOXWDDMDISP_RENDERTGT)));
762 UINT iRt = (offRT - offFirst) / sizeof (VBOXWDDMDISP_RENDERTGT);
763 Assert(iRt < pSwapchain->cRTs);
764 return iRt;
765}
766
767DECLINLINE(VOID) vboxWddmSwapchainRtRemove(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
768{
769 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
770 Assert(iRt < pSwapchain->cRTs);
771 pRT->pAlloc->pSwapchain = NULL;
772 for (UINT i = iRt; i < pSwapchain->cRTs - 1; ++i)
773 {
774 pSwapchain->aRTs[i] = pSwapchain->aRTs[i + 1];
775 }
776
777 --pSwapchain->cRTs;
778 if (pSwapchain->cRTs)
779 {
780 if (pSwapchain->iBB > iRt)
781 {
782 --pSwapchain->iBB;
783 }
784 else if (pSwapchain->iBB == iRt)
785 {
786 pSwapchain->iBB = 0;
787 }
788 }
789 else
790 {
791 pSwapchain->iBB = VBOXWDDMDISP_INDEX_UNDEFINED;
792 }
793 pSwapchain->fFlags.bChanged = TRUE;
794 pSwapchain->fFlags.bSwitchReportingPresent = TRUE;
795}
796
797DECLINLINE(VOID) vboxWddmSwapchainSetBb(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_RENDERTGT pRT)
798{
799 UINT iRt = vboxWddmSwapchainRtIndex(pSwapchain, pRT);
800 Assert(iRt < pSwapchain->cRTs);
801 pSwapchain->iBB = iRt;
802 pSwapchain->fFlags.bChanged = TRUE;
803}
804
805PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainFindCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc, BOOL *pbNeedPresent)
806{
807 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = pBbAlloc->pSwapchain;
808 if (pSwapchain)
809 {
810 /* check if this is what we expect */
811 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
812 if (pRt->pAlloc != pBbAlloc)
813 {
814 if (pBbAlloc == vboxWddmSwapchainGetFb(pSwapchain)->pAlloc)
815 {
816 /* the current front-buffer present is requested, don't do anything */
817 *pbNeedPresent = FALSE;
818 return pSwapchain;
819 }
820 /* bad, @todo: correct the swapchain by either removing the Rt and adding it to another swapchain
821 * or by removing the pBbAlloc out of it */
822//@todo: Assert(0);
823
824 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pBbAlloc);
825 Assert(pRt);
826 vboxWddmSwapchainSetBb(pSwapchain, pRt);
827 pSwapchain->fFlags.bSwitchReportingPresent = TRUE;
828 }
829 }
830
831 *pbNeedPresent = TRUE;
832
833 if (!pSwapchain)
834 {
835 /* first search for the swapchain the alloc might be added to */
836 PVBOXWDDMDISP_SWAPCHAIN pCur = RTListGetFirst(&pDevice->SwapchainList, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
837 while (pCur)
838 {
839 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pCur);
840 Assert(pRt);
841 if (pRt->cNumFlips < 2
842 && vboxWddmSwapchainRtIndex(pCur, pRt) == 0) /* <- in case we add a rt to the swapchain on present this would mean
843 * that the last RT in the swapchain array is now a frontbuffer and
844 * thus the aRTs[0] is a backbuffer */
845 {
846 if (pBbAlloc->SurfDesc.width == pRt->pAlloc->SurfDesc.width
847 && pBbAlloc->SurfDesc.height == pRt->pAlloc->SurfDesc.height
848 && vboxWddmFmtNoAlphaFormat(pBbAlloc->SurfDesc.format) == vboxWddmFmtNoAlphaFormat(pRt->pAlloc->SurfDesc.format)
849 && pBbAlloc->SurfDesc.VidPnSourceId == pRt->pAlloc->SurfDesc.VidPnSourceId
850 )
851 {
852 vboxWddmSwapchainBbAddTail(pCur, pBbAlloc, TRUE);
853 pSwapchain = pCur;
854 break;
855 }
856 }
857 if (RTListNodeIsLast(&pDevice->SwapchainList, &pCur->ListEntry))
858 break;
859 pCur = RTListNodeGetNext(&pCur->ListEntry, VBOXWDDMDISP_SWAPCHAIN, ListEntry);
860 }
861
862// if (!pSwapchain) need to create a new one (see below)
863 }
864
865 if (!pSwapchain)
866 {
867 pSwapchain = vboxWddmSwapchainAlloc(pDevice);
868 Assert(pSwapchain);
869 if (pSwapchain)
870 {
871 vboxWddmSwapchainBbAddTail(pSwapchain, pBbAlloc, FALSE);
872 }
873 }
874
875 return pSwapchain;
876}
877
878static PVBOXWDDMDISP_SWAPCHAIN vboxWddmSwapchainCreateForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc)
879{
880 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainAlloc(pDevice);
881 Assert(pSwapchain);
882 if (pSwapchain)
883 {
884 for (UINT i = 0; i < pRc->cAllocations; ++i)
885 {
886 vboxWddmSwapchainBbAddTail(pSwapchain, &pRc->aAllocations[i], FALSE);
887 }
888 return pSwapchain;
889 }
890 return NULL;
891}
892
893DECLINLINE(UINT) vboxWddmSwapchainIdxBb2Rt(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
894{
895 return iBb != (~0) ? (iBb + pSwapchain->iBB) % pSwapchain->cRTs : vboxWddmSwapchainIdxFb(pSwapchain);
896}
897
898static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, uint32_t iBb)
899{
900 if (pSwapchain->fFlags.bRtReportingPresent)
901 return S_OK;
902
903 IDirect3DSurface9 *pD3D9Surf;
904#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
905 if (pSwapchain->cRTs == 1)
906 {
907 iBb = 0;
908 }
909#endif
910 UINT iRt = vboxWddmSwapchainIdxBb2Rt(pSwapchain, iBb);
911 Assert(iRt < pSwapchain->cRTs);
912 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[iRt];
913 HRESULT hr = pSwapchain->pSwapChainIf->GetBackBuffer(iBb, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
914 if (FAILED(hr))
915 {
916 WARN(("GetBackBuffer failed, hr (0x%x)",hr));
917 return hr;
918 }
919
920 PVBOXWDDMDISP_ALLOCATION pAlloc = pRt->pAlloc;
921 Assert(pD3D9Surf);
922 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
923 if (pAlloc->pD3DIf)
924 {
925 if (pSwapchain->fFlags.bChanged)
926 {
927 IDirect3DSurface9 *pD3D9OldSurf = NULL;
928 if (pAlloc->pD3DIf)
929 {
930 /* since this can be texture, need to do the VBoxD3DIfSurfGet magic */
931 hr = VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9OldSurf);
932 if (FAILED(hr))
933 {
934 WARN(("VBoxD3DIfSurfGet failed, hr (0x%x)",hr));
935 pD3D9Surf->Release();
936 return hr;
937 }
938 }
939
940 if (pD3D9OldSurf && pD3D9OldSurf != pD3D9Surf)
941 {
942 VOID *pvSwapchain = NULL;
943 /* get the old surface's swapchain */
944 HRESULT tmpHr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
945 if (tmpHr == S_OK)
946 {
947 Assert(pvSwapchain);
948 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
949 }
950 else
951 {
952 Assert(!pvSwapchain);
953 }
954
955 if (pvSwapchain != pSwapchain->pSwapChainIf)
956 {
957 /* the swapchain has changed, copy data to the new surface */
958#ifdef DEBUG_misha
959 /* @todo: we can not generally update the render target directly, implement */
960 Assert(iBb != (~0));
961#endif
962 VBOXVDBG_CHECK_SWAPCHAIN_SYNC(hr = pDevice->pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9Surf, NULL, D3DTEXF_NONE); Assert(hr == S_OK),
963 pAlloc, pD3D9OldSurf, NULL, pAlloc, pD3D9Surf, NULL);
964 }
965 }
966
967 if (pD3D9OldSurf)
968 {
969 pD3D9OldSurf->Release();
970 }
971 }
972 else
973 {
974 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
975 }
976 pAlloc->pD3DIf->Release();
977 }
978
979 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
980 pAlloc->pD3DIf = pD3D9Surf;
981 pRt->fFlags.Value = 0;
982
983 if (pSwapchain->fFlags.bChanged)
984 {
985 for (UINT i = 0; i < pDevice->cRTs; ++i)
986 {
987 if (pDevice->apRTs[i] == pAlloc)
988 {
989 hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
990 Assert(hr == S_OK);
991 }
992 }
993 }
994
995#ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
996 if (pSwapchain->cRTs == 1)
997 {
998 IDirect3DSurface9 *pD3D9Bb;
999 /* only use direct bb if wine is able to handle quick blits bewteen surfaces in one swapchain,
1000 * this is FALSE by now :( */
1001# ifdef VBOX_WINE_WITH_FAST_INTERSWAPCHAIN_BLT
1002 /* here we sync the front-buffer with a backbuffer data*/
1003 pD3D9Bb = (IDirect3DSurface9*)vboxWddmSwapchainGetBb(pSwapchain)->pAlloc->pD3DIf;
1004 Assert(pD3D9Bb);
1005 pD3D9Bb->AddRef();
1006 /* we use backbuffer as a rt frontbuffer copy, so release the old one and assign the current bb */
1007 if (pSwapchain->pRenderTargetFbCopy)
1008 {
1009 pSwapchain->pRenderTargetFbCopy->Release();
1010 }
1011 pSwapchain->pRenderTargetFbCopy = pD3D9Bb;
1012# else
1013 pD3D9Bb = pSwapchain->pRenderTargetFbCopy;
1014# endif
1015 HRESULT tmpHr = pSwapchain->pSwapChainIf->GetFrontBufferData(pD3D9Bb);
1016 if (SUCCEEDED(tmpHr))
1017 {
1018 VBOXVDBG_DUMP_SYNC_RT(pD3D9Bb);
1019 pSwapchain->bRTFbCopyUpToDate = TRUE;
1020# ifndef VBOX_WINE_WITH_FAST_INTERSWAPCHAIN_BLT
1021 VBOXVDBG_CHECK_SWAPCHAIN_SYNC(tmpHr = pDevice->pDevice9If->StretchRect(pD3D9Bb, NULL, (IDirect3DSurface9*)vboxWddmSwapchainGetBb(pSwapchain)->pAlloc->pD3DIf, NULL, D3DTEXF_NONE); Assert(tmpHr == S_OK),
1022 pAlloc, pD3D9Bb, NULL, pAlloc, (IDirect3DSurface9*)vboxWddmSwapchainGetBb(pSwapchain)->pAlloc->pD3DIf, NULL);
1023
1024 if (FAILED(tmpHr))
1025 {
1026 WARN(("StretchRect failed, hr (0x%x)", tmpHr));
1027 }
1028# endif
1029 }
1030 else
1031 {
1032 WARN(("GetFrontBufferData failed, hr (0x%x)", hr));
1033 }
1034 }
1035#endif
1036 return hr;
1037}
1038
1039static HRESULT vboxWddmSwapchainSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1040{
1041 HRESULT hr = S_OK;
1042 for (int iBb = -1; iBb < int(pSwapchain->cRTs - 1); ++iBb)
1043 {
1044 hr = vboxWddmSwapchainRtSynch(pDevice, pSwapchain, (UINT)iBb);
1045 Assert(hr == S_OK);
1046 }
1047 if (pSwapchain->fFlags.bChanged)
1048 {
1049 hr = vboxWddmSwapchainKmSynch(pDevice, pSwapchain);
1050 if (hr == S_OK)
1051 {
1052 pSwapchain->fFlags.bChanged = 0;
1053 }
1054 }
1055 return hr;
1056}
1057
1058static VOID vboxWddmSwapchainFillPresentParams(PVBOXWDDMDISP_SWAPCHAIN pSwapchain, D3DPRESENT_PARAMETERS *pParams)
1059{
1060 Assert(pSwapchain->cRTs);
1061#ifdef DEBUG_misha
1062 /* not supported by wine properly, need to use offscreen render targets and blit their data to swapchain RTs*/
1063 Assert(pSwapchain->cRTs <= 2);
1064#endif
1065 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainGetBb(pSwapchain);
1066 PVBOXWDDMDISP_RESOURCE pRc = pRt->pAlloc->pRc;
1067 VBoxD3DIfFillPresentParams(pParams, pRc, pSwapchain->cRTs);
1068}
1069
1070/* copy current rt data to offscreen render targets */
1071static HRESULT vboxWddmSwapchainSwtichOffscreenRt(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, BOOL fForceCreate)
1072{
1073 D3DPRESENT_PARAMETERS Params;
1074 vboxWddmSwapchainFillPresentParams(pSwapchain, &Params);
1075 IDirect3DSurface9* pD3D9OldFb = NULL;
1076 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf;
1077 HRESULT hr = S_OK;
1078 if (pOldIf)
1079 {
1080 hr = pOldIf->GetBackBuffer(~0, D3DBACKBUFFER_TYPE_MONO, &pD3D9OldFb);
1081 if (FAILED(hr))
1082 {
1083 WARN(("GetBackBuffer ~0 failed, hr (%d)", hr));
1084 return hr;
1085 }
1086 /* just need a pointer to match */
1087 pD3D9OldFb->Release();
1088 }
1089
1090 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1091 {
1092 PVBOXWDDMDISP_RENDERTGT pRT = &pSwapchain->aRTs[i];
1093 if (pRT->pAlloc->enmD3DIfType != VBOXDISP_D3DIFTYPE_SURFACE)
1094 continue;
1095 BOOL fHasSurf = pRT->pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE ?
1096 !!pRT->pAlloc->pD3DIf
1097 :
1098 !!pRT->pAlloc->pRc->aAllocations[0].pD3DIf;
1099 if (!fForceCreate && !fHasSurf)
1100 continue;
1101
1102 IDirect3DSurface9* pD3D9OldSurf = NULL;
1103 if (fHasSurf)
1104 {
1105 VOID *pvSwapchain = NULL;
1106 /* since this can be texture, need to do the VBoxD3DIfSurfGet magic */
1107 hr = VBoxD3DIfSurfGet(pRT->pAlloc->pRc, pRT->pAlloc->iAlloc, &pD3D9OldSurf);
1108 Assert(hr == S_OK);
1109 hr = pD3D9OldSurf->GetContainer(IID_IDirect3DSwapChain9, &pvSwapchain);
1110 if (hr == S_OK)
1111 {
1112 Assert(pvSwapchain);
1113 ((IDirect3DSwapChain9 *)pvSwapchain)->Release();
1114 }
1115 else
1116 {
1117 hr = S_OK;
1118 Assert(!pvSwapchain);
1119 }
1120
1121 if (!pvSwapchain) /* no swapchain, it is already offscreen */
1122 {
1123 pD3D9OldSurf->Release();
1124 continue;
1125 }
1126 Assert (pvSwapchain == pOldIf);
1127 }
1128
1129 IDirect3DSurface9* pD3D9NewSurf;
1130 IDirect3DDevice9 *pDevice9If = pDevice->pDevice9If;
1131 hr = pDevice9If->CreateRenderTarget(
1132 Params.BackBufferWidth, Params.BackBufferHeight,
1133 Params.BackBufferFormat,
1134 Params.MultiSampleType,
1135 Params.MultiSampleQuality,
1136 TRUE, /*bLockable*/
1137 &pD3D9NewSurf,
1138 pRT->pAlloc->hSharedHandle ? &pRT->pAlloc->hSharedHandle : NULL
1139 );
1140 Assert(hr == S_OK);
1141 if (FAILED(hr))
1142 {
1143 if (pD3D9OldSurf)
1144 pD3D9OldSurf->Release();
1145 break;
1146 }
1147
1148 if (pD3D9OldSurf)
1149 {
1150 if (pD3D9OldSurf != pD3D9OldFb)
1151 {
1152 VBOXVDBG_CHECK_SWAPCHAIN_SYNC(hr = pDevice9If->StretchRect(pD3D9OldSurf, NULL, pD3D9NewSurf, NULL, D3DTEXF_NONE); Assert(hr == S_OK),
1153 pRT->pAlloc, pD3D9OldSurf, NULL, pRT->pAlloc, pD3D9NewSurf, NULL);
1154 }
1155 else
1156 {
1157 hr = pOldIf->GetFrontBufferData(pD3D9NewSurf);
1158 Assert(hr == S_OK);
1159 }
1160 }
1161 if (FAILED(hr))
1162 {
1163 if (pD3D9OldSurf)
1164 pD3D9OldSurf->Release();
1165 break;
1166 }
1167
1168 Assert(pRT->pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1169
1170 if (pRT->pAlloc->pD3DIf)
1171 pRT->pAlloc->pD3DIf->Release();
1172 pRT->pAlloc->pD3DIf = pD3D9NewSurf;
1173 if (pD3D9OldSurf)
1174 pD3D9OldSurf->Release();
1175 }
1176
1177 return hr;
1178}
1179
1180
1181/**
1182 * @return old RtReportingPresent state
1183 */
1184static HRESULT vboxWddmSwapchainSwtichRtPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1185{
1186 if (pSwapchain->fFlags.bRtReportingPresent)
1187 return S_OK;
1188
1189 HRESULT hr;
1190 pSwapchain->bRTFbCopyUpToDate = FALSE;
1191 if (pSwapchain->pRenderTargetFbCopy)
1192 {
1193 pSwapchain->pRenderTargetFbCopy->Release();
1194 pSwapchain->pRenderTargetFbCopy = NULL;
1195 }
1196
1197 hr = vboxWddmSwapchainSwtichOffscreenRt(pDevice, pSwapchain,
1198 TRUE /* force offscreen surface creation right away. This way we ensure the swapchain data
1199 * is always uptodate which allows making the vboxWddmSwapchainRtSynch behave as a nop */
1200 );
1201 Assert(hr == S_OK);
1202 if (FAILED(hr))
1203 return hr;
1204
1205 /* ensure we update device RTs to offscreen ones we just created */
1206 for (UINT i = 0; i < pDevice->cRTs; ++i)
1207 {
1208 PVBOXWDDMDISP_ALLOCATION pRtAlloc = pDevice->apRTs[i];
1209 for (UINT j = 0; j < pSwapchain->cRTs; ++j)
1210 {
1211 PVBOXWDDMDISP_ALLOCATION pAlloc = pSwapchain->aRTs[j].pAlloc;
1212 if (pRtAlloc == pAlloc)
1213 {
1214 hr = vboxWddmRenderTargetSet(pDevice, i, pAlloc, TRUE);
1215 Assert(hr == S_OK);
1216 }
1217 }
1218 }
1219
1220 pSwapchain->fFlags.bRtReportingPresent = TRUE;
1221 return hr;
1222}
1223
1224HRESULT vboxWddmSwapchainChkCreateIf(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1225{
1226 if (!pSwapchain->fFlags.bChanged && pSwapchain->pSwapChainIf)
1227 return S_OK;
1228 /* preserve the old one */
1229 IDirect3DSwapChain9 * pOldIf = pSwapchain->pSwapChainIf;
1230 HRESULT hr = S_OK;
1231 BOOL bReuseSwapchain = FALSE;
1232 BOOL fNeedRtPresentSwitch = FALSE;
1233
1234 if (pSwapchain->fFlags.bSwitchReportingPresent || pSwapchain->cRTs > VBOXWDDMDISP_MAX_DIRECT_RTS)
1235 {
1236 pSwapchain->fFlags.bSwitchReportingPresent = FALSE;
1237 /* indicae switch to Render Target Reporting Present mode is needed */
1238 fNeedRtPresentSwitch = TRUE;
1239// vboxWddmSwapchainSwtichRtPresent(pDevice, pSwapchain);
1240 }
1241 else
1242 {
1243 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1244 {
1245 if (pSwapchain->aRTs[i].pAlloc->enmD3DIfType != VBOXDISP_D3DIFTYPE_SURFACE
1246 && (pSwapchain->aRTs[i].pAlloc->enmD3DIfType != VBOXDISP_D3DIFTYPE_UNDEFINED
1247 || pSwapchain->aRTs[i].pAlloc->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
1248 ))
1249 {
1250 fNeedRtPresentSwitch = TRUE;
1251 break;
1252 }
1253 }
1254 }
1255
1256 /* check if we need to re-create the swapchain */
1257 if (pOldIf)
1258 {
1259 if (fNeedRtPresentSwitch)
1260 {
1261 /* the number of swapchain backbuffers does not matter */
1262 bReuseSwapchain = TRUE;
1263 }
1264 else
1265 {
1266 D3DPRESENT_PARAMETERS OldParams;
1267 hr = pOldIf->GetPresentParameters(&OldParams);
1268 Assert(hr == S_OK);
1269 if (hr == S_OK)
1270 {
1271 if (OldParams.BackBufferCount == pSwapchain->cRTs-1)
1272 {
1273 bReuseSwapchain = TRUE;
1274 }
1275 }
1276 }
1277 }
1278
1279 /* first create the new one */
1280 IDirect3DSwapChain9 * pNewIf;
1281 ///
1282 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
1283 UINT cSurfs = pSwapchain->cRTs;
1284 IDirect3DDevice9 *pDevice9If = NULL;
1285 HWND hOldWnd = pSwapchain->hWnd;
1286 if (!bReuseSwapchain)
1287 {
1288 VBOXWINEEX_D3DPRESENT_PARAMETERS Params;
1289 vboxWddmSwapchainFillPresentParams(pSwapchain, &Params.Base);
1290 Params.pHgsmi = NULL;
1291
1292 if (hr == S_OK)
1293 {
1294 DWORD fFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
1295
1296 Params.Base.hDeviceWindow = NULL;
1297 /* @todo: it seems there should be a way to detect this correctly since
1298 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
1299 Params.Base.Windowed = TRUE;
1300 // params.EnableAutoDepthStencil = FALSE;
1301 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
1302 // params.Flags;
1303 // params.FullScreen_RefreshRateInHz;
1304 // params.FullScreen_PresentationInterval;
1305 if (!pDevice->pDevice9If)
1306 {
1307 Params.pHgsmi = &pDevice->Uhgsmi.BasePrivate.Base;
1308 hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
1309 Assert(hr == S_OK);
1310 if (hr == S_OK)
1311 {
1312 Assert(Params.Base.hDeviceWindow);
1313 pSwapchain->hWnd = Params.Base.hDeviceWindow;
1314 pDevice->pDevice9If = pDevice9If;
1315 hr = pDevice9If->GetSwapChain(0, &pNewIf);
1316 Assert(hr == S_OK);
1317 if (hr == S_OK)
1318 {
1319 Assert(pNewIf);
1320 }
1321 else
1322 {
1323 pDevice9If->Release();
1324 }
1325 }
1326 }
1327 else
1328 {
1329 pDevice9If = pDevice->pDevice9If;
1330
1331 if (pOldIf)
1332 {
1333 /* need to copy data to offscreen rt to ensure the data is preserved
1334 * since the swapchain data may become invalid once we create a new swapchain
1335 * and pass the current swapchain's window to it
1336 * thus vboxWddmSwapchainSynch will not be able to do synchronization */
1337 hr = vboxWddmSwapchainSwtichOffscreenRt(pDevice, pSwapchain, FALSE);
1338 Assert(hr == S_OK);
1339 }
1340
1341 /* re-use swapchain window
1342 * this will invalidate the previusly used swapchain */
1343 Params.Base.hDeviceWindow = pSwapchain->hWnd;
1344
1345 hr = pDevice->pDevice9If->CreateAdditionalSwapChain(&Params.Base, &pNewIf);
1346 Assert(hr == S_OK);
1347 if (hr == S_OK)
1348 {
1349 Assert(Params.Base.hDeviceWindow);
1350 pSwapchain->hWnd = Params.Base.hDeviceWindow;
1351 Assert(pNewIf);
1352 }
1353 }
1354 }
1355 }
1356 else
1357 {
1358 Assert(pOldIf);
1359 Assert(hOldWnd);
1360 pNewIf = pOldIf;
1361 /* to ensure the swapchain is not deleted once we release the pOldIf */
1362 pNewIf->AddRef();
1363 }
1364
1365 if (FAILED(hr))
1366 return hr;
1367
1368 Assert(pNewIf);
1369 pSwapchain->pSwapChainIf = pNewIf;
1370
1371 if (fNeedRtPresentSwitch)
1372 {
1373 hr = vboxWddmSwapchainSwtichRtPresent(pDevice, pSwapchain);
1374 }
1375 else
1376 {
1377#ifndef VBOXWDDM_WITH_VISIBLE_FB
1378 if (!pSwapchain->fFlags.bRtReportingPresent)
1379 {
1380 pSwapchain->bRTFbCopyUpToDate = FALSE;
1381# if defined(VBOXDISP_WITH_WINE_BB_WORKAROUND) && defined(VBOX_WINE_WITH_FAST_INTERSWAPCHAIN_BLT)
1382 /* if wine is able to do fast fb->bb blits, we will use backbuffer directly,
1383 * this is NOT possible currently */
1384 if (pSwapchain->cRTs == 1)
1385 {
1386 /* we will assign it to wine backbuffer on a swapchain synch */
1387 if (pSwapchain->pRenderTargetFbCopy)
1388 {
1389 pSwapchain->pRenderTargetFbCopy->Release();
1390 pSwapchain->pRenderTargetFbCopy = NULL;
1391 }
1392 }
1393 else
1394# endif
1395 if (!pSwapchain->pRenderTargetFbCopy)
1396 {
1397 D3DPRESENT_PARAMETERS Params;
1398 vboxWddmSwapchainFillPresentParams(pSwapchain, &Params);
1399 IDirect3DSurface9* pD3D9Surf;
1400 hr = pDevice9If->CreateRenderTarget(
1401 Params.BackBufferWidth, Params.BackBufferHeight,
1402 Params.BackBufferFormat,
1403 Params.MultiSampleType,
1404 Params.MultiSampleQuality,
1405 TRUE, /*bLockable*/
1406 &pD3D9Surf,
1407 NULL /* HANDLE* pSharedHandle */
1408 );
1409 Assert(hr == S_OK);
1410 if (hr == S_OK)
1411 {
1412 Assert(pD3D9Surf);
1413 pSwapchain->pRenderTargetFbCopy = pD3D9Surf;
1414 }
1415 }
1416 }
1417#endif
1418 }
1419
1420 /* ignore any subsequen failures */
1421 Assert(hr == S_OK);
1422
1423
1424#ifdef DEBUG
1425 for (UINT i = 0; i < cSurfs; ++i)
1426 {
1427 PVBOXWDDMDISP_RENDERTGT pRt = &pSwapchain->aRTs[i];
1428 Assert(pRt->pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE
1429 || pRt->pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE);
1430 Assert(pRt->pAlloc->pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
1431 }
1432#endif
1433
1434 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
1435 Assert(hr == S_OK);
1436
1437 Assert(!pSwapchain->fFlags.bChanged);
1438 Assert(!pSwapchain->fFlags.bSwitchReportingPresent);
1439 if (pOldIf)
1440 {
1441 Assert(hOldWnd);
1442 pOldIf->Release();
1443 }
1444 else
1445 {
1446 Assert(!hOldWnd);
1447 }
1448 return S_OK;
1449}
1450
1451static HRESULT vboxWddmSwapchainCreateIfForRc(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, PVBOXWDDMDISP_SWAPCHAIN *ppSwapchain)
1452{
1453 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainCreateForRc(pDevice, pRc);
1454 Assert(pSwapchain);
1455 *ppSwapchain = NULL;
1456 if (pSwapchain)
1457 {
1458 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
1459 Assert(hr == S_OK);
1460 if (hr == S_OK)
1461 {
1462 *ppSwapchain = pSwapchain;
1463 }
1464 return hr;
1465 }
1466 return E_OUTOFMEMORY;
1467}
1468
1469static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain);
1470
1471static HRESULT vboxWddmSwapchainBbUpdate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
1472{
1473 Assert(!pSwapchain->fFlags.bRtReportingPresent);
1474 for (UINT i = 0; i < pSwapchain->cRTs; ++i)
1475 {
1476 PVBOXWDDMDISP_ALLOCATION pCurBb = vboxWddmSwapchainGetBb(pSwapchain)->pAlloc;
1477 if (pCurBb == pBbAlloc)
1478 return S_OK;
1479
1480 HRESULT hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain);
1481 if (FAILED(hr))
1482 {
1483 WARN(("vboxWddmSwapchainPresentPerform failed, hr (0x%x)", hr));
1484 return hr;
1485 }
1486 }
1487
1488 AssertMsgFailed(("the given allocation not par of the swapchain\n"));
1489 return E_FAIL;
1490}
1491
1492/* get the surface for the specified allocation in the swapchain */
1493static HRESULT vboxWddmSwapchainSurfGet(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DSurface9 **ppSurf)
1494{
1495 Assert(pAlloc->pSwapchain == pSwapchain);
1496
1497#ifndef VBOXWDDM_WITH_VISIBLE_FB
1498 if (!pSwapchain->fFlags.bRtReportingPresent
1499 && vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc
1500# ifdef VBOXDISP_WITH_WINE_BB_WORKAROUND
1501
1502 && vboxWddmSwapchainNumRTs(pSwapchain) != 1 /* for swapchains w/o a backbuffer the alloc will contain the back-buffer actually */
1503 )
1504 {
1505 /* this is a front-buffer */
1506 Assert(vboxWddmSwapchainNumRTs(pSwapchain) > 1);
1507 IDirect3DSurface9 *pSurf = pSwapchain->pRenderTargetFbCopy;
1508 Assert(pSurf);
1509 pSurf->AddRef();
1510 if (!pSwapchain->bRTFbCopyUpToDate)
1511 {
1512 HRESULT hr = pSwapchain->pSwapChainIf->GetFrontBufferData(pSurf);
1513 if (FAILED(hr))
1514 {
1515 WARN(("GetFrontBufferData failed, hr (0x%x)", hr));
1516 pSurf->Release();
1517 return hr;
1518 }
1519 pSwapchain->bRTFbCopyUpToDate = TRUE;
1520 }
1521
1522 *ppSurf = pSurf;
1523 return S_OK;
1524 }
1525# endif
1526#endif
1527
1528 /* if this is not a front-buffer - just return the surface associated with the allocation */
1529 return VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, ppSurf);
1530}
1531
1532static HRESULT vboxWddmSwapchainRtSurfGet(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch, IDirect3DSurface9 **ppSurf)
1533{
1534 Assert(pAlloc->pSwapchain == pSwapchain);
1535 HRESULT hr = S_OK;
1536
1537 /* do the necessary swapchain synchronization first,
1538 * not needed on swapchain synch since it is done already and we're called here just to set RTs */
1539 if (!bOnSwapchainSynch)
1540 {
1541
1542 if (!pSwapchain->fFlags.bRtReportingPresent)
1543 {
1544 /* iRt != 0 is untested here !! */
1545 Assert(iRt == 0);
1546 if (iRt == 0)
1547 {
1548 hr = vboxWddmSwapchainBbUpdate(pDevice, pSwapchain, pAlloc);
1549 if (FAILED(hr))
1550 {
1551 WARN(("vboxWddmSwapchainBbUpdate failed, hr(0x%x)",hr));
1552 return hr;
1553 }
1554 }
1555 }
1556
1557//@todo: Assert(!pSwapchain->fFlags.bChanged);
1558 Assert(pSwapchain->pSwapChainIf);
1559 hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
1560 if (FAILED(hr))
1561 {
1562 WARN(("vboxWddmSwapchainChkCreateIf failed, hr(0x%x)",hr));
1563 return hr;
1564 }
1565 }
1566
1567//@todo: Assert(vboxWddmSwapchainGetBb(pSwapchain)->pAlloc == pAlloc || iRt != 0);
1568 IDirect3DSurface9 *pSurf;
1569 hr = vboxWddmSwapchainSurfGet(pDevice, pSwapchain, pAlloc, &pSurf);
1570 if (FAILED(hr))
1571 {
1572 WARN(("vboxWddmSwapchainSurfGet failed, hr(0x%x)", hr));
1573 return hr;
1574 }
1575
1576 *ppSurf = pSurf;
1577 return S_OK;
1578
1579}
1580
1581static HRESULT vboxWddmSwapchainPresentPerform(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
1582{
1583 HRESULT hr;
1584
1585 VBOXVDBG_DUMP_PRESENT_ENTER(pDevice, pSwapchain);
1586
1587 if (!pSwapchain->fFlags.bRtReportingPresent)
1588 {
1589 hr = pSwapchain->pSwapChainIf->Present(NULL, NULL, NULL, NULL, 0);
1590 Assert(hr == S_OK);
1591 if (FAILED(hr))
1592 return hr;
1593 }
1594 else
1595 {
1596 PVBOXWDDMDISP_ALLOCATION pCurBb = vboxWddmSwapchainGetBb(pSwapchain)->pAlloc;
1597 IDirect3DSurface9 *pSurf;
1598 hr = vboxWddmSwapchainSurfGet(pDevice, pSwapchain, pCurBb, &pSurf);
1599 Assert(hr == S_OK);
1600 if (FAILED(hr))
1601 return hr;
1602 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSwapchain9Present(pSwapchain->pSwapChainIf, pSurf);
1603 Assert(hr == S_OK);
1604 pSurf->Release();
1605 if (FAILED(hr))
1606 return hr;
1607 }
1608
1609 VBOXVDBG_DUMP_PRESENT_LEAVE(pDevice, pSwapchain);
1610
1611 pSwapchain->bRTFbCopyUpToDate = FALSE;
1612 vboxWddmSwapchainFlip(pSwapchain);
1613 Assert(!pSwapchain->fFlags.bChanged);
1614 Assert(!pSwapchain->fFlags.bSwitchReportingPresent);
1615 hr = vboxWddmSwapchainSynch(pDevice, pSwapchain);
1616 Assert(hr == S_OK);
1617 return hr;
1618}
1619
1620static HRESULT vboxWddmSwapchainPresent(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pBbAlloc)
1621{
1622 /* we currently *assume* that presenting shared resource is only possible when 3d app is rendering with composited desktop on,
1623 * no need to do anything else since dwm will present everything for us */
1624 if (pBbAlloc->hSharedHandle)
1625 {
1626 VBOXVDBG_ASSERT_IS_DWM(FALSE);
1627
1628 HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
1629 Assert(hr == S_OK);
1630
1631 vboxWddmDalNotifyChange(pDevice);
1632
1633 return S_OK;
1634 }
1635
1636 VBOXVDBG_ASSERT_IS_DWM(TRUE);
1637
1638 BOOL bNeedPresent;
1639 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainFindCreate(pDevice, pBbAlloc, &bNeedPresent);
1640 Assert(pSwapchain);
1641 if (!bNeedPresent)
1642 return S_OK;
1643 if (pSwapchain)
1644 {
1645 HRESULT hr = vboxWddmSwapchainChkCreateIf(pDevice, pSwapchain);
1646 Assert(hr == S_OK);
1647 if (hr == S_OK)
1648 {
1649 hr = vboxWddmSwapchainPresentPerform(pDevice, pSwapchain);
1650 Assert(hr == S_OK);
1651 }
1652 return hr;
1653 }
1654 return E_OUTOFMEMORY;
1655}
1656
1657#if 0 //def DEBUG
1658static void vboxWddmDbgRenderTargetUpdateCheckSurface(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t iBBuf)
1659{
1660 IDirect3DSurface9 *pD3D9Surf;
1661 Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
1662 IDirect3DDevice9 * pDevice9If = pDevice->aScreens[pDevice->iPrimaryScreen].pDevice9If;
1663 HRESULT hr = pDevice9If->GetBackBuffer(0 /*UINT iSwapChain*/,
1664 iBBuf, D3DBACKBUFFER_TYPE_MONO, &pD3D9Surf);
1665 Assert(hr == S_OK);
1666 if (hr == S_OK)
1667 {
1668 Assert(pD3D9Surf);
1669 Assert(pD3D9Surf == pAlloc->pD3DIf);
1670 pD3D9Surf->Release();
1671 }
1672}
1673
1674static void vboxWddmDbgRenderTargetCheck(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_RESOURCE pRc, uint32_t iNewRTFB)
1675{
1676 PVBOXWDDMDISP_ALLOCATION pAlloc;
1677 UINT iBBuf = 0;
1678 Assert(iNewRTFB < pRc->cAllocations);
1679
1680 for (UINT i = 1; i < pRc->cAllocations; ++i, ++iBBuf)
1681 {
1682 UINT iAlloc = (iNewRTFB + i) % pRc->cAllocations;
1683 Assert(iAlloc != iNewRTFB);
1684 pAlloc = &pRc->aAllocations[iAlloc];
1685 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, iBBuf);
1686 }
1687
1688 pAlloc = &pRc->aAllocations[iNewRTFB];
1689#ifdef VBOXWDDM_WITH_VISIBLE_FB
1690 vboxWddmDbgRenderTargetUpdateCheckSurface(pDevice, pAlloc, ~0UL /* <- for the frontbuffer */);
1691#else
1692 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
1693#endif
1694
1695 for (UINT i = 0; i < pRc->cAllocations; ++i)
1696 {
1697 pAlloc = &pRc->aAllocations[i];
1698 if (iNewRTFB == i)
1699 {
1700 Assert((!pAlloc->pD3DIf) == (pRc->cAllocations > 1));
1701 }
1702
1703 for (UINT j = i+1; j < pRc->cAllocations; ++j)
1704 {
1705 PVBOXWDDMDISP_ALLOCATION pAllocJ = &pRc->aAllocations[j];
1706 Assert(pAlloc->pD3DIf != pAllocJ->pD3DIf);
1707 }
1708 }
1709}
1710
1711# define VBOXVDBG_RTGT_STATECHECK(_pDev) (vboxWddmDbgRenderTargetCheck((_pDev), (_pDev)->aScreens[(_pDev)->iPrimaryScreen].pRenderTargetRc, (_pDev)->aScreens[(_pDev)->iPrimaryScreen].iRenderTargetFrontBuf))
1712#else
1713# define VBOXVDBG_RTGT_STATECHECK(_pDev) do{}while(0)
1714#endif
1715
1716/******/
1717
1718static HRESULT vboxWddmRenderTargetSet(PVBOXWDDMDISP_DEVICE pDevice, UINT iRt, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOL bOnSwapchainSynch)
1719{
1720 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
1721 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
1722 HRESULT hr = S_OK;
1723 IDirect3DSurface9 *pD3D9Surf;
1724 if (pSwapchain)
1725 {
1726 hr = vboxWddmSwapchainRtSurfGet(pDevice, pSwapchain, iRt, pAlloc, bOnSwapchainSynch, &pD3D9Surf);
1727 if (FAILED(hr))
1728 {
1729 WARN(("vboxWddmSwapchainRtSurfGet failed, hr(0x%x)",hr));
1730 return hr;
1731 }
1732 }
1733 else
1734 {
1735 hr = VBoxD3DIfSurfGet(pAlloc->pRc, pAlloc->iAlloc, &pD3D9Surf);
1736 if (FAILED(hr))
1737 {
1738 WARN(("VBoxD3DIfSurfGet failed, hr(0x%x)",hr));
1739 return hr;
1740 }
1741 }
1742
1743 Assert(pD3D9Surf);
1744
1745 hr = pDevice9If->SetRenderTarget(iRt, pD3D9Surf);
1746 Assert(hr == S_OK);
1747 if (hr == S_OK)
1748 {
1749 Assert(iRt < pDevice->cRTs);
1750 pDevice->apRTs[iRt] = pAlloc;
1751 }
1752 pD3D9Surf->Release();
1753
1754 return hr;
1755}
1756
1757/**
1758 * DLL entry point.
1759 */
1760BOOL WINAPI DllMain(HINSTANCE hInstance,
1761 DWORD dwReason,
1762 LPVOID lpReserved)
1763{
1764 switch (dwReason)
1765 {
1766 case DLL_PROCESS_ATTACH:
1767 {
1768 vboxDispLockInit();
1769
1770 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
1771#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
1772 vboxVDbgVEHandlerRegister();
1773#endif
1774 int rc = RTR3InitDll(0);
1775 AssertRC(rc);
1776 if (RT_SUCCESS(rc))
1777 {
1778// rc = VbglR3Init();
1779// AssertRC(rc);
1780// if (RT_SUCCESS(rc))
1781 {
1782 HRESULT hr = vboxDispCmInit();
1783 Assert(hr == S_OK);
1784 if (hr == S_OK)
1785 {
1786 hr = vboxDispMpInternalInit();
1787 Assert(hr == S_OK);
1788 if (hr == S_OK)
1789 {
1790 VBoxDispD3DGlobalInit();
1791 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
1792 return TRUE;
1793 }
1794 }
1795// VbglR3Term();
1796 }
1797 }
1798
1799#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
1800 vboxVDbgVEHandlerUnregister();
1801#endif
1802 break;
1803 }
1804
1805 case DLL_PROCESS_DETACH:
1806 {
1807#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
1808 vboxVDbgVEHandlerUnregister();
1809#endif
1810 HRESULT hr = vboxDispMpInternalTerm();
1811 Assert(hr == S_OK);
1812 if (hr == S_OK)
1813 {
1814 hr = vboxDispCmTerm();
1815 Assert(hr == S_OK);
1816 if (hr == S_OK)
1817 {
1818// VbglR3Term();
1819 /// @todo RTR3Term();
1820 VBoxDispD3DGlobalTerm();
1821 return TRUE;
1822 }
1823 }
1824
1825 break;
1826 }
1827
1828 default:
1829 return TRUE;
1830 }
1831 return FALSE;
1832}
1833
1834static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
1835{
1836 VBOXDISP_DDI_PROLOGUE_ADP(hAdapter);
1837
1838 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
1839
1840 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
1841
1842 HRESULT hr = S_OK;
1843 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
1844
1845 switch (pData->Type)
1846 {
1847 case D3DDDICAPS_DDRAW:
1848 {
1849 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1850 Assert(pData->DataSize == sizeof (DDRAW_CAPS));
1851 if (pData->DataSize >= sizeof (DDRAW_CAPS))
1852 {
1853 memset(pData->pData, 0, sizeof (DDRAW_CAPS));
1854#ifdef VBOX_WITH_VIDEOHWACCEL
1855 if (!VBOXDISPMODE_IS_3D(pAdapter))
1856 {
1857 if (vboxVhwaHasCKeying(pAdapter))
1858 {
1859 DDRAW_CAPS *pCaps = (DDRAW_CAPS*)pData->pData;
1860 pCaps->Caps |= DDRAW_CAPS_COLORKEY;
1861 // pCaps->Caps2 |= DDRAW_CAPS2_FLIPNOVSYNC;
1862 }
1863 }
1864 else
1865 {
1866 WARN(("D3DDDICAPS_DDRAW query for D3D mode!"));
1867 }
1868#endif
1869 }
1870 else
1871 hr = E_INVALIDARG;
1872 break;
1873 }
1874 case D3DDDICAPS_DDRAW_MODE_SPECIFIC:
1875 {
1876 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1877 Assert(pData->DataSize == sizeof (DDRAW_MODE_SPECIFIC_CAPS));
1878 if (pData->DataSize >= sizeof (DDRAW_MODE_SPECIFIC_CAPS))
1879 {
1880 DDRAW_MODE_SPECIFIC_CAPS * pCaps = (DDRAW_MODE_SPECIFIC_CAPS*)pData->pData;
1881 memset(&pCaps->Caps /* do not cleanup the first "Head" field,
1882 zero starting with the one following "Head", i.e. Caps */,
1883 0, sizeof (DDRAW_MODE_SPECIFIC_CAPS) - RT_OFFSETOF(DDRAW_MODE_SPECIFIC_CAPS, Caps));
1884#ifdef VBOX_WITH_VIDEOHWACCEL
1885 if (!VBOXDISPMODE_IS_3D(pAdapter))
1886 {
1887 VBOXVHWA_INFO *pSettings = &pAdapter->aHeads[pCaps->Head].Vhwa.Settings;
1888 if (pSettings->fFlags & VBOXVHWA_F_ENABLED)
1889 {
1890 pCaps->Caps |= MODE_CAPS_OVERLAY | MODE_CAPS_OVERLAYSTRETCH;
1891
1892 if (pSettings->fFlags & VBOXVHWA_F_CKEY_DST)
1893 {
1894 pCaps->CKeyCaps |= MODE_CKEYCAPS_DESTOVERLAY
1895 | MODE_CKEYCAPS_DESTOVERLAYYUV /* ?? */
1896 ;
1897 }
1898
1899 if (pSettings->fFlags & VBOXVHWA_F_CKEY_SRC)
1900 {
1901 pCaps->CKeyCaps |= MODE_CKEYCAPS_SRCOVERLAY
1902 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACE /* ?? */
1903 | MODE_CKEYCAPS_SRCOVERLAYCLRSPACEYUV /* ?? */
1904 | MODE_CKEYCAPS_SRCOVERLAYYUV /* ?? */
1905 ;
1906 }
1907
1908 pCaps->FxCaps = MODE_FXCAPS_OVERLAYSHRINKX
1909 | MODE_FXCAPS_OVERLAYSHRINKY
1910 | MODE_FXCAPS_OVERLAYSTRETCHX
1911 | MODE_FXCAPS_OVERLAYSTRETCHY;
1912
1913
1914 pCaps->MaxVisibleOverlays = pSettings->cOverlaysSupported;
1915 pCaps->MinOverlayStretch = 1;
1916 pCaps->MaxOverlayStretch = 32000;
1917 }
1918 }
1919 else
1920 {
1921 WARN(("D3DDDICAPS_DDRAW_MODE_SPECIFIC query for D3D mode!"));
1922 }
1923#endif
1924 }
1925 else
1926 hr = E_INVALIDARG;
1927 break;
1928 }
1929 case D3DDDICAPS_GETFORMATCOUNT:
1930 *((uint32_t*)pData->pData) = pAdapter->Formats.cFormstOps;
1931 break;
1932 case D3DDDICAPS_GETFORMATDATA:
1933 Assert(pData->DataSize == pAdapter->Formats.cFormstOps * sizeof (FORMATOP));
1934 memcpy(pData->pData, pAdapter->Formats.paFormstOps, pAdapter->Formats.cFormstOps * sizeof (FORMATOP));
1935 break;
1936 case D3DDDICAPS_GETD3DQUERYCOUNT:
1937#if 1
1938 *((uint32_t*)pData->pData) = VBOX_QUERYTYPE_COUNT();
1939#else
1940 *((uint32_t*)pData->pData) = 0;
1941#endif
1942 break;
1943 case D3DDDICAPS_GETD3DQUERYDATA:
1944#if 1
1945 Assert(pData->DataSize == VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
1946 memcpy(pData->pData, gVBoxQueryTypes, VBOX_QUERYTYPE_COUNT() * sizeof (D3DDDIQUERYTYPE));
1947#else
1948 Assert(0);
1949 memset(pData->pData, 0, pData->DataSize);
1950#endif
1951 break;
1952 case D3DDDICAPS_GETD3D3CAPS:
1953 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
1954 Assert(pData->DataSize == sizeof (D3DHAL_GLOBALDRIVERDATA));
1955 if (pData->DataSize >= sizeof (D3DHAL_GLOBALDRIVERDATA))
1956 {
1957 D3DHAL_GLOBALDRIVERDATA *pCaps = (D3DHAL_GLOBALDRIVERDATA *)pData->pData;
1958 memset (pCaps, 0, sizeof (D3DHAL_GLOBALDRIVERDATA));
1959 pCaps->dwSize = sizeof (D3DHAL_GLOBALDRIVERDATA);
1960 pCaps->hwCaps.dwSize = sizeof (D3DDEVICEDESC_V1);
1961 pCaps->hwCaps.dwFlags = D3DDD_COLORMODEL
1962 | D3DDD_DEVCAPS
1963 | D3DDD_DEVICERENDERBITDEPTH;
1964
1965 pCaps->hwCaps.dcmColorModel = D3DCOLOR_RGB;
1966 pCaps->hwCaps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP
1967// | D3DDEVCAPS_DRAWPRIMTLVERTEX
1968 | D3DDEVCAPS_EXECUTESYSTEMMEMORY
1969 | D3DDEVCAPS_EXECUTEVIDEOMEMORY
1970// | D3DDEVCAPS_FLOATTLVERTEX
1971 | D3DDEVCAPS_HWRASTERIZATION
1972// | D3DDEVCAPS_HWTRANSFORMANDLIGHT
1973// | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY
1974// | D3DDEVCAPS_TEXTUREVIDEOMEMORY
1975 ;
1976 pCaps->hwCaps.dtcTransformCaps.dwSize = sizeof (D3DTRANSFORMCAPS);
1977 pCaps->hwCaps.dtcTransformCaps.dwCaps = 0;
1978 pCaps->hwCaps.bClipping = FALSE;
1979 pCaps->hwCaps.dlcLightingCaps.dwSize = sizeof (D3DLIGHTINGCAPS);
1980 pCaps->hwCaps.dlcLightingCaps.dwCaps = 0;
1981 pCaps->hwCaps.dlcLightingCaps.dwLightingModel = 0;
1982 pCaps->hwCaps.dlcLightingCaps.dwNumLights = 0;
1983 pCaps->hwCaps.dpcLineCaps.dwSize = sizeof (D3DPRIMCAPS);
1984 pCaps->hwCaps.dpcLineCaps.dwMiscCaps = 0;
1985 pCaps->hwCaps.dpcLineCaps.dwRasterCaps = 0;
1986 pCaps->hwCaps.dpcLineCaps.dwZCmpCaps = 0;
1987 pCaps->hwCaps.dpcLineCaps.dwSrcBlendCaps = 0;
1988 pCaps->hwCaps.dpcLineCaps.dwDestBlendCaps = 0;
1989 pCaps->hwCaps.dpcLineCaps.dwAlphaCmpCaps = 0;
1990 pCaps->hwCaps.dpcLineCaps.dwShadeCaps = 0;
1991 pCaps->hwCaps.dpcLineCaps.dwTextureCaps = 0;
1992 pCaps->hwCaps.dpcLineCaps.dwTextureFilterCaps = 0;
1993 pCaps->hwCaps.dpcLineCaps.dwTextureBlendCaps = 0;
1994 pCaps->hwCaps.dpcLineCaps.dwTextureAddressCaps = 0;
1995 pCaps->hwCaps.dpcLineCaps.dwStippleWidth = 0;
1996 pCaps->hwCaps.dpcLineCaps.dwStippleHeight = 0;
1997
1998 pCaps->hwCaps.dpcTriCaps.dwSize = sizeof (D3DPRIMCAPS);
1999 pCaps->hwCaps.dpcTriCaps.dwMiscCaps = 0;
2000 pCaps->hwCaps.dpcTriCaps.dwRasterCaps = 0;
2001 pCaps->hwCaps.dpcTriCaps.dwZCmpCaps = 0;
2002 pCaps->hwCaps.dpcTriCaps.dwSrcBlendCaps = 0;
2003 pCaps->hwCaps.dpcTriCaps.dwDestBlendCaps = 0;
2004 pCaps->hwCaps.dpcTriCaps.dwAlphaCmpCaps = 0;
2005 pCaps->hwCaps.dpcTriCaps.dwShadeCaps = 0;
2006 pCaps->hwCaps.dpcTriCaps.dwTextureCaps = 0;
2007 pCaps->hwCaps.dpcTriCaps.dwTextureFilterCaps = 0;
2008 pCaps->hwCaps.dpcTriCaps.dwTextureBlendCaps = 0;
2009 pCaps->hwCaps.dpcTriCaps.dwTextureAddressCaps = 0;
2010 pCaps->hwCaps.dpcTriCaps.dwStippleWidth = 0;
2011 pCaps->hwCaps.dpcTriCaps.dwStippleHeight = 0;
2012 pCaps->hwCaps.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32;
2013 pCaps->hwCaps.dwDeviceZBufferBitDepth = 0;
2014 pCaps->hwCaps.dwMaxBufferSize = 0;
2015 pCaps->hwCaps.dwMaxVertexCount = 0;
2016
2017
2018 pCaps->dwNumVertices = 0;
2019 pCaps->dwNumClipVertices = 0;
2020 pCaps->dwNumTextureFormats = 0;//pAdapter->cSurfDescs;
2021 pCaps->lpTextureFormats = NULL;//pAdapter->paSurfDescs;
2022 }
2023 else
2024 hr = E_INVALIDARG;
2025 break;
2026 case D3DDDICAPS_GETD3D7CAPS:
2027 Assert(!VBOXDISPMODE_IS_3D(pAdapter));
2028 Assert(pData->DataSize == sizeof (D3DHAL_D3DEXTENDEDCAPS));
2029 if (pData->DataSize >= sizeof (D3DHAL_D3DEXTENDEDCAPS))
2030 {
2031 memset(pData->pData, 0, sizeof (D3DHAL_D3DEXTENDEDCAPS));
2032 D3DHAL_D3DEXTENDEDCAPS *pCaps = (D3DHAL_D3DEXTENDEDCAPS*)pData->pData;
2033 pCaps->dwSize = sizeof (D3DHAL_D3DEXTENDEDCAPS);
2034 }
2035 else
2036 hr = E_INVALIDARG;
2037 break;
2038 case D3DDDICAPS_GETD3D9CAPS:
2039 {
2040 Assert(pData->DataSize == sizeof (D3DCAPS9));
2041 if (pData->DataSize >= sizeof (D3DCAPS9))
2042 {
2043 Assert(VBOXDISPMODE_IS_3D(pAdapter));
2044 if (VBOXDISPMODE_IS_3D(pAdapter))
2045 {
2046 memcpy(pData->pData, &pAdapter->D3D.Caps, sizeof (D3DCAPS9));
2047 hr = S_OK;
2048 break;
2049 }
2050
2051 memset(pData->pData, 0, sizeof (D3DCAPS9));
2052 }
2053 else
2054 hr = E_INVALIDARG;
2055 break;
2056 }
2057 case D3DDDICAPS_GETD3D8CAPS:
2058 {
2059 Assert(pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2));
2060 if (pData->DataSize == RT_OFFSETOF(D3DCAPS9, DevCaps2))
2061 {
2062 Assert(VBOXDISPMODE_IS_3D(pAdapter));
2063 if (VBOXDISPMODE_IS_3D(pAdapter))
2064 {
2065 memcpy(pData->pData, &pAdapter->D3D.Caps, RT_OFFSETOF(D3DCAPS9, DevCaps2));
2066 hr = S_OK;
2067 break;
2068 }
2069 }
2070 else
2071 hr = E_INVALIDARG;
2072 break;
2073 }
2074 case D3DDDICAPS_GETGAMMARAMPCAPS:
2075 *((uint32_t*)pData->pData) = 0;
2076 break;
2077 case D3DDDICAPS_GETVIDEOPROCESSORCAPS:
2078 case D3DDDICAPS_GETEXTENSIONGUIDCOUNT:
2079 case D3DDDICAPS_GETDECODEGUIDCOUNT:
2080 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDCOUNT:
2081 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATCOUNT:
2082 if (pData->pData && pData->DataSize)
2083 memset(pData->pData, 0, pData->DataSize);
2084 break;
2085 case D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS:
2086 case D3DDDICAPS_GETD3D5CAPS:
2087 case D3DDDICAPS_GETD3D6CAPS:
2088 case D3DDDICAPS_GETDECODEGUIDS:
2089 case D3DDDICAPS_GETDECODERTFORMATCOUNT:
2090 case D3DDDICAPS_GETDECODERTFORMATS:
2091 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFOCOUNT:
2092 case D3DDDICAPS_GETDECODECOMPRESSEDBUFFERINFO:
2093 case D3DDDICAPS_GETDECODECONFIGURATIONCOUNT:
2094 case D3DDDICAPS_GETDECODECONFIGURATIONS:
2095 case D3DDDICAPS_GETVIDEOPROCESSORDEVICEGUIDS:
2096 case D3DDDICAPS_GETVIDEOPROCESSORRTFORMATS:
2097 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT:
2098 case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS:
2099 case D3DDDICAPS_GETPROCAMPRANGE:
2100 case D3DDDICAPS_FILTERPROPERTYRANGE:
2101 case D3DDDICAPS_GETEXTENSIONGUIDS:
2102 case D3DDDICAPS_GETEXTENSIONCAPS:
2103 vboxVDbgPrint((__FUNCTION__": unimplemented caps type(%d)\n", pData->Type));
2104 Assert(0);
2105 if (pData->pData && pData->DataSize)
2106 memset(pData->pData, 0, pData->DataSize);
2107 break;
2108 default:
2109 vboxVDbgPrint((__FUNCTION__": unknown caps type(%d)\n", pData->Type));
2110 Assert(0);
2111 }
2112
2113 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
2114
2115 return S_OK;
2116}
2117
2118static HRESULT APIENTRY vboxWddmDDevSetRenderState(HANDLE hDevice, CONST D3DDDIARG_RENDERSTATE* pData)
2119{
2120 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2121 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2122 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2123 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2124 Assert(pDevice);
2125 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2126 HRESULT hr = pDevice9If->SetRenderState(vboxDDI2D3DRenderStateType(pData->State), pData->Value);
2127 Assert(hr == S_OK);
2128 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2129 return hr;
2130}
2131
2132static HRESULT APIENTRY vboxWddmDDevUpdateWInfo(HANDLE hDevice, CONST D3DDDIARG_WINFO* pData)
2133{
2134 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2135// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2136// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2137 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2138 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2139 return S_OK;
2140}
2141
2142static HRESULT APIENTRY vboxWddmDDevValidateDevice(HANDLE hDevice, D3DDDIARG_VALIDATETEXTURESTAGESTATE* pData)
2143{
2144 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2145// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2146// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2147 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2148#ifdef DEBUG_misha
2149 /* @todo: check if it's ok to always return success */
2150 vboxVDbgPrint((__FUNCTION__": @todo: check if it's ok to always return success\n"));
2151 Assert(0);
2152#endif
2153 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2154 return S_OK;
2155}
2156
2157static HRESULT APIENTRY vboxWddmDDevSetTextureStageState(HANDLE hDevice, CONST D3DDDIARG_TEXTURESTAGESTATE* pData)
2158{
2159 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2160 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2161 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2162 Assert(pDevice);
2163 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2164 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2165
2166 VBOXWDDMDISP_TSS_LOOKUP lookup = vboxDDI2D3DTestureStageStateType(pData->State);
2167 HRESULT hr;
2168
2169 if (!lookup.bSamplerState)
2170 {
2171 hr = pDevice9If->SetTextureStageState(pData->Stage, D3DTEXTURESTAGESTATETYPE(lookup.dType), pData->Value);
2172 }
2173 else
2174 {
2175 hr = pDevice9If->SetSamplerState(pData->Stage, D3DSAMPLERSTATETYPE(lookup.dType), pData->Value);
2176 }
2177
2178 Assert(hr == S_OK);
2179 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2180 return hr;
2181}
2182
2183static HRESULT APIENTRY vboxWddmDDevSetTexture(HANDLE hDevice, UINT Stage, HANDLE hTexture)
2184{
2185 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2186 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2187 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2188 Assert(pDevice);
2189 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2190 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2191 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hTexture;
2192// Assert(pRc);
2193 IDirect3DBaseTexture9 *pD3DIfTex;
2194 if (pRc)
2195 {
2196 VBOXVDBG_CHECK_SMSYNC(pRc);
2197 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE)
2198 {
2199 pD3DIfTex = (IDirect3DTexture9*)pRc->aAllocations[0].pD3DIf;
2200
2201 VBOXVDBG_BREAK_SHARED(pRc);
2202 VBOXVDBG_DUMP_SETTEXTURE(pRc);
2203 }
2204 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE)
2205 {
2206 pD3DIfTex = (IDirect3DCubeTexture9*)pRc->aAllocations[0].pD3DIf;
2207
2208 VBOXVDBG_BREAK_SHARED(pRc);
2209 VBOXVDBG_DUMP_SETTEXTURE(pRc);
2210 }
2211 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
2212 {
2213 pD3DIfTex = (IDirect3DVolumeTexture9*)pRc->aAllocations[0].pD3DIf;
2214
2215 VBOXVDBG_BREAK_SHARED(pRc);
2216 VBOXVDBG_DUMP_SETTEXTURE(pRc);
2217 }
2218 else
2219 {
2220 Assert(0);
2221 }
2222
2223 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2224 int idx = VBOXWDDMDISP_SAMPLER_IDX(Stage);
2225 if (idx >= 0)
2226 {
2227 Assert(idx < RT_ELEMENTS(pDevice->aSamplerTextures));
2228#ifdef DEBUG_misha
2229 if (VBOXWDDMDISP_SAMPLER_IDX_IS_SPECIAL(Stage))
2230 {
2231 WARN(("non-zero special sampler index not tested!\n"));
2232 }
2233#endif
2234 if (!pDevice->aSamplerTextures[idx])
2235 {
2236 ++pDevice->cSamplerTextures;
2237 }
2238 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2239 pDevice->aSamplerTextures[idx] = pRc;
2240 }
2241 else
2242 {
2243 WARN(("incorrect dampler index1! (%d)\n", Stage));
2244 }
2245 }
2246 else
2247 {
2248 pD3DIfTex = NULL;
2249 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2250 int idx = VBOXWDDMDISP_SAMPLER_IDX(Stage);
2251 if (idx >= 0)
2252 {
2253 Assert(idx < RT_ELEMENTS(pDevice->aSamplerTextures));
2254 if (pDevice->aSamplerTextures[idx])
2255 {
2256 Assert(pDevice->cSamplerTextures);
2257 --pDevice->cSamplerTextures;
2258 }
2259 Assert(pDevice->cSamplerTextures < RT_ELEMENTS(pDevice->aSamplerTextures));
2260 pDevice->aSamplerTextures[idx] = NULL;
2261 }
2262 else
2263 {
2264 WARN(("incorrect dampler index2! (%d)\n", Stage));
2265 }
2266 }
2267
2268 HRESULT hr = pDevice9If->SetTexture(Stage, pD3DIfTex);
2269 Assert(hr == S_OK);
2270 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2271 return hr;
2272}
2273
2274static HRESULT APIENTRY vboxWddmDDevSetPixelShader(HANDLE hDevice, HANDLE hShaderHandle)
2275{
2276 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2277 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2278 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2279 Assert(pDevice);
2280 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2281 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2282 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
2283 HRESULT hr = pDevice9If->SetPixelShader(pShader);
2284 Assert(hr == S_OK);
2285 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2286 return hr;
2287}
2288
2289static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONST* pData, CONST FLOAT* pRegisters)
2290{
2291 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2292 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2293 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2294 Assert(pDevice);
2295 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2296 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2297 HRESULT hr = pDevice9If->SetPixelShaderConstantF(pData->Register, pRegisters, pData->Count);
2298 Assert(hr == S_OK);
2299 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2300 return hr;
2301}
2302
2303static HRESULT APIENTRY vboxWddmDDevSetStreamSourceUm(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEUM* pData, CONST VOID* pUMBuffer )
2304{
2305 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2306 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2307 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2308 Assert(pDevice);
2309 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2310 HRESULT hr = S_OK;
2311
2312 Assert(pData->Stream < RT_ELEMENTS(pDevice->aStreamSourceUm));
2313 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
2314 if (pStrSrcUm->pvBuffer && !pUMBuffer)
2315 {
2316 --pDevice->cStreamSourcesUm;
2317 Assert(pDevice->cStreamSourcesUm < UINT32_MAX/2);
2318 }
2319 else if (!pStrSrcUm->pvBuffer && pUMBuffer)
2320 {
2321 ++pDevice->cStreamSourcesUm;
2322 Assert(pDevice->cStreamSourcesUm <= RT_ELEMENTS(pDevice->aStreamSourceUm));
2323 }
2324
2325 pStrSrcUm->pvBuffer = pUMBuffer;
2326 pStrSrcUm->cbStride = pData->Stride;
2327
2328 if (pDevice->aStreamSource[pData->Stream])
2329 {
2330 hr = pDevice->pDevice9If->SetStreamSource(pData->Stream, NULL, 0, 0);
2331 --pDevice->cStreamSources;
2332 Assert(pDevice->cStreamSources < UINT32_MAX/2);
2333 pDevice->aStreamSource[pData->Stream] = NULL;
2334 }
2335
2336 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2337 return hr;
2338}
2339
2340static HRESULT APIENTRY vboxWddmDDevSetIndices(HANDLE hDevice, CONST D3DDDIARG_SETINDICES* pData)
2341{
2342 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2343 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2344 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2345 Assert(pDevice);
2346 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2347
2348 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2349 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hIndexBuffer;
2350 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
2351 IDirect3DIndexBuffer9 *pIndexBuffer = NULL;
2352 if (pRc)
2353 {
2354 VBOXVDBG_CHECK_SMSYNC(pRc);
2355 Assert(pRc->cAllocations == 1);
2356 pAlloc = &pRc->aAllocations[0];
2357 Assert(pAlloc->pD3DIf);
2358 pIndexBuffer = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
2359 }
2360 HRESULT hr = pDevice9If->SetIndices(pIndexBuffer);
2361 Assert(hr == S_OK);
2362 if (hr == S_OK)
2363 {
2364 pDevice->IndiciesInfo.pIndicesAlloc = pAlloc;
2365 pDevice->IndiciesInfo.uiStride = pData->Stride;
2366 pDevice->IndiciesInfo.pvIndicesUm = NULL;
2367 }
2368 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2369 return hr;
2370}
2371
2372static HRESULT APIENTRY vboxWddmDDevSetIndicesUm(HANDLE hDevice, UINT IndexSize, CONST VOID* pUMBuffer)
2373{
2374 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2375 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2376 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2377 Assert(pDevice);
2378 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2379
2380 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2381
2382 HRESULT hr = S_OK;
2383 if (pDevice->IndiciesInfo.pIndicesAlloc)
2384 {
2385 hr = pDevice9If->SetIndices(NULL);
2386 }
2387
2388 if (SUCCEEDED(hr))
2389 {
2390 pDevice->IndiciesInfo.pvIndicesUm = pUMBuffer;
2391 pDevice->IndiciesInfo.uiStride = IndexSize;
2392 pDevice->IndiciesInfo.pIndicesAlloc = NULL;
2393 hr = S_OK;
2394 }
2395 else
2396 {
2397 WARN(("SetIndices failed hr 0x%x", hr));
2398 }
2399
2400 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2401 return hr;
2402}
2403
2404static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE* pData, CONST UINT* pFlagBuffer)
2405{
2406 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2407 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2408 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2409 Assert(pDevice);
2410 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2411
2412 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2413 Assert(!pFlagBuffer);
2414 HRESULT hr = S_OK;
2415
2416 VBOXVDBG_BREAK_SHARED_DEV(pDevice);
2417
2418 VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
2419
2420 if (!pDevice->cStreamSources)
2421 {
2422 if (pDevice->aStreamSourceUm[0].pvBuffer)
2423 {
2424#ifdef DEBUG
2425 for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2426 {
2427 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
2428 }
2429#endif
2430 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
2431 pData->PrimitiveCount,
2432 ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
2433 pDevice->aStreamSourceUm[0].cbStride);
2434 Assert(hr == S_OK);
2435
2436// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
2437 }
2438 else
2439 {
2440 /* todo: impl */
2441 Assert(0);
2442 }
2443 }
2444 else
2445 {
2446
2447#ifdef DEBUG
2448 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2449 {
2450 Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
2451 }
2452
2453 uint32_t cStreams = 0;
2454 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2455 {
2456 if (pDevice->aStreamSource[i])
2457 {
2458 ++cStreams;
2459 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2460 }
2461 }
2462
2463 Assert(cStreams);
2464 Assert(cStreams == pDevice->cStreamSources);
2465#endif
2466 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType,
2467 pData->VStart,
2468 pData->PrimitiveCount);
2469 Assert(hr == S_OK);
2470
2471// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitive\n"));
2472 }
2473
2474 vboxWddmDalCheckAddRtsSamplers(pDevice);
2475
2476 VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
2477
2478 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2479 return hr;
2480}
2481
2482static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE* pData)
2483{
2484 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2485 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2486 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2487 Assert(pDevice);
2488 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2489
2490 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2491
2492 VBOXVDBG_BREAK_SHARED_DEV(pDevice);
2493
2494 VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
2495
2496
2497#ifdef DEBUG
2498 uint32_t cStreams = 0;
2499 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2500 {
2501 if(pDevice->aStreamSourceUm[i].pvBuffer)
2502 ++cStreams;
2503 }
2504
2505 Assert(cStreams == pDevice->cStreamSourcesUm);
2506
2507 cStreams = 0;
2508
2509 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSource); ++i)
2510 {
2511 if (pDevice->aStreamSource[i])
2512 {
2513 ++cStreams;
2514 Assert(!pDevice->aStreamSource[i]->LockInfo.cLocks);
2515 }
2516 }
2517
2518 Assert(cStreams == pDevice->cStreamSources);
2519#endif
2520
2521 HRESULT hr;
2522
2523 if (pDevice->cStreamSources)
2524 {
2525 Assert(pDevice->IndiciesInfo.pIndicesAlloc);
2526 Assert(!pDevice->IndiciesInfo.pvIndicesUm);
2527 Assert(!pDevice->IndiciesInfo.pIndicesAlloc->LockInfo.cLocks);
2528 Assert(!pDevice->cStreamSourcesUm);
2529
2530 hr = pDevice9If->DrawIndexedPrimitive(
2531 pData->PrimitiveType,
2532 pData->BaseVertexIndex,
2533 pData->MinIndex,
2534 pData->NumVertices,
2535 pData->StartIndex,
2536 pData->PrimitiveCount);
2537
2538 if(SUCCEEDED(hr))
2539 hr = S_OK;
2540 else
2541 WARN(("DrawIndexedPrimitive failed hr = 0x%x", hr));
2542 }
2543 else
2544 {
2545 Assert(pDevice->cStreamSourcesUm == 1);
2546 Assert(pDevice->IndiciesInfo.uiStride == 2 || pDevice->IndiciesInfo.uiStride == 4);
2547 const uint8_t * pvIndexBuffer;
2548 hr = S_OK;
2549
2550 if (pDevice->IndiciesInfo.pIndicesAlloc)
2551 {
2552 Assert(!pDevice->IndiciesInfo.pvIndicesUm);
2553 if (pDevice->IndiciesInfo.pIndicesAlloc->pvMem)
2554 pvIndexBuffer = (const uint8_t*)pDevice->IndiciesInfo.pIndicesAlloc->pvMem;
2555 else
2556 {
2557 WARN(("not expected!"));
2558 hr = E_FAIL;
2559 pvIndexBuffer = NULL;
2560 }
2561 }
2562 else
2563 {
2564 pvIndexBuffer = (const uint8_t*)pDevice->IndiciesInfo.pvIndicesUm;
2565 if (!pvIndexBuffer)
2566 {
2567 WARN(("not expected!"));
2568 hr = E_FAIL;
2569 }
2570 }
2571
2572 if (SUCCEEDED(hr))
2573 {
2574 for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
2575 {
2576 if(pDevice->aStreamSourceUm[i].pvBuffer)
2577 {
2578 hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
2579 pData->MinIndex,
2580 pData->NumVertices,
2581 pData->PrimitiveCount,
2582 pvIndexBuffer + pDevice->IndiciesInfo.uiStride * pData->StartIndex,
2583 pDevice->IndiciesInfo.uiStride == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
2584 pDevice->aStreamSourceUm[i].pvBuffer,
2585 pDevice->aStreamSourceUm[i].cbStride);
2586 if(SUCCEEDED(hr))
2587 {
2588 if (pDevice->IndiciesInfo.pIndicesAlloc)
2589 {
2590 HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
2591 if(!SUCCEEDED(tmpHr))
2592 WARN(("SetIndices failed hr = 0x%x", tmpHr));
2593 }
2594
2595 hr = S_OK;
2596 }
2597 else
2598 WARN(("DrawIndexedPrimitiveUP failed hr = 0x%x", hr));
2599 break;
2600 }
2601 }
2602 }
2603 }
2604
2605 vboxWddmDalCheckAddRtsSamplers(pDevice);
2606
2607 VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
2608
2609 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2610 return hr;
2611}
2612
2613static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWRECTPATCH* pData, CONST D3DDDIRECTPATCH_INFO* pInfo, CONST FLOAT* pPatch)
2614{
2615 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2616 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2617 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2618 Assert(pDevice);
2619 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2620 Assert(0);
2621 vboxWddmDalCheckAddRtsSamplers(pDevice);
2622 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2623 return E_FAIL;
2624}
2625
2626static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG_DRAWTRIPATCH* pData, CONST D3DDDITRIPATCH_INFO* pInfo, CONST FLOAT* pPatch)
2627{
2628 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2629 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2630 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2631 Assert(pDevice);
2632 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2633 Assert(0);
2634 vboxWddmDalCheckAddRtsSamplers(pDevice);
2635 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2636 return E_FAIL;
2637}
2638
2639static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWPRIMITIVE2* pData)
2640{
2641 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2642 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2643 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2644 Assert(pDevice);
2645 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2646
2647 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2648 HRESULT hr;
2649
2650#if 0
2651 int stream;
2652 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
2653 {
2654 if (pDevice->aStreamSource[stream] && pDevice->aStreamSource[stream]->LockInfo.cLocks)
2655 {
2656 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
2657 if (pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite))
2658 {
2659 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf;
2660 Assert(pLock->fFlags.RangeValid);
2661 pD3D9VBuf->Lock(pLock->Range.Offset, pLock->Range.Size,
2662 &pLock->LockedRect.pBits,
2663 vboxDDI2D3DLockFlags(pLock->fFlags));
2664 RECT r;
2665 r.top = 0;
2666 r.left = pLock->Range.Offset;
2667 r.bottom = 1;
2668 r.right = pLock->Range.Offset + pLock->Range.Size;
2669
2670 VBoxD3DIfLockUnlockMemSynch(pDevice->aStreamSource[stream], &pLock->LockedRect, &r, true /*bool bToLockInfo*/);
2671
2672 pD3D9VBuf->Unlock();
2673 }
2674 }
2675 }
2676
2677 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset, pData->PrimitiveCount);
2678#else
2679 VBOXVDBG_BREAK_SHARED_DEV(pDevice);
2680
2681 VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
2682
2683#ifdef DEBUG
2684 uint32_t cStreams = 0;
2685#endif
2686
2687 int stream;
2688 for (stream=0; stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS; ++stream)
2689 {
2690 if (pDevice->aStreamSource[stream])
2691 {
2692#ifdef DEBUG
2693 ++cStreams;
2694#endif
2695 Assert(stream==0); /*only stream 0 should be accessed here*/
2696 Assert(pDevice->StreamSourceInfo[stream].uiStride!=0);
2697 VBOXWDDMDISP_LOCKINFO *pLock = &pDevice->aStreamSource[stream]->LockInfo;
2698
2699 if (pLock->cLocks)
2700 {
2701// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
2702
2703 Assert(pLock->fFlags.MightDrawFromLocked && (pLock->fFlags.Discard || pLock->fFlags.NoOverwrite));
2704 hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType, pData->PrimitiveCount,
2705 (void*)((uintptr_t)pDevice->aStreamSource[stream]->pvMem+pDevice->StreamSourceInfo[stream].uiOffset+pData->FirstVertexOffset),
2706 pDevice->StreamSourceInfo[stream].uiStride);
2707 Assert(hr == S_OK);
2708 hr = pDevice9If->SetStreamSource(stream, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[stream]->pD3DIf, pDevice->StreamSourceInfo[stream].uiOffset, pDevice->StreamSourceInfo[stream].uiStride);
2709 Assert(hr == S_OK);
2710 }
2711 else
2712 {
2713// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitive\n"));
2714
2715 hr = pDevice9If->DrawPrimitive(pData->PrimitiveType, pData->FirstVertexOffset/pDevice->StreamSourceInfo[stream].uiStride, pData->PrimitiveCount);
2716 Assert(hr == S_OK);
2717 }
2718 }
2719 }
2720
2721#ifdef DEBUG
2722 Assert(cStreams);
2723 Assert(cStreams == pDevice->cStreamSources);
2724#endif
2725#endif
2726
2727 vboxWddmDalCheckAddRtsSamplers(pDevice);
2728
2729 VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
2730
2731 Assert(hr == S_OK);
2732 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2733 return hr;
2734}
2735
2736static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST D3DDDIARG_DRAWINDEXEDPRIMITIVE2* pData, UINT dwIndicesSize, CONST VOID* pIndexBuffer, CONST UINT* pFlagBuffer)
2737{
2738 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2739 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2740 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2741 Assert(pDevice);
2742 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2743 HRESULT hr = S_OK;
2744 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2745 const uint8_t *pvVertexBuffer = NULL;
2746 DWORD cbVertexStride = 0;
2747
2748 if (dwIndicesSize != 2 && dwIndicesSize != 4)
2749 WARN(("unsupported dwIndicesSize %d", dwIndicesSize));
2750
2751 if (pDevice->aStreamSourceUm[0].pvBuffer)
2752 {
2753 Assert(pDevice->aStreamSourceUm[0].cbStride);
2754
2755 pvVertexBuffer = (const uint8_t *)pDevice->aStreamSourceUm[0].pvBuffer;
2756 cbVertexStride = pDevice->aStreamSourceUm[0].cbStride;
2757 }
2758 else if (pDevice->aStreamSource[0])
2759 {
2760 PVBOXWDDMDISP_ALLOCATION pAlloc = pDevice->aStreamSource[0];
2761 if (pAlloc->pvMem)
2762 {
2763 Assert(pDevice->StreamSourceInfo[0].uiStride);
2764 pvVertexBuffer = ((const uint8_t *)pAlloc->pvMem) + pDevice->StreamSourceInfo[0].uiOffset;
2765 cbVertexStride = pDevice->StreamSourceInfo[0].uiStride;
2766 }
2767 else
2768 {
2769 WARN(("unsupported!!"));
2770 hr = E_FAIL;
2771 }
2772 }
2773 else
2774 {
2775 WARN(("not expected!"));
2776 hr = E_FAIL;
2777 }
2778
2779 if (SUCCEEDED(hr))
2780 {
2781 pvVertexBuffer = pvVertexBuffer + pData->BaseVertexOffset /* * cbVertexStride */;
2782
2783 hr = pDevice9If->DrawIndexedPrimitiveUP(pData->PrimitiveType,
2784 pData->MinIndex,
2785 pData->NumVertices,
2786 pData->PrimitiveCount,
2787 ((uint8_t*)pIndexBuffer) + dwIndicesSize * pData->StartIndexOffset,
2788 dwIndicesSize == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32,
2789 pvVertexBuffer,
2790 cbVertexStride);
2791 if(SUCCEEDED(hr))
2792 hr = S_OK;
2793 else
2794 WARN(("DrawIndexedPrimitiveUP failed hr = 0x%x", hr));
2795
2796 if (pDevice->aStreamSource[0])
2797 {
2798 HRESULT tmpHr = pDevice9If->SetStreamSource(0, (IDirect3DVertexBuffer9*)pDevice->aStreamSource[0]->pD3DIf, pDevice->StreamSourceInfo[0].uiOffset, pDevice->StreamSourceInfo[0].uiStride);
2799 if(!SUCCEEDED(tmpHr))
2800 WARN(("SetStreamSource failed hr = 0x%x", tmpHr));
2801 }
2802
2803 if (pDevice->IndiciesInfo.pIndicesAlloc)
2804 {
2805 HRESULT tmpHr = pDevice9If->SetIndices((IDirect3DIndexBuffer9*)pDevice->IndiciesInfo.pIndicesAlloc->pD3DIf);
2806 if(!SUCCEEDED(tmpHr))
2807 WARN(("SetIndices failed hr = 0x%x", tmpHr));
2808 }
2809 }
2810
2811 vboxWddmDalCheckAddRtsSamplers(pDevice);
2812 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2813 return hr;
2814}
2815
2816AssertCompile(sizeof (D3DDDIBOX) == sizeof (VBOXBOX3D));
2817AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Left) == RT_SIZEOFMEMB(VBOXBOX3D, Left));
2818AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Top) == RT_SIZEOFMEMB(VBOXBOX3D, Top));
2819AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Right) == RT_SIZEOFMEMB(VBOXBOX3D, Right));
2820AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Bottom) == RT_SIZEOFMEMB(VBOXBOX3D, Bottom));
2821AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Front) == RT_SIZEOFMEMB(VBOXBOX3D, Front));
2822AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Back) == RT_SIZEOFMEMB(VBOXBOX3D, Back));
2823
2824AssertCompile(RT_OFFSETOF(D3DDDIBOX, Left) == RT_OFFSETOF(VBOXBOX3D, Left));
2825AssertCompile(RT_OFFSETOF(D3DDDIBOX, Top) == RT_OFFSETOF(VBOXBOX3D, Top));
2826AssertCompile(RT_OFFSETOF(D3DDDIBOX, Right) == RT_OFFSETOF(VBOXBOX3D, Right));
2827AssertCompile(RT_OFFSETOF(D3DDDIBOX, Bottom) == RT_OFFSETOF(VBOXBOX3D, Bottom));
2828AssertCompile(RT_OFFSETOF(D3DDDIBOX, Front) == RT_OFFSETOF(VBOXBOX3D, Front));
2829AssertCompile(RT_OFFSETOF(D3DDDIBOX, Back) == RT_OFFSETOF(VBOXBOX3D, Back));
2830
2831static HRESULT APIENTRY vboxWddmDDevVolBlt(HANDLE hDevice, CONST D3DDDIARG_VOLUMEBLT* pData)
2832{
2833 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2834 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2835 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2836 Assert(pDevice);
2837 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2838 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2839 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
2840 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
2841 /* requirements for D3DDevice9::UpdateTexture */
2842 Assert(pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2843 Assert(pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2844 IDirect3DVolumeTexture9 * pSrcTex = (IDirect3DVolumeTexture9*)pSrcRc->aAllocations[0].pD3DIf;
2845 IDirect3DVolumeTexture9 * pDstTex = (IDirect3DVolumeTexture9*)pDstRc->aAllocations[0].pD3DIf;
2846 VBOXPOINT3D Point;
2847 Point.x = pData->DstX;
2848 Point.y = pData->DstY;
2849 Point.z = pData->DstZ;
2850
2851 HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9VolTexBlt((IDirect3DDevice9Ex*)pDevice9If, pSrcTex, pDstTex,
2852 (VBOXBOX3D*)&pData->SrcBox, &Point);
2853 if (FAILED(hr))
2854 WARN(("pfnVBoxWineExD3DDev9VolTexBlt failed hr 0x%x", hr));
2855 else
2856 hr = S_OK;
2857 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2858 return hr;;
2859}
2860
2861static HRESULT APIENTRY vboxWddmDDevBufBlt(HANDLE hDevice, CONST D3DDDIARG_BUFFERBLT* pData)
2862{
2863 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2864 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2865 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2866 Assert(pDevice);
2867 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2868 Assert(0);
2869// @todo: vboxWddmDalCheckAdd(pDevice);
2870 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2871 return E_FAIL;
2872}
2873
2874static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBLT* pData)
2875{
2876 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2877 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2878 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2879 Assert(pDevice);
2880 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2881 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2882 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
2883 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
2884 /* requirements for D3DDevice9::UpdateTexture */
2885 Assert(pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
2886 || pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
2887 || pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2888 Assert(pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
2889 || pSrcRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
2890 || pDstRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2891 Assert(pSrcRc->aAllocations[0].enmD3DIfType == pDstRc->aAllocations[0].enmD3DIfType);
2892 Assert(pSrcRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
2893 Assert(pDstRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM);
2894 HRESULT hr = S_OK;
2895 VBOXVDBG_CHECK_SMSYNC(pDstRc);
2896 VBOXVDBG_CHECK_SMSYNC(pSrcRc);
2897
2898 if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
2899 && pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
2900 && pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
2901 &&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
2902 && pData->SrcRect.left == 0 && pData->SrcRect.top == 0
2903 && pData->SrcRect.right - pData->SrcRect.left == pSrcRc->aAllocations[0].SurfDesc.width
2904 && pData->SrcRect.bottom - pData->SrcRect.top == pSrcRc->aAllocations[0].SurfDesc.height)
2905 {
2906 IDirect3DBaseTexture9 *pD3DIfSrcTex = (IDirect3DBaseTexture9*)pSrcRc->aAllocations[0].pD3DIf;
2907 IDirect3DBaseTexture9 *pD3DIfDstTex = (IDirect3DBaseTexture9*)pDstRc->aAllocations[0].pD3DIf;
2908 Assert(pD3DIfSrcTex);
2909 Assert(pD3DIfDstTex);
2910 VBOXVDBG_CHECK_TEXBLT(
2911 hr = pDevice9If->UpdateTexture(pD3DIfSrcTex, pD3DIfDstTex); Assert(hr == S_OK),
2912 pSrcRc,
2913 &pData->SrcRect,
2914 pDstRc,
2915 &pData->DstPoint);
2916 }
2917 else
2918 {
2919 Assert(pDstRc->aAllocations[0].enmD3DIfType != VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2920 Assert(pSrcRc->aAllocations[0].enmD3DIfType != VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE);
2921
2922 IDirect3DSurface9 *pSrcSurfIf = NULL;
2923 IDirect3DSurface9 *pDstSurfIf = NULL;
2924 hr = VBoxD3DIfSurfGet(pDstRc, 0, &pDstSurfIf);
2925 Assert(hr == S_OK);
2926 if (hr == S_OK)
2927 {
2928 hr = VBoxD3DIfSurfGet(pSrcRc, 0, &pSrcSurfIf);
2929 Assert(hr == S_OK);
2930 if (hr == S_OK)
2931 {
2932 RECT DstRect;
2933 vboxWddmRectMoved(&DstRect, &pData->SrcRect, pData->DstPoint.x, pData->DstPoint.y);
2934#ifdef DEBUG
2935 RECT tstRect = {0,0, pDstRc->aAllocations[0].SurfDesc.width, pDstRc->aAllocations[0].SurfDesc.height};
2936 Assert(vboxWddmRectIsCoveres(&tstRect, &DstRect));
2937#endif
2938 VBOXVDBG_CHECK_TEXBLT(
2939 hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &DstRect, D3DTEXF_NONE); Assert(hr == S_OK),
2940 pSrcRc,
2941 &pData->SrcRect,
2942 pDstRc,
2943 &pData->DstPoint);
2944 pSrcSurfIf->Release();
2945 }
2946 pDstSurfIf->Release();
2947 }
2948 }
2949
2950 vboxWddmDalCheckAddRc(pDevice, pDstRc, TRUE);
2951 vboxWddmDalCheckAddRc(pDevice, pSrcRc, FALSE);
2952
2953 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
2954 return hr;
2955}
2956
2957static HRESULT APIENTRY vboxWddmDDevStateSet(HANDLE hDevice, D3DDDIARG_STATESET* pData)
2958{
2959 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2960 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2961 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2962 Assert(pDevice);
2963 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2964 Assert(0);
2965 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2966 return E_FAIL;
2967}
2968static HRESULT APIENTRY vboxWddmDDevSetPriority(HANDLE hDevice, CONST D3DDDIARG_SETPRIORITY* pData)
2969{
2970 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2971// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2972// Assert(pDevice);
2973// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2974 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2975 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2976 return S_OK;
2977}
2978AssertCompile(sizeof (RECT) == sizeof (D3DRECT));
2979AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DRECT, x1));
2980AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DRECT, x2));
2981AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DRECT, y1));
2982AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DRECT, y2));
2983AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DRECT, x1));
2984AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DRECT, x2));
2985AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DRECT, y1));
2986AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DRECT, y2));
2987
2988static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR* pData, UINT NumRect, CONST RECT* pRect)
2989{
2990 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
2991 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
2992 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
2993 Assert(pDevice);
2994 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
2995 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
2996 HRESULT hr = pDevice9If->Clear(NumRect, (D3DRECT*)pRect /* see AssertCompile above */,
2997 pData->Flags,
2998 pData->FillColor,
2999 pData->FillDepth,
3000 pData->FillStencil);
3001 Assert(hr == S_OK);
3002 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3003 return hr;
3004}
3005static HRESULT APIENTRY vboxWddmDDevUpdatePalette(HANDLE hDevice, CONST D3DDDIARG_UPDATEPALETTE* pData, CONST PALETTEENTRY* pPaletteData)
3006{
3007 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3008 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3009 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3010 Assert(pDevice);
3011 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3012 Assert(0);
3013 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3014 return E_FAIL;
3015}
3016
3017static HRESULT APIENTRY vboxWddmDDevSetPalette(HANDLE hDevice, CONST D3DDDIARG_SETPALETTE* pData)
3018{
3019 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3020 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3021 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3022 Assert(pDevice);
3023 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3024 Assert(0);
3025 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3026 return E_FAIL;
3027}
3028
3029static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConst(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONST* pData , CONST VOID* pRegisters)
3030{
3031 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3032 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3033 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3034 Assert(pDevice);
3035 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3036 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3037 HRESULT hr = pDevice9If->SetVertexShaderConstantF(
3038 pData->Register,
3039 (CONST float*)pRegisters,
3040 pData->Count);
3041 Assert(hr == S_OK);
3042 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3043 return hr;
3044}
3045static HRESULT APIENTRY vboxWddmDDevMultiplyTransform(HANDLE hDevice, CONST D3DDDIARG_MULTIPLYTRANSFORM* pData)
3046{
3047 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3048 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3049 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3050 Assert(pDevice);
3051 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3052 Assert(0);
3053 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3054 return E_FAIL;
3055}
3056static HRESULT APIENTRY vboxWddmDDevSetTransform(HANDLE hDevice, CONST D3DDDIARG_SETTRANSFORM* pData)
3057{
3058 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3059 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3060 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3061 Assert(pDevice);
3062 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3063 Assert(0);
3064 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3065 return E_FAIL;
3066}
3067static HRESULT APIENTRY vboxWddmDDevSetViewport(HANDLE hDevice, CONST D3DDDIARG_VIEWPORTINFO* pData)
3068{
3069 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3070 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3071 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3072 Assert(pDevice);
3073 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3074
3075 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3076 pDevice->ViewPort.X = pData->X;
3077 pDevice->ViewPort.Y = pData->Y;
3078 pDevice->ViewPort.Width = pData->Width;
3079 pDevice->ViewPort.Height = pData->Height;
3080 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3081 Assert(hr == S_OK);
3082 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3083 return hr;
3084}
3085static HRESULT APIENTRY vboxWddmDDevSetZRange(HANDLE hDevice, CONST D3DDDIARG_ZRANGE* pData)
3086{
3087 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3088 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3089 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3090 Assert(pDevice);
3091 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3092
3093 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3094 pDevice->ViewPort.MinZ = pData->MinZ;
3095 pDevice->ViewPort.MaxZ = pData->MaxZ;
3096 HRESULT hr = pDevice9If->SetViewport(&pDevice->ViewPort);
3097 Assert(hr == S_OK);
3098 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3099 return hr;
3100}
3101static HRESULT APIENTRY vboxWddmDDevSetMaterial(HANDLE hDevice, CONST D3DDDIARG_SETMATERIAL* pData)
3102{
3103 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3104 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3105 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3106 Assert(pDevice);
3107 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3108 Assert(0);
3109 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3110 return E_FAIL;
3111}
3112static HRESULT APIENTRY vboxWddmDDevSetLight(HANDLE hDevice, CONST D3DDDIARG_SETLIGHT* pData, CONST D3DDDI_LIGHT* pLightProperties)
3113{
3114 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3115 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3116 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3117 Assert(pDevice);
3118 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3119 Assert(0);
3120 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3121 return E_FAIL;
3122}
3123static HRESULT APIENTRY vboxWddmDDevCreateLight(HANDLE hDevice, CONST D3DDDIARG_CREATELIGHT* pData)
3124{
3125 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3126 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3127 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3128 Assert(pDevice);
3129 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3130 Assert(0);
3131 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3132 return E_FAIL;
3133}
3134static HRESULT APIENTRY vboxWddmDDevDestroyLight(HANDLE hDevice, CONST D3DDDIARG_DESTROYLIGHT* pData)
3135{
3136 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3137 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3138 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3139 Assert(pDevice);
3140 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3141 Assert(0);
3142 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3143 return E_FAIL;
3144}
3145static HRESULT APIENTRY vboxWddmDDevSetClipPlane(HANDLE hDevice, CONST D3DDDIARG_SETCLIPPLANE* pData)
3146{
3147 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3148 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3149 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3150 Assert(pDevice);
3151 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3152
3153 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
3154 HRESULT hr = pDevice9If->SetClipPlane(pData->Index, pData->Plane);
3155 Assert(hr == S_OK);
3156 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3157 return hr;
3158}
3159
3160static HRESULT APIENTRY vboxWddmDDevGetInfo(HANDLE hDevice, UINT DevInfoID, VOID* pDevInfoStruct, UINT DevInfoSize)
3161{
3162 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3163 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3164// PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3165// Assert(pDevice);
3166// VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3167 HRESULT hr = S_OK;
3168 switch (DevInfoID)
3169 {
3170 case D3DDDIDEVINFOID_VCACHE:
3171 {
3172 Assert(DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE));
3173 if (DevInfoSize == sizeof (D3DDDIDEVINFO_VCACHE))
3174 {
3175 D3DDDIDEVINFO_VCACHE *pVCache = (D3DDDIDEVINFO_VCACHE*)pDevInfoStruct;
3176 pVCache->Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
3177 pVCache->OptMethod = 0 /* D3DXMESHOPT_STRIPREORDER */;
3178 pVCache->CacheSize = 0;
3179 pVCache->MagicNumber = 0;
3180 }
3181 else
3182 hr = E_INVALIDARG;
3183 break;
3184 }
3185 default:
3186 Assert(0);
3187 hr = E_NOTIMPL;
3188 }
3189 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
3190 return hr;
3191}
3192
3193AssertCompile(sizeof (D3DDDIBOX) == sizeof (D3DBOX));
3194AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Left) == RT_SIZEOFMEMB(D3DBOX, Left));
3195AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Top) == RT_SIZEOFMEMB(D3DBOX, Top));
3196AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Right) == RT_SIZEOFMEMB(D3DBOX, Right));
3197AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Bottom) == RT_SIZEOFMEMB(D3DBOX, Bottom));
3198AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Front) == RT_SIZEOFMEMB(D3DBOX, Front));
3199AssertCompile(RT_SIZEOFMEMB(D3DDDIBOX, Back) == RT_SIZEOFMEMB(D3DBOX, Back));
3200
3201AssertCompile(RT_OFFSETOF(D3DDDIBOX, Left) == RT_OFFSETOF(D3DBOX, Left));
3202AssertCompile(RT_OFFSETOF(D3DDDIBOX, Top) == RT_OFFSETOF(D3DBOX, Top));
3203AssertCompile(RT_OFFSETOF(D3DDDIBOX, Right) == RT_OFFSETOF(D3DBOX, Right));
3204AssertCompile(RT_OFFSETOF(D3DDDIBOX, Bottom) == RT_OFFSETOF(D3DBOX, Bottom));
3205AssertCompile(RT_OFFSETOF(D3DDDIBOX, Front) == RT_OFFSETOF(D3DBOX, Front));
3206AssertCompile(RT_OFFSETOF(D3DDDIBOX, Back) == RT_OFFSETOF(D3DBOX, Back));
3207
3208static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
3209{
3210 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3211 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3212 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3213 Assert(pDevice);
3214 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3215 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3216 Assert(pData->SubResourceIndex < pRc->cAllocations);
3217 if (pData->SubResourceIndex >= pRc->cAllocations)
3218 return E_INVALIDARG;
3219
3220 HRESULT hr = S_OK;
3221
3222 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
3223 {
3224// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
3225
3226 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
3227 || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
3228 || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE)
3229 {
3230 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3231 Assert(pData->SubResourceIndex < pRc->cAllocations);
3232 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3233 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
3234 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pTexAlloc->pD3DIf;
3235 IDirect3DSurface9 *pD3DIfSurface = (IDirect3DSurface9*)pTexAlloc->pD3DIf;
3236 Assert(pTexAlloc->pD3DIf);
3237 RECT *pRect = NULL;
3238 BOOL fNeedLock = TRUE;
3239 Assert(!pData->Flags.RangeValid);
3240 Assert(!pData->Flags.BoxValid);
3241 if (pData->Flags.AreaValid)
3242 {
3243 pRect = &pData->Area;
3244 }
3245
3246 /* else - we lock the entire texture, pRect == NULL */
3247
3248 if (pLockAlloc->LockInfo.cLocks)
3249 {
3250 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
3251 if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
3252 {
3253 Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
3254 Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
3255 Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
3256 Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
3257 }
3258 Assert(pLockAlloc->LockInfo.LockedRect.pBits);
3259 Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
3260
3261 if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
3262 {
3263 switch (pTexAlloc->enmD3DIfType)
3264 {
3265 case VBOXDISP_D3DIFTYPE_TEXTURE:
3266 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
3267 break;
3268 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
3269 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
3270 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex));
3271 break;
3272 case VBOXDISP_D3DIFTYPE_SURFACE:
3273 hr = pD3DIfSurface->UnlockRect();
3274 break;
3275 default:
3276 Assert(0);
3277 break;
3278 }
3279 Assert(hr == S_OK);
3280 }
3281 else
3282 {
3283 fNeedLock = FALSE;
3284 }
3285 }
3286
3287 if (fNeedLock && SUCCEEDED(hr))
3288 {
3289 VBOXVDBG_CHECK_SMSYNC(pRc);
3290
3291 pLockAlloc->LockInfo.fFlags = pData->Flags;
3292 if (pRect)
3293 {
3294 pLockAlloc->LockInfo.Area = *pRect;
3295 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
3296 }
3297 else
3298 {
3299 Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
3300 }
3301
3302 switch (pTexAlloc->enmD3DIfType)
3303 {
3304 case VBOXDISP_D3DIFTYPE_TEXTURE:
3305 hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
3306 &pLockAlloc->LockInfo.LockedRect,
3307 pRect,
3308 vboxDDI2D3DLockFlags(pData->Flags));
3309 break;
3310 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
3311 hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
3312 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex),
3313 &pLockAlloc->LockInfo.LockedRect,
3314 pRect,
3315 vboxDDI2D3DLockFlags(pData->Flags));
3316 break;
3317 case VBOXDISP_D3DIFTYPE_SURFACE:
3318 hr = pD3DIfSurface->LockRect(&pLockAlloc->LockInfo.LockedRect,
3319 pRect,
3320 vboxDDI2D3DLockFlags(pData->Flags));
3321 break;
3322 default:
3323 Assert(0);
3324 break;
3325 }
3326
3327 if (FAILED(hr))
3328 {
3329 WARN(("LockRect failed, hr", hr));
3330 }
3331 }
3332
3333 if (SUCCEEDED(hr))
3334 {
3335 ++pLockAlloc->LockInfo.cLocks;
3336
3337 if (!pData->Flags.NotifyOnly)
3338 {
3339 pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
3340 pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
3341 pData->SlicePitch = 0;
3342 Assert(pLockAlloc->SurfDesc.slicePitch == 0);
3343 Assert(!pLockAlloc->pvMem);
3344 }
3345 else
3346 {
3347 Assert(pLockAlloc->pvMem);
3348 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3349 }
3350
3351 VBOXVDBG_DUMP_LOCK_ST(pData);
3352
3353 hr = S_OK;
3354 }
3355 }
3356 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
3357 {
3358 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3359 Assert(pData->SubResourceIndex < pRc->cAllocations);
3360 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3361 IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pTexAlloc->pD3DIf;
3362 Assert(pTexAlloc->pD3DIf);
3363 D3DDDIBOX *pBox = NULL;
3364 BOOL fNeedLock = TRUE;
3365 Assert(!pData->Flags.AreaValid);
3366 Assert(!pData->Flags.BoxValid);
3367 if (pData->Flags.BoxValid)
3368 {
3369 pBox = &pData->Box;
3370 }
3371
3372 /* else - we lock the entire texture, pBox == NULL */
3373
3374 if (pLockAlloc->LockInfo.cLocks)
3375 {
3376 Assert(pLockAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid);
3377 if (pLockAlloc->LockInfo.fFlags.BoxValid && pData->Flags.BoxValid)
3378 {
3379 Assert(pLockAlloc->LockInfo.Box.Left == pData->Box.Left);
3380 Assert(pLockAlloc->LockInfo.Box.Top == pData->Box.Top);
3381 Assert(pLockAlloc->LockInfo.Box.Right == pData->Box.Right);
3382 Assert(pLockAlloc->LockInfo.Box.Bottom == pData->Box.Bottom);
3383 Assert(pLockAlloc->LockInfo.Box.Front == pData->Box.Front);
3384 Assert(pLockAlloc->LockInfo.Box.Back == pData->Box.Back);
3385 }
3386 Assert(pLockAlloc->LockInfo.LockedBox.pBits);
3387 Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
3388
3389 if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
3390 {
3391 hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex);
3392 Assert(hr == S_OK);
3393 }
3394 else
3395 {
3396 fNeedLock = FALSE;
3397 }
3398 }
3399
3400 if (fNeedLock && SUCCEEDED(hr))
3401 {
3402 VBOXVDBG_CHECK_SMSYNC(pRc);
3403
3404 pLockAlloc->LockInfo.fFlags = pData->Flags;
3405 if (pBox)
3406 {
3407 pLockAlloc->LockInfo.Box = *pBox;
3408 Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 1);
3409 }
3410 else
3411 {
3412 Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 0);
3413 }
3414
3415 hr = pD3DIfTex->LockBox(pData->SubResourceIndex,
3416 &pLockAlloc->LockInfo.LockedBox,
3417 (D3DBOX*)pBox,
3418 vboxDDI2D3DLockFlags(pData->Flags));
3419 if (FAILED(hr))
3420 {
3421 WARN(("LockRect failed, hr", hr));
3422 }
3423 }
3424
3425 if (SUCCEEDED(hr))
3426 {
3427 ++pLockAlloc->LockInfo.cLocks;
3428
3429 if (!pData->Flags.NotifyOnly)
3430 {
3431 pData->pSurfData = pLockAlloc->LockInfo.LockedBox.pBits;
3432 pData->Pitch = pLockAlloc->LockInfo.LockedBox.RowPitch;
3433 pData->SlicePitch = pLockAlloc->LockInfo.LockedBox.SlicePitch;
3434 Assert(!pLockAlloc->pvMem);
3435 }
3436 else
3437 {
3438 Assert(pLockAlloc->pvMem);
3439 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3440 }
3441
3442 VBOXVDBG_DUMP_LOCK_ST(pData);
3443
3444 hr = S_OK;
3445 }
3446 }
3447 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
3448 {
3449 Assert(pData->SubResourceIndex < pRc->cAllocations);
3450 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3451 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
3452 BOOL bLocked = false;
3453 Assert(pD3D9VBuf);
3454 Assert(!pData->Flags.AreaValid);
3455 Assert(!pData->Flags.BoxValid);
3456 D3DDDIRANGE *pRange = NULL;
3457 if (pData->Flags.RangeValid)
3458 {
3459 pRange = &pData->Range;
3460 }
3461
3462 /* else - we lock the entire vertex buffer, pRect == NULL */
3463
3464 if (!pAlloc->LockInfo.cLocks)
3465 {
3466 VBOXVDBG_CHECK_SMSYNC(pRc);
3467 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
3468 {
3469 hr = pD3D9VBuf->Lock(pRange ? pRange->Offset : 0,
3470 pRange ? pRange->Size : 0,
3471 &pAlloc->LockInfo.LockedRect.pBits,
3472 vboxDDI2D3DLockFlags(pData->Flags));
3473 bLocked = true;
3474 }
3475
3476 Assert(hr == S_OK);
3477 if (hr == S_OK)
3478 {
3479 Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
3480 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
3481// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
3482 pAlloc->LockInfo.fFlags = pData->Flags;
3483 if (pRange)
3484 {
3485 pAlloc->LockInfo.Range = *pRange;
3486 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
3487// pAlloc->LockInfo.fFlags.RangeValid = 1;
3488 }
3489 else
3490 {
3491 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
3492// pAlloc->LockInfo.fFlags.RangeValid = 0;
3493 }
3494 }
3495 }
3496 else
3497 {
3498 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
3499 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
3500 {
3501 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
3502 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
3503 }
3504 Assert(pAlloc->LockInfo.LockedRect.pBits);
3505 }
3506
3507 if (hr == S_OK)
3508 {
3509 ++pAlloc->LockInfo.cLocks;
3510
3511 if (!pData->Flags.NotifyOnly)
3512 {
3513 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
3514 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
3515 pData->SlicePitch = 0;
3516 Assert(pAlloc->SurfDesc.slicePitch == 0);
3517 Assert(!pAlloc->pvMem);
3518 }
3519 else
3520 {
3521 Assert(pAlloc->pvMem);
3522 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3523 if (bLocked && !pData->Flags.Discard)
3524 {
3525 RECT r, *pr;
3526 if (pRange)
3527 {
3528 r.top = 0;
3529 r.left = pRange->Offset;
3530 r.bottom = 1;
3531 r.right = pRange->Offset + pRange->Size;
3532 pr = &r;
3533 }
3534 else
3535 pr = NULL;
3536 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
3537 }
3538 }
3539 }
3540 }
3541 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
3542 {
3543 Assert(pData->SubResourceIndex < pRc->cAllocations);
3544 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3545 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3546 BOOL bLocked = false;
3547 Assert(pD3D9IBuf);
3548 Assert(!pData->Flags.AreaValid);
3549 Assert(!pData->Flags.BoxValid);
3550 D3DDDIRANGE *pRange = NULL;
3551 if (pData->Flags.RangeValid)
3552 {
3553 pRange = &pData->Range;
3554 }
3555
3556 /* else - we lock the entire vertex buffer, pRect == NULL */
3557
3558 if (!pAlloc->LockInfo.cLocks)
3559 {
3560 VBOXVDBG_CHECK_SMSYNC(pRc);
3561 if (!pData->Flags.MightDrawFromLocked || (!pData->Flags.Discard && !pData->Flags.NoOverwrite))
3562 {
3563 hr = pD3D9IBuf->Lock(pRange ? pRange->Offset : 0,
3564 pRange ? pRange->Size : 0,
3565 &pAlloc->LockInfo.LockedRect.pBits,
3566 vboxDDI2D3DLockFlags(pData->Flags));
3567 bLocked = true;
3568 }
3569
3570 Assert(hr == S_OK);
3571 if (hr == S_OK)
3572 {
3573 Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
3574 pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
3575// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
3576 pAlloc->LockInfo.fFlags = pData->Flags;
3577 if (pRange)
3578 {
3579 pAlloc->LockInfo.Range = *pRange;
3580 Assert(pAlloc->LockInfo.fFlags.RangeValid == 1);
3581// pAlloc->LockInfo.fFlags.RangeValid = 1;
3582 }
3583 else
3584 {
3585 Assert(pAlloc->LockInfo.fFlags.RangeValid == 0);
3586// pAlloc->LockInfo.fFlags.RangeValid = 0;
3587 }
3588 }
3589 }
3590 else
3591 {
3592 Assert(pAlloc->LockInfo.fFlags.RangeValid == pData->Flags.RangeValid);
3593 if (pAlloc->LockInfo.fFlags.RangeValid && pData->Flags.RangeValid)
3594 {
3595 Assert(pAlloc->LockInfo.Range.Offset == pData->Range.Offset);
3596 Assert(pAlloc->LockInfo.Range.Size == pData->Range.Size);
3597 }
3598 Assert(pAlloc->LockInfo.LockedRect.pBits);
3599 }
3600
3601 if (hr == S_OK)
3602 {
3603 ++pAlloc->LockInfo.cLocks;
3604
3605 if (!pData->Flags.NotifyOnly)
3606 {
3607 pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
3608 pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
3609 pData->SlicePitch = 0;
3610 Assert(pAlloc->SurfDesc.slicePitch == 0);
3611 Assert(!pAlloc->pvMem);
3612 }
3613 else
3614 {
3615 Assert(pAlloc->pvMem);
3616 Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
3617 if (bLocked && !pData->Flags.Discard)
3618 {
3619 RECT r, *pr;
3620 if (pRange)
3621 {
3622 r.top = 0;
3623 r.left = pRange->Offset;
3624 r.bottom = 1;
3625 r.right = pRange->Offset + pRange->Size;
3626 pr = &r;
3627 }
3628 else
3629 pr = NULL;
3630 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect, pr, false /*bool bToLockInfo*/);
3631 }
3632 }
3633 }
3634 }
3635 else
3636 {
3637 Assert(0);
3638 }
3639 }
3640 else /* if !VBOXDISPMODE_IS_3D(pDevice->pAdapter) */
3641 {
3642 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3643 if (pAlloc->hAllocation)
3644 {
3645 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
3646 {
3647 D3DDDICB_LOCK LockData;
3648 LockData.hAllocation = pAlloc->hAllocation;
3649 LockData.PrivateDriverData = 0;
3650 LockData.NumPages = 0;
3651 LockData.pPages = NULL;
3652 LockData.pData = NULL; /* out */
3653 LockData.Flags.Value = 0;
3654 LockData.Flags.Discard = pData->Flags.Discard;
3655 LockData.Flags.DonotWait = pData->Flags.DoNotWait;
3656
3657 uintptr_t offset;
3658 if (pData->Flags.AreaValid)
3659 {
3660 offset = vboxWddmCalcOffXYrd(pData->Area.left, pData->Area.top, pAlloc->SurfDesc.pitch, pAlloc->SurfDesc.format);
3661 }
3662 else if (pData->Flags.RangeValid)
3663 {
3664 offset = pData->Range.Offset;
3665 }
3666 else if (pData->Flags.BoxValid)
3667 {
3668 vboxVDbgPrintF((__FUNCTION__": Implement Box area"));
3669 Assert(0);
3670 }
3671 else
3672 {
3673 offset = 0;
3674 }
3675
3676 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
3677 Assert(hr == S_OK || (hr == D3DERR_WASSTILLDRAWING && pData->Flags.DoNotWait));
3678 if (hr == S_OK)
3679 {
3680 pData->pSurfData = ((uint8_t*)LockData.pData) + offset;
3681 pData->Pitch = pAlloc->SurfDesc.pitch;
3682 pData->SlicePitch = pAlloc->SurfDesc.slicePitch;
3683
3684 if (pData->Flags.Discard)
3685 {
3686 /* check if the surface was renamed */
3687 if (LockData.hAllocation)
3688 pAlloc->hAllocation = LockData.hAllocation;
3689 }
3690 }
3691 }
3692 /* else - d3d may create sysmem render targets and call our Present callbacks for those
3693 * to make it work properly we need to create a VRAM surface corresponding to sysmem one
3694 * and copy stuff to VRAM on lock/unlock
3695 *
3696 * so we don't do any locking here, but still track the lock info here
3697 * and do lock-memcopy-unlock to VRAM surface on sysmem surface unlock
3698 * */
3699
3700 if (hr == S_OK)
3701 {
3702 Assert(!pAlloc->LockInfo.cLocks);
3703
3704 if (!pData->Flags.ReadOnly)
3705 {
3706 if (pData->Flags.AreaValid)
3707 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, &pData->Area);
3708 else
3709 {
3710 Assert(!pData->Flags.RangeValid);
3711 Assert(!pData->Flags.BoxValid);
3712 vboxWddmDirtyRegionAddRect(&pAlloc->DirtyRegion, NULL); /* <- NULL means the entire surface */
3713 }
3714 }
3715
3716 ++pAlloc->LockInfo.cLocks;
3717 }
3718 }
3719 }
3720
3721 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(%d)\n", hDevice, hr));
3722 return hr;
3723}
3724
3725static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOCK* pData)
3726{
3727 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3728 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3729 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3730 Assert(pDevice);
3731 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3732 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
3733 HRESULT hr = S_OK;
3734
3735 Assert(pData->SubResourceIndex < pRc->cAllocations);
3736 if (pData->SubResourceIndex >= pRc->cAllocations)
3737 return E_INVALIDARG;
3738
3739 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
3740 {
3741 if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
3742 || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
3743 || pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE)
3744 {
3745 Assert(pData->SubResourceIndex < pRc->cAllocations);
3746 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3747
3748 VBOXVDBG_DUMP_UNLOCK_ST(pData);
3749
3750 --pLockAlloc->LockInfo.cLocks;
3751 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
3752 if (!pLockAlloc->LockInfo.cLocks)
3753 {
3754 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3755 Assert(pTexAlloc->pD3DIf);
3756 switch (pRc->aAllocations[0].enmD3DIfType)
3757 {
3758 case VBOXDISP_D3DIFTYPE_TEXTURE:
3759 {
3760 IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
3761 hr = pD3DIfTex->UnlockRect(pData->SubResourceIndex);
3762 break;
3763 }
3764 case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
3765 {
3766 IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pTexAlloc->pD3DIf;
3767 hr = pD3DIfCubeTex->UnlockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
3768 VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex));
3769 break;
3770 }
3771 case VBOXDISP_D3DIFTYPE_SURFACE:
3772 {
3773 IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pTexAlloc->pD3DIf;
3774 hr = pD3DIfSurf->UnlockRect();
3775 break;
3776 }
3777 default:
3778 Assert(0);
3779 break;
3780 }
3781 if (FAILED(hr))
3782 WARN(("UnlockRect failed, hr 0x%x", hr));
3783 VBOXVDBG_CHECK_SMSYNC(pRc);
3784 }
3785 }
3786 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
3787 {
3788 Assert(pData->SubResourceIndex < pRc->cAllocations);
3789 PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3790
3791 VBOXVDBG_DUMP_UNLOCK_ST(pData);
3792
3793 --pLockAlloc->LockInfo.cLocks;
3794 Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
3795 if (!pLockAlloc->LockInfo.cLocks)
3796 {
3797 PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
3798 Assert(pTexAlloc->pD3DIf);
3799 IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pTexAlloc->pD3DIf;
3800 hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex);
3801 if (FAILED(hr))
3802 WARN(("UnlockBox failed, hr 0x%x", hr));
3803 VBOXVDBG_CHECK_SMSYNC(pRc);
3804 }
3805 }
3806 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
3807 {
3808 Assert(pData->SubResourceIndex < pRc->cAllocations);
3809 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3810
3811 --pAlloc->LockInfo.cLocks;
3812 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3813 if (!pAlloc->LockInfo.cLocks
3814 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
3815 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
3816 {
3817// Assert(!pAlloc->LockInfo.cLocks);
3818 IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
3819 Assert(pD3D9VBuf);
3820 /* this is a sysmem texture, update */
3821 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
3822 {
3823 RECT r, *pr;
3824 if (pAlloc->LockInfo.fFlags.RangeValid)
3825 {
3826 r.top = 0;
3827 r.left = pAlloc->LockInfo.Range.Offset;
3828 r.bottom = 1;
3829 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
3830 pr = &r;
3831 }
3832 else
3833 pr = NULL;
3834 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
3835 pr,
3836 true /*bool bToLockInfo*/);
3837 }
3838 hr = pD3D9VBuf->Unlock();
3839 Assert(hr == S_OK);
3840 VBOXVDBG_CHECK_SMSYNC(pRc);
3841 }
3842 else
3843 {
3844 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3845 }
3846 }
3847 else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
3848 {
3849 Assert(pData->SubResourceIndex < pRc->cAllocations);
3850 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3851
3852 --pAlloc->LockInfo.cLocks;
3853 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3854 if (!pAlloc->LockInfo.cLocks
3855 && (!pAlloc->LockInfo.fFlags.MightDrawFromLocked
3856 || (!pAlloc->LockInfo.fFlags.Discard && !pAlloc->LockInfo.fFlags.NoOverwrite)))
3857 {
3858// Assert(!pAlloc->LockInfo.cLocks);
3859 IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
3860 Assert(pD3D9IBuf);
3861 /* this is a sysmem texture, update */
3862 if (pAlloc->pvMem && !pAlloc->LockInfo.fFlags.ReadOnly)
3863 {
3864 RECT r, *pr;
3865 if (pAlloc->LockInfo.fFlags.RangeValid)
3866 {
3867 r.top = 0;
3868 r.left = pAlloc->LockInfo.Range.Offset;
3869 r.bottom = 1;
3870 r.right = pAlloc->LockInfo.Range.Offset + pAlloc->LockInfo.Range.Size;
3871 pr = &r;
3872 }
3873 else
3874 pr = NULL;
3875 VBoxD3DIfLockUnlockMemSynch(pAlloc, &pAlloc->LockInfo.LockedRect,
3876 pr,
3877 true /*bool bToLockInfo*/);
3878 }
3879 hr = pD3D9IBuf->Unlock();
3880 Assert(hr == S_OK);
3881 VBOXVDBG_CHECK_SMSYNC(pRc);
3882 }
3883 else
3884 {
3885 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3886 }
3887 }
3888 else
3889 {
3890 Assert(0);
3891 }
3892 }
3893 else
3894 {
3895 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
3896
3897 if (pAlloc->hAllocation)
3898 {
3899 BOOL fDoUnlock = FALSE;
3900
3901 Assert(pAlloc->LockInfo.cLocks);
3902 --pAlloc->LockInfo.cLocks;
3903 Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
3904
3905 if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
3906 {
3907 fDoUnlock = TRUE;
3908 }
3909 else
3910 {
3911 if (!pAlloc->LockInfo.cLocks)
3912 {
3913 D3DDDICB_LOCK LockData;
3914 LockData.hAllocation = pAlloc->hAllocation;
3915 LockData.PrivateDriverData = 0;
3916 LockData.NumPages = 0;
3917 LockData.pPages = NULL;
3918 LockData.pData = NULL; /* out */
3919 LockData.Flags.Value = 0;
3920
3921 hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
3922 if (hr == S_OK)
3923 {
3924 D3DLOCKED_RECT LRect;
3925 LRect.pBits = LockData.pData;
3926 LRect.Pitch = ((pAlloc->SurfDesc.bpp * pAlloc->SurfDesc.width) + 7) >> 3;
3927 Assert(pAlloc->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID);
3928 VBoxD3DIfLockUnlockMemSynch(pAlloc, &LRect, &pAlloc->DirtyRegion.Rect, TRUE /* bool bToLockInfo*/);
3929 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
3930 fDoUnlock = TRUE;
3931 }
3932 else
3933 {
3934 WARN(("pfnLockCb failed, hr 0x%x", hr));
3935 }
3936 }
3937 }
3938
3939 if (fDoUnlock)
3940 {
3941 struct
3942 {
3943 D3DDDICB_UNLOCK Unlock;
3944 D3DKMT_HANDLE hAllocation;
3945 } UnlockData;
3946
3947
3948 UnlockData.Unlock.NumAllocations = 1;
3949 UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
3950 UnlockData.hAllocation = pAlloc->hAllocation;
3951
3952 hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
3953 if(hr != S_OK)
3954 {
3955 WARN(("pfnUnlockCb failed, hr 0x%x", hr));
3956 }
3957 }
3958
3959 if (!SUCCEEDED(hr))
3960 {
3961 WARN(("unlock failure!"));
3962 ++pAlloc->LockInfo.cLocks;
3963 }
3964 }
3965 }
3966
3967 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3968 return hr;
3969}
3970static HRESULT APIENTRY vboxWddmDDevLockAsync(HANDLE hDevice, D3DDDIARG_LOCKASYNC* pData)
3971{
3972 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3973 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3974 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3975 Assert(pDevice);
3976 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3977 Assert(0);
3978 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3979 return E_FAIL;
3980}
3981static HRESULT APIENTRY vboxWddmDDevUnlockAsync(HANDLE hDevice, CONST D3DDDIARG_UNLOCKASYNC* pData)
3982{
3983 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3984 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3985 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3986 Assert(pDevice);
3987 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3988 Assert(0);
3989 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3990 return E_FAIL;
3991}
3992static HRESULT APIENTRY vboxWddmDDevRename(HANDLE hDevice, CONST D3DDDIARG_RENAME* pData)
3993{
3994 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
3995 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
3996 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
3997 Assert(pDevice);
3998 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
3999 Assert(0);
4000 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4001 return E_FAIL;
4002}
4003
4004static void vboxWddmRequestAllocFree(D3DDDICB_ALLOCATE* pAlloc)
4005{
4006 RTMemFree(pAlloc);
4007}
4008
4009static D3DDDICB_ALLOCATE* vboxWddmRequestAllocAlloc(D3DDDIARG_CREATERESOURCE* pResource)
4010{
4011 /* allocate buffer for D3DDDICB_ALLOCATE + D3DDDI_ALLOCATIONINFO * numAllocs + PVBOXWDDM_RCINFO with aAllocInfos[numAllocs] */
4012 uint32_t cbBuf = sizeof (D3DDDICB_ALLOCATE);
4013 uint32_t offDdiAllocInfos = (cbBuf + 7) & ~3;
4014 uint32_t cbDdiAllocInfos = sizeof (D3DDDI_ALLOCATIONINFO) * pResource->SurfCount;
4015 cbBuf = offDdiAllocInfos + cbDdiAllocInfos;
4016 uint32_t offRcInfo = (cbBuf + 7) & ~3;
4017 uint32_t cbRcInfo = sizeof (VBOXWDDM_RCINFO);
4018 cbBuf = offRcInfo + cbRcInfo;
4019 uint32_t offAllocInfos = (cbBuf + 7) & ~3;
4020 uint32_t cbAllocInfos = sizeof (VBOXWDDM_ALLOCINFO) * pResource->SurfCount;
4021 cbBuf = offAllocInfos + cbAllocInfos;
4022 uint8_t *pvBuf = (uint8_t*)RTMemAllocZ(cbBuf);
4023 Assert(pvBuf);
4024 if (pvBuf)
4025 {
4026 D3DDDICB_ALLOCATE* pAlloc = (D3DDDICB_ALLOCATE*)pvBuf;
4027 pAlloc->NumAllocations = pResource->SurfCount;
4028 pAlloc->pAllocationInfo = (D3DDDI_ALLOCATIONINFO*)(pvBuf + offDdiAllocInfos);
4029 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)(pvBuf + offRcInfo);
4030 pAlloc->PrivateDriverDataSize = cbRcInfo;
4031 pAlloc->pPrivateDriverData = pRcInfo;
4032 pAlloc->hResource = pResource->hResource;
4033 PVBOXWDDM_ALLOCINFO pAllocInfos = (PVBOXWDDM_ALLOCINFO)(pvBuf + offAllocInfos);
4034 for (UINT i = 0; i < pResource->SurfCount; ++i)
4035 {
4036 D3DDDI_ALLOCATIONINFO* pDdiAllocInfo = &pAlloc->pAllocationInfo[i];
4037 PVBOXWDDM_ALLOCINFO pAllocInfo = &pAllocInfos[i];
4038 pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
4039 pDdiAllocInfo->PrivateDriverDataSize = sizeof (VBOXWDDM_ALLOCINFO);
4040 }
4041 return pAlloc;
4042 }
4043 return NULL;
4044}
4045
4046static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
4047{
4048 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4049 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4050 HRESULT hr = S_OK;
4051 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4052 Assert(pDevice);
4053 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4054 Assert(pResource);
4055 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
4056
4057 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pResource->SurfCount);
4058 if (!pRc)
4059 {
4060 WARN(("vboxResourceAlloc failed"));
4061 return E_OUTOFMEMORY;
4062 }
4063 bool bIssueCreateResource = false;
4064 bool bCreateKMResource = false;
4065
4066 pRc->hResource = pResource->hResource;
4067 pRc->hKMResource = NULL;
4068 pRc->pDevice = pDevice;
4069 pRc->fFlags.Value = 0;
4070 pRc->fFlags.Generic = 1;
4071 pRc->RcDesc.fFlags = pResource->Flags;
4072 pRc->RcDesc.enmFormat = pResource->Format;
4073 pRc->RcDesc.enmPool = pResource->Pool;
4074 pRc->RcDesc.enmMultisampleType = pResource->MultisampleType;
4075 pRc->RcDesc.MultisampleQuality = pResource->MultisampleQuality;
4076 pRc->RcDesc.MipLevels = pResource->MipLevels;
4077 pRc->RcDesc.Fvf = pResource->Fvf;
4078 pRc->RcDesc.VidPnSourceId = pResource->VidPnSourceId;
4079 pRc->RcDesc.RefreshRate = pResource->RefreshRate;
4080 pRc->RcDesc.enmRotation = pResource->Rotation;
4081 pRc->cAllocations = pResource->SurfCount;
4082 for (UINT i = 0; i < pResource->SurfCount; ++i)
4083 {
4084 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4085 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4086 pAllocation->hAllocation = NULL;
4087 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4088 pAllocation->iAlloc = i;
4089 pAllocation->pRc = pRc;
4090 pAllocation->D3DWidth = pSurf->Width;
4091 pAllocation->pvMem = (void*)pSurf->pSysMem;
4092 pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
4093 pAllocation->SurfDesc.depth = pSurf->Depth;
4094 pAllocation->SurfDesc.width = pSurf->Width;
4095 pAllocation->SurfDesc.height = pSurf->Height;
4096 pAllocation->SurfDesc.format = pResource->Format;
4097 if (!vboxWddmFormatToFourcc(pResource->Format))
4098 pAllocation->SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pResource->Format);
4099 else
4100 pAllocation->SurfDesc.bpp = 0;
4101
4102 if (pSurf->SysMemPitch)
4103 pAllocation->SurfDesc.pitch = pSurf->SysMemPitch;
4104 else
4105 pAllocation->SurfDesc.pitch = vboxWddmCalcPitch(pSurf->Width, pResource->Format);
4106
4107 pAllocation->SurfDesc.cbSize = vboxWddmCalcSize(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.height, pAllocation->SurfDesc.format);
4108
4109 pAllocation->SurfDesc.VidPnSourceId = pResource->VidPnSourceId;
4110
4111 if (pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM)
4112 {
4113 Assert(pAllocation->pvMem);
4114 Assert(pAllocation->SurfDesc.pitch);
4115 UINT minPitch = vboxWddmCalcPitch(pAllocation->SurfDesc.width, pAllocation->SurfDesc.format);
4116 Assert(minPitch);
4117 if (minPitch)
4118 {
4119 if (pAllocation->SurfDesc.pitch != minPitch)
4120 {
4121 Assert(pAllocation->SurfDesc.pitch > minPitch);
4122 pAllocation->D3DWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.format);
4123 Assert(VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags) && !pRc->RcDesc.fFlags.CubeMap); /* <- tested for textures only! */
4124 }
4125 Assert(pAllocation->D3DWidth >= pAllocation->SurfDesc.width);
4126 }
4127 else
4128 {
4129 Assert(pAllocation->D3DWidth == pAllocation->SurfDesc.width);
4130 }
4131 }
4132
4133 }
4134
4135 if (VBOXDISPMODE_IS_3D(pAdapter))
4136 {
4137 if (pRc->RcDesc.fFlags.SharedResource)
4138 {
4139 bIssueCreateResource = true;
4140 bCreateKMResource = true;
4141 }
4142
4143 if (pRc->RcDesc.fFlags.RenderTarget)
4144 {
4145 bIssueCreateResource = true;
4146 }
4147
4148 hr = VBoxD3DIfCreateForRc(pRc);
4149 if (!SUCCEEDED(hr))
4150 {
4151 WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
4152 }
4153 }
4154 else
4155 {
4156 bIssueCreateResource = (pResource->Pool != D3DDDIPOOL_SYSTEMMEM) || pResource->Flags.RenderTarget;
4157 bCreateKMResource = bIssueCreateResource;
4158 }
4159
4160 if (SUCCEEDED(hr) && bIssueCreateResource)
4161 {
4162 pRc->fFlags.KmResource = bCreateKMResource;
4163 D3DDDICB_ALLOCATE *pDdiAllocate = vboxWddmRequestAllocAlloc(pResource);
4164 Assert(pDdiAllocate);
4165 if (pDdiAllocate)
4166 {
4167 Assert(pDdiAllocate->pPrivateDriverData);
4168 Assert(pDdiAllocate->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
4169 PVBOXWDDM_RCINFO pRcInfo = (PVBOXWDDM_RCINFO)pDdiAllocate->pPrivateDriverData;
4170 pRcInfo->fFlags = pRc->fFlags;
4171 pRcInfo->RcDesc = pRc->RcDesc;
4172 pRcInfo->cAllocInfos = pResource->SurfCount;
4173
4174 for (UINT i = 0; i < pResource->SurfCount; ++i)
4175 {
4176 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
4177 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4178 Assert(pDdiAllocI->pPrivateDriverData);
4179 Assert(pDdiAllocI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
4180 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
4181 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4182 pDdiAllocI->hAllocation = NULL;
4183 pDdiAllocI->pSystemMem = pSurf->pSysMem;
4184 Assert((!!(pSurf->pSysMem)) == (pResource->Pool == D3DDDIPOOL_SYSTEMMEM));
4185 pDdiAllocI->VidPnSourceId = pResource->VidPnSourceId;
4186 pDdiAllocI->Flags.Value = 0;
4187 if (pResource->Flags.Primary)
4188 {
4189 Assert(pResource->Flags.RenderTarget);
4190 pDdiAllocI->Flags.Primary = 1;
4191 }
4192
4193 pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4194 pAllocInfo->fFlags = pResource->Flags;
4195 pAllocInfo->hSharedHandle = (uint64_t)pAllocation->hSharedHandle;
4196 pAllocInfo->SurfDesc = pAllocation->SurfDesc;
4197 }
4198
4199 Assert(!pRc->fFlags.Opened);
4200// Assert(!pRc->fFlags.KmResource);
4201 Assert(pRc->fFlags.Generic);
4202
4203 if (bCreateKMResource)
4204 {
4205 Assert(pRc->fFlags.KmResource);
4206
4207 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
4208 Assert(hr == S_OK);
4209 Assert(pDdiAllocate->hKMResource
4210 || pResource->Flags.SharedResource /* for some reason shared resources
4211 * are created with zero km resource handle on Win7+ */
4212 );
4213 }
4214 else
4215 {
4216 Assert(!pRc->fFlags.KmResource);
4217
4218 pDdiAllocate->hResource = NULL;
4219 pDdiAllocate->NumAllocations = 1;
4220 pDdiAllocate->PrivateDriverDataSize = 0;
4221 pDdiAllocate->pPrivateDriverData = NULL;
4222 D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
4223
4224 for (UINT i = 0; i < pResource->SurfCount; ++i)
4225 {
4226 pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
4227 hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
4228 Assert(hr == S_OK);
4229 Assert(!pDdiAllocate->hKMResource);
4230 if (SUCCEEDED(hr))
4231 {
4232 Assert(pDdiAllocate->pAllocationInfo->hAllocation);
4233 }
4234 else
4235 {
4236 for (UINT j = 0; i < j; ++j)
4237 {
4238 D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
4239 D3DDDICB_DEALLOCATE Dealloc;
4240 Dealloc.hResource = 0;
4241 Dealloc.NumAllocations = 1;
4242 Dealloc.HandleList = &pCur->hAllocation;
4243 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
4244 Assert(tmpHr == S_OK);
4245 }
4246 break;
4247 }
4248 }
4249
4250 pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
4251 }
4252
4253 if (SUCCEEDED(hr))
4254 {
4255 pRc->hKMResource = pDdiAllocate->hKMResource;
4256
4257 for (UINT i = 0; i < pResource->SurfCount; ++i)
4258 {
4259 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
4260 D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
4261 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
4262 CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
4263 pAllocation->hAllocation = pDdiAllocI->hAllocation;
4264 pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
4265 pAllocation->pvMem = (void*)pSurf->pSysMem;
4266 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
4267
4268 if (pResource->Flags.SharedResource)
4269 {
4270#ifdef VBOXWDDMDISP_DEBUG_PRINT_SHARED_CREATE
4271 Assert(VBOXWDDMDISP_IS_TEXTURE(pResource->Flags));
4272 vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared CREATED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), "
4273 "Handle(0x%x), (0n%d) \n***********\n\n",
4274 GetCurrentProcessId(), GetCurrentProcessId(),
4275 pAllocation, pRc->hKMResource, pAllocation->hAllocation,
4276 pAllocation->hSharedHandle, pAllocation->hSharedHandle
4277 ));
4278#endif
4279 }
4280 }
4281
4282 VBOXVDBG_CREATE_CHECK_SWAPCHAIN();
4283 }
4284
4285 vboxWddmRequestAllocFree(pDdiAllocate);
4286 }
4287 else
4288 {
4289 hr = E_OUTOFMEMORY;
4290 }
4291 }
4292
4293 VBOXVDBG_BREAK_SHARED(pRc);
4294
4295 if (SUCCEEDED(hr))
4296 {
4297 pResource->hResource = pRc;
4298 hr = S_OK;
4299 }
4300 else
4301 vboxResourceFree(pRc);
4302
4303 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4304 return hr;
4305}
4306
4307static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hResource)
4308{
4309 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4310 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4311 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4312 Assert(pDevice);
4313 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4314 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
4315 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)hResource;
4316
4317 HRESULT hr = S_OK;
4318
4319 Assert(pDevice);
4320 Assert(hResource);
4321
4322 if (VBOXDISPMODE_IS_3D(pAdapter))
4323 {
4324 for (UINT i = 0; i < pRc->cAllocations; ++i)
4325 {
4326 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
4327 if (pAlloc->hSharedHandle)
4328 {
4329#ifdef VBOXWDDMDISP_DEBUG_PRINT_SHARED_CREATE
4330 vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared DESTROYED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), "
4331 "Handle(0x%x), (0n%d) \n***********\n\n",
4332 GetCurrentProcessId(), GetCurrentProcessId(),
4333 pAlloc, pRc->hKMResource, pAlloc->hAllocation,
4334 pAlloc->hSharedHandle, pAlloc->hSharedHandle
4335 ));
4336#endif
4337 }
4338
4339 if (pAlloc->pD3DIf)
4340 pAlloc->pD3DIf->Release();
4341
4342 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
4343 if (pSwapchain)
4344 {
4345 PVBOXWDDMDISP_RENDERTGT pRt = vboxWddmSwapchainRtForAlloc(pSwapchain, pAlloc);
4346 vboxWddmSwapchainRtRemove(pSwapchain, pRt);
4347 Assert(!vboxWddmSwapchainForAlloc(pAlloc));
4348 if (!vboxWddmSwapchainNumRTs(pSwapchain))
4349 vboxWddmSwapchainDestroy(pDevice, pSwapchain);
4350 }
4351
4352 vboxWddmDalCheckRemove(pDevice, pAlloc);
4353 }
4354 }
4355
4356 if (pRc->fFlags.KmResource)
4357 {
4358 D3DDDICB_DEALLOCATE Dealloc;
4359 Assert(pRc->hResource);
4360 Dealloc.hResource = pRc->hResource;
4361 /* according to the docs the below two are ignored in case we set the hResource */
4362 Dealloc.NumAllocations = 0;
4363 Dealloc.HandleList = NULL;
4364 hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
4365 Assert(hr == S_OK);
4366 }
4367 else
4368 {
4369 Assert(!(pRc->fFlags.Opened));
4370 for (UINT j = 0; j < pRc->cAllocations; ++j)
4371 {
4372 if (pRc->aAllocations[j].hAllocation)
4373 {
4374 D3DDDICB_DEALLOCATE Dealloc;
4375 Dealloc.hResource = NULL;
4376 Dealloc.NumAllocations = 1;
4377 Dealloc.HandleList = &pRc->aAllocations[j].hAllocation;
4378 HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
4379 Assert(tmpHr == S_OK);
4380 }
4381 }
4382 }
4383
4384 vboxResourceFree(pRc);
4385 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4386 return hr;
4387}
4388static HRESULT APIENTRY vboxWddmDDevSetDisplayMode(HANDLE hDevice, CONST D3DDDIARG_SETDISPLAYMODE* pData)
4389{
4390 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4391 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4392 HRESULT hr = S_OK;
4393 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4394 Assert(pDevice);
4395 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4396 Assert(VBOXDISPMODE_IS_3D(pDevice->pAdapter));
4397 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4398 Assert(pRc);
4399 Assert(pRc->cAllocations > pData->SubResourceIndex);
4400 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4401 Assert(pRc->RcDesc.fFlags.RenderTarget);
4402 Assert(pRc->RcDesc.fFlags.Primary);
4403 Assert(pAlloc->hAllocation);
4404 D3DDDICB_SETDISPLAYMODE DdiDm = {0};
4405 DdiDm.hPrimaryAllocation = pAlloc->hAllocation;
4406
4407 {
4408 hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
4409 Assert(hr == S_OK);
4410 }
4411
4412 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4413 return hr;
4414}
4415
4416#ifdef VBOXWDDM_TEST_UHGSMI
4417int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs);
4418#endif
4419
4420static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRESENT* pData)
4421{
4422 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4423 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4424 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4425// VBOXDISPPROFILE_DDI_CHKDUMPRESET(pDevice);
4426 Assert(pDevice);
4427 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4428 HRESULT hr = S_OK;
4429 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4430 {
4431#ifdef VBOXWDDM_TEST_UHGSMI
4432 {
4433 static uint32_t cCals = 100000;
4434 static uint32_t cbData = 8 * 1024 * 1024;
4435 uint64_t TimeMs;
4436 int rc = vboxUhgsmiTst(&pDevice->Uhgsmi.Base, cbData, cCals, &TimeMs);
4437 uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs;
4438 }
4439#endif
4440 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4441 Assert(pRc);
4442 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
4443 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
4444 hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
4445 Assert(hr == S_OK);
4446 }
4447
4448 {
4449 D3DDDICB_PRESENT DdiPresent = {0};
4450 if (pData->hSrcResource)
4451 {
4452 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4453 Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
4454 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
4455 Assert(pAlloc->hAllocation);
4456 DdiPresent.hSrcAllocation = pAlloc->hAllocation;
4457 }
4458 if (pData->hDstResource)
4459 {
4460 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4461 Assert(pRc->cAllocations > pData->DstSubResourceIndex);
4462 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
4463 Assert(pAlloc->hAllocation);
4464 DdiPresent.hDstAllocation = pAlloc->hAllocation;
4465 }
4466 DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
4467
4468#if 0 //def VBOX_WDDMDISP_WITH_PROFILE
4469 VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb"));
4470#endif
4471#ifdef VBOXWDDMDISP_DEBUG_TIMER
4472 HANDLE hTimer = NULL;
4473 vboxVDbgTimerStart(pDevice->hTimerQueue, &hTimer, 1000);
4474#endif
4475 hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
4476#ifdef VBOXWDDMDISP_DEBUG_TIMER
4477 vboxVDbgTimerStop(pDevice->hTimerQueue, hTimer);
4478#endif
4479#if 0 //def VBOX_WDDMDISP_WITH_PROFILE
4480 profilePresentCbLogger.logAndDisable();
4481 if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64)
4482 {
4483 pDevice->ProfileDdiPresentCb.dump(pDevice);
4484 pDevice->ProfileDdiPresentCb.reset();
4485 }
4486#endif
4487 Assert(hr == S_OK);
4488 }
4489
4490 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4491
4492 VBOXDISPPROFILE_DDI_REPORT_FRAME(pDevice);
4493
4494 return hr;
4495}
4496
4497static HRESULT APIENTRY vboxWddmDDevFlush(HANDLE hDevice)
4498{
4499 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4500 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4501 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4502 Assert(pDevice);
4503 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4504 HRESULT hr = S_OK;
4505 if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
4506 {
4507
4508 hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Flush((IDirect3DDevice9Ex*)pDevice->pDevice9If);
4509 Assert(hr == S_OK);
4510
4511 vboxWddmDalNotifyChange(pDevice);
4512
4513 VBOXVDBG_DUMP_FLUSH(pDevice);
4514 }
4515 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4516
4517 VBOXDISPPROFILE_DDI_REPORT_FLUSH(pDevice);
4518
4519 return hr;
4520}
4521
4522AssertCompile(sizeof (D3DDDIVERTEXELEMENT) == sizeof (D3DVERTEXELEMENT9));
4523AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Stream) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Stream));
4524AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Offset) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Offset));
4525AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Type) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Type));
4526AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Method) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Method));
4527AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, Usage) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, Usage));
4528AssertCompile(RT_SIZEOFMEMB(D3DDDIVERTEXELEMENT, UsageIndex) == RT_SIZEOFMEMB(D3DVERTEXELEMENT9, UsageIndex));
4529
4530AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Stream) == RT_OFFSETOF(D3DVERTEXELEMENT9, Stream));
4531AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Offset) == RT_OFFSETOF(D3DVERTEXELEMENT9, Offset));
4532AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Type) == RT_OFFSETOF(D3DVERTEXELEMENT9, Type));
4533AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Method) == RT_OFFSETOF(D3DVERTEXELEMENT9, Method));
4534AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, Usage) == RT_OFFSETOF(D3DVERTEXELEMENT9, Usage));
4535AssertCompile(RT_OFFSETOF(D3DDDIVERTEXELEMENT, UsageIndex) == RT_OFFSETOF(D3DVERTEXELEMENT9, UsageIndex));
4536
4537static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderDecl(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERDECL* pData, CONST D3DDDIVERTEXELEMENT* pVertexElements)
4538{
4539 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4540 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4541 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4542 Assert(pDevice);
4543 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4544 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4545 IDirect3DVertexDeclaration9 *pDecl;
4546 static D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
4547 D3DVERTEXELEMENT9* pVe;
4548 HRESULT hr = S_OK;
4549 bool bFreeVe = false;
4550 if(memcmp(&DeclEnd, &pVertexElements[pData->NumVertexElements], sizeof (DeclEnd)))
4551 {
4552 pVe = (D3DVERTEXELEMENT9*)RTMemAlloc(sizeof (D3DVERTEXELEMENT9) * (pData->NumVertexElements + 1));
4553 if (pVe)
4554 {
4555 memcpy(pVe, pVertexElements, sizeof (D3DVERTEXELEMENT9) * pData->NumVertexElements);
4556 pVe[pData->NumVertexElements] = DeclEnd;
4557 bFreeVe = true;
4558 }
4559 else
4560 hr = E_OUTOFMEMORY;
4561 }
4562 else
4563 pVe = (D3DVERTEXELEMENT9*)pVertexElements;
4564
4565 if (hr == S_OK)
4566 {
4567 hr = pDevice9If->CreateVertexDeclaration(
4568 pVe,
4569 &pDecl
4570 );
4571 Assert(hr == S_OK);
4572 if (hr == S_OK)
4573 {
4574 Assert(pDecl);
4575 pData->ShaderHandle = pDecl;
4576 }
4577 }
4578
4579 if (bFreeVe)
4580 RTMemFree((void*)pVe);
4581
4582 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4583 return hr;
4584}
4585static HRESULT APIENTRY vboxWddmDDevSetVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4586{
4587 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4588 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4589 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4590 Assert(pDevice);
4591 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4592 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4593 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4594 Assert(pDecl);
4595 HRESULT hr = pDevice9If->SetVertexDeclaration(pDecl);
4596 Assert(hr == S_OK);
4597 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4598 return hr;
4599}
4600static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderDecl(HANDLE hDevice, HANDLE hShaderHandle)
4601{
4602 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4603 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4604 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4605 Assert(pDevice);
4606 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4607 IDirect3DVertexDeclaration9 *pDecl = (IDirect3DVertexDeclaration9*)hShaderHandle;
4608 HRESULT hr = S_OK;
4609 pDecl->Release();
4610 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4611 return hr;
4612}
4613static HRESULT APIENTRY vboxWddmDDevCreateVertexShaderFunc(HANDLE hDevice, D3DDDIARG_CREATEVERTEXSHADERFUNC* pData, CONST UINT* pCode)
4614{
4615 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4616 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4617 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4618 Assert(pDevice);
4619 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4620 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4621 IDirect3DVertexShader9 *pShader;
4622 Assert(*((UINT*)((uint8_t*)pCode + pData->Size-4)) == 0x0000FFFF /* end token */);
4623 HRESULT hr = pDevice9If->CreateVertexShader((const DWORD *)pCode, &pShader);
4624 Assert(hr == S_OK);
4625 if (hr == S_OK)
4626 {
4627 Assert(pShader);
4628 pData->ShaderHandle = pShader;
4629 }
4630 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4631 return hr;
4632}
4633static HRESULT APIENTRY vboxWddmDDevSetVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4634{
4635 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4636 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4637 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4638 Assert(pDevice);
4639 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4640 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4641 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4642 HRESULT hr = pDevice9If->SetVertexShader(pShader);
4643 Assert(hr == S_OK);
4644 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4645 return hr;
4646}
4647static HRESULT APIENTRY vboxWddmDDevDeleteVertexShaderFunc(HANDLE hDevice, HANDLE hShaderHandle)
4648{
4649 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4650 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4651 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4652 Assert(pDevice);
4653 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4654 IDirect3DVertexShader9 *pShader = (IDirect3DVertexShader9*)hShaderHandle;
4655 HRESULT hr = S_OK;
4656 pShader->Release();
4657 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4658 return hr;
4659}
4660static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTI* pData, CONST INT* pRegisters)
4661{
4662 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4663 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4664 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4665 Assert(pDevice);
4666 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4667 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4668 HRESULT hr = pDevice9If->SetVertexShaderConstantI(pData->Register, pRegisters, pData->Count);
4669 Assert(hr == S_OK);
4670 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4671 return hr;
4672}
4673static HRESULT APIENTRY vboxWddmDDevSetVertexShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETVERTEXSHADERCONSTB* pData, CONST BOOL* pRegisters)
4674{
4675 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4676 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4677 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4678 Assert(pDevice);
4679 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4680 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4681 HRESULT hr = pDevice9If->SetVertexShaderConstantB(pData->Register, pRegisters, pData->Count);
4682 Assert(hr == S_OK);
4683 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4684 return hr;
4685}
4686static HRESULT APIENTRY vboxWddmDDevSetScissorRect(HANDLE hDevice, CONST RECT* pRect)
4687{
4688 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4689 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4690 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4691 Assert(pDevice);
4692 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4693 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4694 HRESULT hr = pDevice9If->SetScissorRect(pRect);
4695 Assert(hr == S_OK);
4696 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4697 return hr;
4698}
4699static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCE* pData)
4700{
4701 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4702 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4703 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4704 Assert(pDevice);
4705 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4706 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4707 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hVertexBuffer;
4708 PVBOXWDDMDISP_ALLOCATION pAlloc = NULL;
4709 IDirect3DVertexBuffer9 *pStreamData = NULL;
4710 if (pRc)
4711 {
4712 VBOXVDBG_CHECK_SMSYNC(pRc);
4713 Assert(pRc->cAllocations == 1);
4714 pAlloc = &pRc->aAllocations[0];
4715 Assert(pAlloc->pD3DIf);
4716 pStreamData = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
4717 }
4718 HRESULT hr = pDevice9If->SetStreamSource(pData->Stream, pStreamData, pData->Offset, pData->Stride);
4719 Assert(hr == S_OK);
4720 Assert(pData->Stream<VBOXWDDMDISP_MAX_VERTEX_STREAMS);
4721 if (hr == S_OK)
4722 {
4723 if (pDevice->aStreamSource[pData->Stream] && !pAlloc)
4724 {
4725 --pDevice->cStreamSources;
4726 Assert(pDevice->cStreamSources < UINT32_MAX/2);
4727 }
4728 else if (!pDevice->aStreamSource[pData->Stream] && pAlloc)
4729 {
4730 ++pDevice->cStreamSources;
4731 Assert(pDevice->cStreamSources <= RT_ELEMENTS(pDevice->aStreamSource));
4732 }
4733 pDevice->aStreamSource[pData->Stream] = pAlloc;
4734 pDevice->StreamSourceInfo[pData->Stream].uiOffset = pData->Offset;
4735 pDevice->StreamSourceInfo[pData->Stream].uiStride = pData->Stride;
4736
4737 PVBOXWDDMDISP_STREAMSOURCEUM pStrSrcUm = &pDevice->aStreamSourceUm[pData->Stream];
4738 if (pStrSrcUm->pvBuffer)
4739 {
4740 --pDevice->cStreamSourcesUm;
4741 Assert(pDevice->cStreamSourcesUm < UINT32_MAX/2);
4742 pStrSrcUm->pvBuffer = NULL;
4743 pStrSrcUm->cbStride = 0;
4744 }
4745 }
4746 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4747 return hr;
4748}
4749static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
4750{
4751 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4752 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4753 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4754 Assert(pDevice);
4755 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4756 Assert(0);
4757 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4758 return E_FAIL;
4759}
4760static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
4761{
4762 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4763 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4764 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4765 Assert(pDevice);
4766 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4767 Assert(0);
4768 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4769 return E_FAIL;
4770}
4771static HRESULT APIENTRY vboxWddmDDevComposeRects(HANDLE hDevice, CONST D3DDDIARG_COMPOSERECTS* pData)
4772{
4773 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4774 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4775 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4776 Assert(pDevice);
4777 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4778 Assert(0);
4779 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4780 return E_FAIL;
4781}
4782
4783static HRESULT APIENTRY vboxWddmDDevBlt(HANDLE hDevice, CONST D3DDDIARG_BLT* pData)
4784{
4785 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4786 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4787 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4788 Assert(pDevice);
4789 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4790// PVBOXWDDMDISP_SCREEN pScreen = &pDevice->aScreens[pDevice->iPrimaryScreen];
4791 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4792 PVBOXWDDMDISP_RESOURCE pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
4793 PVBOXWDDMDISP_RESOURCE pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
4794 VBOXVDBG_CHECK_SMSYNC(pDstRc);
4795 VBOXVDBG_CHECK_SMSYNC(pSrcRc);
4796 Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
4797 Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
4798 HRESULT hr = S_OK;
4799 PVBOXWDDMDISP_ALLOCATION pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
4800 PVBOXWDDMDISP_ALLOCATION pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
4801 PVBOXWDDMDISP_SWAPCHAIN pSrcSwapchain = vboxWddmSwapchainForAlloc(pSrcAlloc);
4802 PVBOXWDDMDISP_SWAPCHAIN pDstSwapchain = vboxWddmSwapchainForAlloc(pDstAlloc);
4803 /* try StretchRect */
4804 IDirect3DSurface9 *pSrcSurfIf = NULL;
4805 IDirect3DSurface9 *pDstSurfIf = NULL;
4806 Assert(!pDstSwapchain || vboxWddmSwapchainGetFb(pDstSwapchain)->pAlloc != pDstAlloc || vboxWddmSwapchainNumRTs(pDstSwapchain) == 1);
4807
4808 VBOXVDBG_BREAK_SHARED(pSrcRc);
4809 VBOXVDBG_BREAK_SHARED(pDstRc);
4810
4811 hr = VBoxD3DIfSurfGet(pDstRc, pData->DstSubResourceIndex, &pDstSurfIf);
4812 Assert(hr == S_OK);
4813 if (hr == S_OK)
4814 {
4815 Assert(pDstSurfIf);
4816 do
4817 {
4818 if (pSrcSwapchain)
4819 {
4820 hr = vboxWddmSwapchainSurfGet(pDevice, pSrcSwapchain, pSrcAlloc, &pSrcSurfIf);
4821 Assert(hr == S_OK);
4822 }
4823 else
4824 {
4825 hr = VBoxD3DIfSurfGet(pSrcRc, pData->SrcSubResourceIndex, &pSrcSurfIf);
4826 Assert(hr == S_OK);
4827 }
4828
4829 if (hr == S_OK)
4830 {
4831 Assert(pSrcSurfIf);
4832
4833 VBOXVDBG_BREAK_SHARED(pSrcRc);
4834 VBOXVDBG_BREAK_SHARED(pDstRc);
4835
4836 /* we support only Point & Linear, we ignore [Begin|Continue|End]PresentToDwm */
4837 Assert((pData->Flags.Value & (~(0x00000100 | 0x00000200 | 0x00000400 | 0x00000001 | 0x00000002))) == 0);
4838 VBOXVDBG_CHECK_BLT(hr = pDevice9If->StretchRect(pSrcSurfIf, &pData->SrcRect, pDstSurfIf, &pData->DstRect, vboxDDI2D3DBltFlags(pData->Flags)); Assert(hr == S_OK),
4839 pSrcAlloc, pSrcSurfIf, &pData->SrcRect, pDstAlloc, pDstSurfIf, &pData->DstRect);
4840
4841 pSrcSurfIf->Release();
4842 }
4843 } while (0);
4844
4845 pDstSurfIf->Release();
4846 }
4847
4848 if (hr != S_OK)
4849 {
4850 /* todo: fallback to memcpy or whatever ? */
4851 Assert(0);
4852 }
4853
4854 PVBOXWDDMDISP_ALLOCATION pDAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
4855 vboxWddmDalCheckAdd(pDevice, pDAlloc, TRUE);
4856 pDAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
4857 vboxWddmDalCheckAdd(pDevice, pDAlloc, FALSE);
4858
4859 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4860 return hr;
4861}
4862static HRESULT APIENTRY vboxWddmDDevColorFill(HANDLE hDevice, CONST D3DDDIARG_COLORFILL* pData)
4863{
4864 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4865 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4866 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4867 Assert(pDevice);
4868 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4869 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4870 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
4871 Assert(pRc);
4872 IDirect3DSurface9 *pSurfIf = NULL;
4873 HRESULT hr = VBoxD3DIfSurfGet(pRc, pData->SubResourceIndex, &pSurfIf);
4874 Assert(hr == S_OK);
4875 if (hr == S_OK)
4876 {
4877 VBOXVDBG_CHECK_SMSYNC(pRc);
4878 Assert(pSurfIf);
4879 hr = pDevice9If->ColorFill(pSurfIf, &pData->DstRect, pData->Color);
4880 Assert(hr == S_OK);
4881 /* @todo: check what need to do when PresentToDwm flag is set */
4882 Assert(pData->Flags.Value == 0);
4883
4884 pSurfIf->Release();
4885
4886 PVBOXWDDMDISP_ALLOCATION pDAlloc = &pRc->aAllocations[pData->SubResourceIndex];
4887 vboxWddmDalCheckAdd(pDevice, pDAlloc, TRUE);
4888 }
4889 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
4890 return hr;
4891}
4892static HRESULT APIENTRY vboxWddmDDevDepthFill(HANDLE hDevice, CONST D3DDDIARG_DEPTHFILL* pData)
4893{
4894 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4895 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4896 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4897 Assert(pDevice);
4898 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4899 Assert(0);
4900//@todo: vboxWddmDalCheckAdd(pDevice, pDAlloc, TRUE);
4901 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4902 return E_FAIL;
4903}
4904static HRESULT APIENTRY vboxWddmDDevCreateQuery(HANDLE hDevice, D3DDDIARG_CREATEQUERY* pData)
4905{
4906 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4907 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4908 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4909 Assert(pDevice);
4910 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4911
4912 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
4913 HRESULT hr = S_OK;
4914 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)RTMemAllocZ(sizeof (VBOXWDDMDISP_QUERY));
4915 if (!pQuery)
4916 {
4917 WARN(("RTMemAllocZ failed"));
4918 return E_OUTOFMEMORY;
4919 }
4920
4921 hr = pDevice9If->CreateQuery(vboxDDI2D3DQueryType(pData->QueryType), &pQuery->pQueryIf);
4922 if (FAILED(hr))
4923 {
4924 WARN(("CreateQuery failed, hr 0x%x", hr));
4925 RTMemFree(pQuery);
4926 return hr;
4927 }
4928
4929 Assert(hr == S_OK);
4930
4931 pQuery->enmType = pData->QueryType;
4932 pData->hQuery = pQuery;
4933
4934 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4935 return hr;
4936}
4937static HRESULT APIENTRY vboxWddmDDevDestroyQuery(HANDLE hDevice, HANDLE hQuery)
4938{
4939 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4940 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4941 HRESULT hr = S_OK;
4942 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4943 Assert(pDevice);
4944 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4945
4946 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)hQuery;
4947 Assert(pQuery);
4948 pQuery->pQueryIf->Release();
4949 RTMemFree(pQuery);
4950 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4951 return hr;
4952}
4953static HRESULT APIENTRY vboxWddmDDevIssueQuery(HANDLE hDevice, CONST D3DDDIARG_ISSUEQUERY* pData)
4954{
4955 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4956 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4957 HRESULT hr = S_OK;
4958 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4959 Assert(pDevice);
4960 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4961
4962 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
4963 Assert(pQuery);
4964 pQuery->fQueryState.Value |= pData->Flags.Value;
4965 hr = pQuery->pQueryIf->Issue(vboxDDI2D3DIssueQueryFlags(pData->Flags));
4966 if (hr != S_OK)
4967 WARN(("Issue failed, hr = 0x%x", hr));
4968
4969 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4970 return hr;
4971}
4972static HRESULT APIENTRY vboxWddmDDevGetQueryData(HANDLE hDevice, CONST D3DDDIARG_GETQUERYDATA* pData)
4973{
4974 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
4975 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
4976 HRESULT hr = S_OK;
4977 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
4978 Assert(pDevice);
4979 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
4980
4981 PVBOXWDDMDISP_QUERY pQuery = (PVBOXWDDMDISP_QUERY)pData->hQuery;
4982 Assert(pQuery);
4983 DWORD cbData = pQuery->pQueryIf->GetDataSize();
4984#ifdef DEBUG
4985 switch (pQuery->enmType)
4986 {
4987 case D3DDDIQUERYTYPE_EVENT:
4988 Assert(cbData == sizeof (BOOL));
4989 break;
4990 default:
4991 Assert(0);
4992 break;
4993 }
4994#endif
4995 hr = pQuery->pQueryIf->GetData(pData->pData, cbData, 0);
4996 if (hr != S_OK)
4997 WARN(("GetData failed, hr = 0x%x", hr));
4998
4999 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5000 return hr;
5001}
5002static HRESULT APIENTRY vboxWddmDDevSetRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETRENDERTARGET* pData)
5003{
5004 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5005 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5006 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5007 Assert(pDevice);
5008 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5009
5010 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5011 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hRenderTarget;
5012 VBOXVDBG_CHECK_SMSYNC(pRc);
5013 Assert(pRc);
5014 Assert(pData->SubResourceIndex < pRc->cAllocations);
5015 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
5016 HRESULT hr = vboxWddmRenderTargetSet(pDevice, pData->RenderTargetIndex, pAlloc, FALSE);
5017 Assert(hr == S_OK);
5018 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5019 return hr;
5020}
5021static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDIARG_SETDEPTHSTENCIL* pData)
5022{
5023 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5024 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5025 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5026 Assert(pDevice);
5027 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5028
5029 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5030 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hZBuffer;
5031 IDirect3DSurface9 *pD3D9Surf = NULL;
5032 if (pRc)
5033 {
5034 VBOXVDBG_CHECK_SMSYNC(pRc);
5035 Assert(pRc->cAllocations == 1);
5036 Assert(pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
5037 pD3D9Surf = (IDirect3DSurface9*)pRc->aAllocations[0].pD3DIf;
5038 Assert(pD3D9Surf);
5039 }
5040 HRESULT hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
5041 Assert(hr == S_OK);
5042 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5043 return hr;
5044}
5045static HRESULT APIENTRY vboxWddmDDevGenerateMipSubLevels(HANDLE hDevice, CONST D3DDDIARG_GENERATEMIPSUBLEVELS* pData)
5046{
5047 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5048 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5049 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5050 Assert(pDevice);
5051 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5052
5053 Assert(0);
5054 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5055 return E_FAIL;
5056}
5057static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstI(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTI* pData, CONST INT* pRegisters)
5058{
5059 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5060 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5061 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5062 Assert(pDevice);
5063 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5064
5065 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5066 HRESULT hr = pDevice9If->SetPixelShaderConstantI(pData->Register, pRegisters, pData->Count);
5067 Assert(hr == S_OK);
5068 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5069 return hr;
5070}
5071static HRESULT APIENTRY vboxWddmDDevSetPixelShaderConstB(HANDLE hDevice, CONST D3DDDIARG_SETPIXELSHADERCONSTB* pData, CONST BOOL* pRegisters)
5072{
5073 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5074 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5075 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5076 Assert(pDevice);
5077 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5078
5079 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5080 HRESULT hr = pDevice9If->SetPixelShaderConstantB(pData->Register, pRegisters, pData->Count);
5081 Assert(hr == S_OK);
5082 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5083 return hr;
5084}
5085static HRESULT APIENTRY vboxWddmDDevCreatePixelShader(HANDLE hDevice, D3DDDIARG_CREATEPIXELSHADER* pData, CONST UINT* pCode)
5086{
5087 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5088 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5089 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5090 Assert(pDevice);
5091 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5092
5093 IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
5094 IDirect3DPixelShader9 *pShader;
5095 Assert(*((UINT*)((uint8_t*)pCode + pData->CodeSize-4)) == 0x0000FFFF /* end token */);
5096 HRESULT hr = pDevice9If->CreatePixelShader((const DWORD *)pCode, &pShader);
5097 Assert(hr == S_OK);
5098 if (hr == S_OK)
5099 {
5100 Assert(pShader);
5101 pData->ShaderHandle = pShader;
5102 }
5103 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5104 return hr;
5105}
5106static HRESULT APIENTRY vboxWddmDDevDeletePixelShader(HANDLE hDevice, HANDLE hShaderHandle)
5107{
5108 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5109 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5110 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5111 Assert(pDevice);
5112 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5113
5114 IDirect3DPixelShader9 *pShader = (IDirect3DPixelShader9*)hShaderHandle;
5115 HRESULT hr = S_OK;
5116 pShader->Release();
5117 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
5118 return hr;
5119}
5120static HRESULT APIENTRY vboxWddmDDevCreateDecodeDevice(HANDLE hDevice, D3DDDIARG_CREATEDECODEDEVICE* pData)
5121{
5122 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5123 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5124 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5125 Assert(pDevice);
5126 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5127
5128 Assert(0);
5129 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5130 return E_FAIL;
5131}
5132static HRESULT APIENTRY vboxWddmDDevDestroyDecodeDevice(HANDLE hDevice, HANDLE hDecodeDevice)
5133{
5134 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5135 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5136 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5137 Assert(pDevice);
5138 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5139
5140 Assert(0);
5141 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5142 return E_FAIL;
5143}
5144static HRESULT APIENTRY vboxWddmDDevSetDecodeRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETDECODERENDERTARGET* pData)
5145{
5146 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5147 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5148 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5149 Assert(pDevice);
5150 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5151
5152 Assert(0);
5153 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5154 return E_FAIL;
5155}
5156static HRESULT APIENTRY vboxWddmDDevDecodeBeginFrame(HANDLE hDevice, D3DDDIARG_DECODEBEGINFRAME* pData)
5157{
5158 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5159 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5160 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5161 Assert(pDevice);
5162 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5163
5164 Assert(0);
5165 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5166 return E_FAIL;
5167}
5168static HRESULT APIENTRY vboxWddmDDevDecodeEndFrame(HANDLE hDevice, D3DDDIARG_DECODEENDFRAME* pData)
5169{
5170 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5171 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5172 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5173 Assert(pDevice);
5174 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5175
5176 Assert(0);
5177 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5178 return E_FAIL;
5179}
5180static HRESULT APIENTRY vboxWddmDDevDecodeExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXECUTE* pData)
5181{
5182 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5183 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5184 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5185 Assert(pDevice);
5186 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5187
5188 Assert(0);
5189 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5190 return E_FAIL;
5191}
5192static HRESULT APIENTRY vboxWddmDDevDecodeExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_DECODEEXTENSIONEXECUTE* pData)
5193{
5194 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5195 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5196 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5197 Assert(pDevice);
5198 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5199
5200 Assert(0);
5201 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5202 return E_FAIL;
5203}
5204static HRESULT APIENTRY vboxWddmDDevCreateVideoProcessDevice(HANDLE hDevice, D3DDDIARG_CREATEVIDEOPROCESSDEVICE* pData)
5205{
5206 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5207 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5208 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5209 Assert(pDevice);
5210 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5211
5212 Assert(0);
5213 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5214 return E_FAIL;
5215}
5216static HRESULT APIENTRY vboxWddmDDevDestroyVideoProcessDevice(HANDLE hDevice, HANDLE hVideoProcessor)
5217{
5218 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5219 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5220 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5221 Assert(pDevice);
5222 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5223
5224 Assert(0);
5225 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5226 return E_FAIL;
5227}
5228static HRESULT APIENTRY vboxWddmDDevVideoProcessBeginFrame(HANDLE hDevice, HANDLE hVideoProcess)
5229{
5230 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5231 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5232 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5233 Assert(pDevice);
5234 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5235
5236 Assert(0);
5237 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5238 return E_FAIL;
5239}
5240static HRESULT APIENTRY vboxWddmDDevVideoProcessEndFrame(HANDLE hDevice, D3DDDIARG_VIDEOPROCESSENDFRAME* pData)
5241{
5242 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5243 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5244 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5245 Assert(pDevice);
5246 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5247
5248 Assert(0);
5249 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5250 return E_FAIL;
5251}
5252static HRESULT APIENTRY vboxWddmDDevSetVideoProcessRenderTarget(HANDLE hDevice, CONST D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pData)
5253{
5254 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5255 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5256 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5257 Assert(pDevice);
5258 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5259
5260 Assert(0);
5261 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5262 return E_FAIL;
5263}
5264static HRESULT APIENTRY vboxWddmDDevVideoProcessBlt(HANDLE hDevice, CONST D3DDDIARG_VIDEOPROCESSBLT* pData)
5265{
5266 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5267 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5268 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5269 Assert(pDevice);
5270 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5271
5272 Assert(0);
5273 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5274 return E_FAIL;
5275}
5276static HRESULT APIENTRY vboxWddmDDevCreateExtensionDevice(HANDLE hDevice, D3DDDIARG_CREATEEXTENSIONDEVICE* pData)
5277{
5278 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5279 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5280 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5281 Assert(pDevice);
5282 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5283
5284 Assert(0);
5285 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5286 return E_FAIL;
5287}
5288static HRESULT APIENTRY vboxWddmDDevDestroyExtensionDevice(HANDLE hDevice, HANDLE hExtension)
5289{
5290 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5291 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5292 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5293 Assert(pDevice);
5294 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5295
5296 Assert(0);
5297 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5298 return E_FAIL;
5299}
5300static HRESULT APIENTRY vboxWddmDDevExtensionExecute(HANDLE hDevice, CONST D3DDDIARG_EXTENSIONEXECUTE* pData)
5301{
5302 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5303 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5304 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5305 Assert(pDevice);
5306 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5307
5308 Assert(0);
5309 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5310 return E_FAIL;
5311}
5312static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
5313{
5314 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5315 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5316
5317 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5318 Assert(pDevice);
5319 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5320
5321 VBOXDISPPROFILE_DDI_PRINT(("Dumping on DestroyDevice: 0x%p", pDevice));
5322 VBOXDISPPROFILE_DDI_TERM(pDevice);
5323
5324#ifdef VBOXWDDMDISP_DEBUG_TIMER
5325 DeleteTimerQueueEx(pDevice->hTimerQueue, INVALID_HANDLE_VALUE /* see term */);
5326 pDevice->hTimerQueue = NULL;
5327#endif
5328
5329 PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
5330 if (VBOXDISPMODE_IS_3D(pAdapter))
5331 {
5332 vboxWddmSwapchainDestroyAll(pDevice);
5333 /* ensure the device is destroyed in any way.
5334 * Release may not work in case of some leaking, which will leave the crOgl context refering the destroyed VBOXUHGSMI */
5335 if (pDevice->pDevice9If)
5336 pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Term((IDirect3DDevice9Ex *)pDevice->pDevice9If);
5337 }
5338
5339 HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
5340 Assert(hr == S_OK);
5341 if (hr == S_OK)
5342 RTMemFree(pDevice);
5343 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5344 return hr;
5345}
5346
5347AssertCompile(sizeof (RECT) == sizeof (D3DDDIRECT));
5348AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(D3DDDIRECT, left));
5349AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(D3DDDIRECT, right));
5350AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(D3DDDIRECT, top));
5351AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(D3DDDIRECT, bottom));
5352AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(D3DDDIRECT, left));
5353AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(D3DDDIRECT, right));
5354AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(D3DDDIRECT, top));
5355AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(D3DDDIRECT, bottom));
5356
5357static HRESULT APIENTRY vboxWddmDDevCreateOverlay(HANDLE hDevice, D3DDDIARG_CREATEOVERLAY* pData)
5358{
5359 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5360 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5361 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5362 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5363 Assert(pRc);
5364 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5365 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5366 HRESULT hr = S_OK;
5367 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)RTMemAllocZ(sizeof (VBOXWDDMDISP_OVERLAY));
5368 Assert(pOverlay);
5369 if (pOverlay)
5370 {
5371 VBOXWDDM_OVERLAY_INFO OurInfo;
5372 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5373 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5374 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5375 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5376 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5377 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5378 Assert(!pAlloc->LockInfo.cLocks);
5379 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5380 D3DDDICB_CREATEOVERLAY OverInfo;
5381 OverInfo.VidPnSourceId = pData->VidPnSourceId;
5382 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5383 Assert(pAlloc->hAllocation);
5384 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5385 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5386 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5387 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5388 OverInfo.hKernelOverlay = NULL; /* <-- out */
5389#ifndef VBOXWDDMOVERLAY_TEST
5390 hr = pDevice->RtCallbacks.pfnCreateOverlayCb(pDevice->hDevice, &OverInfo);
5391 Assert(hr == S_OK);
5392 if (hr == S_OK)
5393 {
5394 Assert(OverInfo.hKernelOverlay);
5395 pOverlay->hOverlay = OverInfo.hKernelOverlay;
5396 pOverlay->VidPnSourceId = pData->VidPnSourceId;
5397
5398 Assert(!pAlloc->LockInfo.cLocks);
5399 if (!pAlloc->LockInfo.cLocks)
5400 {
5401 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5402 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5403 }
5404
5405 pData->hOverlay = pOverlay;
5406 }
5407 else
5408 {
5409 RTMemFree(pOverlay);
5410 }
5411#else
5412 pData->hOverlay = pOverlay;
5413#endif
5414 }
5415 else
5416 hr = E_OUTOFMEMORY;
5417
5418 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5419 return hr;
5420}
5421static HRESULT APIENTRY vboxWddmDDevUpdateOverlay(HANDLE hDevice, CONST D3DDDIARG_UPDATEOVERLAY* pData)
5422{
5423 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5424 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5425 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5426 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->OverlayInfo.hResource;
5427 Assert(pRc);
5428 Assert(pRc->cAllocations > pData->OverlayInfo.SubResourceIndex);
5429 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->OverlayInfo.SubResourceIndex];
5430 HRESULT hr = S_OK;
5431 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5432 VBOXWDDM_OVERLAY_INFO OurInfo;
5433 OurInfo.OverlayDesc.DstColorKeyLow = pData->OverlayInfo.DstColorKeyLow;
5434 OurInfo.OverlayDesc.DstColorKeyHigh = pData->OverlayInfo.DstColorKeyHigh;
5435 OurInfo.OverlayDesc.SrcColorKeyLow = pData->OverlayInfo.SrcColorKeyLow;
5436 OurInfo.OverlayDesc.SrcColorKeyHigh = pData->OverlayInfo.SrcColorKeyHigh;
5437 OurInfo.OverlayDesc.fFlags = pData->OverlayInfo.Flags.Value;
5438 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5439 Assert(!pAlloc->LockInfo.cLocks);
5440 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5441 D3DDDICB_UPDATEOVERLAY OverInfo;
5442 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5443 OverInfo.OverlayInfo.hAllocation = pAlloc->hAllocation;
5444 OverInfo.OverlayInfo.DstRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.DstRect);
5445 OverInfo.OverlayInfo.SrcRect = *(D3DDDIRECT*)((void*)&pData->OverlayInfo.SrcRect);
5446 OverInfo.OverlayInfo.pPrivateDriverData = &OurInfo;
5447 OverInfo.OverlayInfo.PrivateDriverDataSize = sizeof (OurInfo);
5448#ifndef VBOXWDDMOVERLAY_TEST
5449 hr = pDevice->RtCallbacks.pfnUpdateOverlayCb(pDevice->hDevice, &OverInfo);
5450 Assert(hr == S_OK);
5451 if (hr == S_OK)
5452#endif
5453 {
5454 Assert(!pAlloc->LockInfo.cLocks);
5455 if (!pAlloc->LockInfo.cLocks)
5456 {
5457 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5458 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5459 }
5460 }
5461
5462 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5463 return hr;
5464}
5465static HRESULT APIENTRY vboxWddmDDevFlipOverlay(HANDLE hDevice, CONST D3DDDIARG_FLIPOVERLAY* pData)
5466{
5467 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5468 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5469 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5470 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSource;
5471 Assert(pRc);
5472 Assert(pRc->cAllocations > pData->SourceIndex);
5473 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SourceIndex];
5474 HRESULT hr = S_OK;
5475 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5476 VBOXWDDM_OVERLAYFLIP_INFO OurInfo;
5477 vboxWddmDirtyRegionClear(&OurInfo.DirtyRegion);
5478 Assert(!pAlloc->LockInfo.cLocks);
5479 vboxWddmDirtyRegionUnite(&OurInfo.DirtyRegion, &pAlloc->DirtyRegion);
5480 D3DDDICB_FLIPOVERLAY OverInfo;
5481 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5482 OverInfo.hSource = pAlloc->hAllocation;
5483 OverInfo.pPrivateDriverData = &OurInfo;
5484 OverInfo.PrivateDriverDataSize = sizeof (OurInfo);
5485#ifndef VBOXWDDMOVERLAY_TEST
5486 hr = pDevice->RtCallbacks.pfnFlipOverlayCb(pDevice->hDevice, &OverInfo);
5487 Assert(hr == S_OK);
5488 if (hr == S_OK)
5489#endif
5490 {
5491 Assert(!pAlloc->LockInfo.cLocks);
5492 if (!pAlloc->LockInfo.cLocks)
5493 {
5494 /* we have reported the dirty rect, may clear it if no locks are pending currently */
5495 vboxWddmDirtyRegionClear(&pAlloc->DirtyRegion);
5496 }
5497 }
5498
5499 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5500 return hr;
5501}
5502static HRESULT APIENTRY vboxWddmDDevGetOverlayColorControls(HANDLE hDevice, D3DDDIARG_GETOVERLAYCOLORCONTROLS* pData)
5503{
5504 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5505 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5506 Assert(0);
5507 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5508 return E_FAIL;
5509}
5510static HRESULT APIENTRY vboxWddmDDevSetOverlayColorControls(HANDLE hDevice, CONST D3DDDIARG_SETOVERLAYCOLORCONTROLS* pData)
5511{
5512 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5513 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5514 Assert(0);
5515 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5516 return E_FAIL;
5517}
5518static HRESULT APIENTRY vboxWddmDDevDestroyOverlay(HANDLE hDevice, CONST D3DDDIARG_DESTROYOVERLAY* pData)
5519{
5520 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5521 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5522 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5523 PVBOXWDDMDISP_OVERLAY pOverlay = (PVBOXWDDMDISP_OVERLAY)pData->hOverlay;
5524 D3DDDICB_DESTROYOVERLAY OverInfo;
5525 OverInfo.hKernelOverlay = pOverlay->hOverlay;
5526#ifndef VBOXWDDMOVERLAY_TEST
5527 HRESULT hr = pDevice->RtCallbacks.pfnDestroyOverlayCb(pDevice->hDevice, &OverInfo);
5528 Assert(hr == S_OK);
5529 if (hr == S_OK)
5530#else
5531 HRESULT hr = S_OK;
5532#endif
5533 {
5534 RTMemFree(pOverlay);
5535 }
5536
5537 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5538 return hr;
5539}
5540static HRESULT APIENTRY vboxWddmDDevQueryResourceResidency(HANDLE hDevice, CONST D3DDDIARG_QUERYRESOURCERESIDENCY* pData)
5541{
5542 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5543 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5544 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5545
5546 HRESULT hr = S_OK;
5547 /* @todo check residency for the "real" allocations */
5548#if 0
5549 for (UINT i = 0; i < pData->NumResources; ++i)
5550 {
5551 PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->pHandleList[i];
5552 Assert(pRc->pDevice == pDevice);
5553 if (pRc->hKMResource)
5554 {
5555
5556 }
5557 }
5558#endif
5559 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5560 return hr;
5561}
5562
5563static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENRESOURCE* pData)
5564{
5565 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5566 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5567 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5568 Assert(pDevice);
5569 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5570
5571 HRESULT hr = S_OK;
5572
5573 Assert(pData->hKMResource);
5574
5575 Assert(pData->NumAllocations);
5576 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(pData->NumAllocations);
5577 Assert(pRc);
5578 if (pRc)
5579 {
5580 pRc->hResource = pData->hResource;
5581 pRc->hKMResource = pData->hKMResource;
5582 pRc->pDevice = pDevice;
5583 pRc->RcDesc.enmRotation = pData->Rotation;
5584 pRc->fFlags.Value = 0;
5585 pRc->fFlags.Opened = 1;
5586 pRc->fFlags.KmResource = 1;
5587
5588 for (UINT i = 0; i < pData->NumAllocations; ++i)
5589 {
5590 PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
5591 D3DDDI_OPENALLOCATIONINFO* pOAI = pData->pOpenAllocationInfo;
5592 Assert(pOAI->PrivateDriverDataSize == sizeof (VBOXWDDM_ALLOCINFO));
5593 if (pOAI->PrivateDriverDataSize != sizeof (VBOXWDDM_ALLOCINFO))
5594 {
5595 hr = E_INVALIDARG;
5596 break;
5597 }
5598 Assert(pOAI->pPrivateDriverData);
5599 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pOAI->pPrivateDriverData;
5600 pAllocation->hAllocation = pOAI->hAllocation;
5601 pAllocation->enmType = pAllocInfo->enmType;
5602 pAllocation->hSharedHandle = (HANDLE)pAllocInfo->hSharedHandle;
5603 pAllocation->SurfDesc = pAllocInfo->SurfDesc;
5604 pAllocation->pvMem = NULL;
5605#ifndef VBOXWDDMDISP_DEBUG_NOSHARED
5606 Assert(!pAllocation->hSharedHandle == (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE));
5607#endif
5608#ifdef VBOXWDDMDISP_DEBUG_PRINT_SHARED_CREATE
5609 vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared OPENNED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), "
5610 "Handle(0x%x), (0n%d) \n***********\n\n",
5611 GetCurrentProcessId(), GetCurrentProcessId(),
5612 pAllocation, pRc->hKMResource, pAllocation->hAllocation,
5613 pAllocation->hSharedHandle, pAllocation->hSharedHandle
5614 ));
5615#endif
5616 }
5617 if (!pData->pPrivateDriverData || !pData->PrivateDriverDataSize)
5618 {
5619 /* this is a "standard" allocation resource */
5620
5621 /* both should be actually zero */
5622 Assert(!pData->pPrivateDriverData && !pData->PrivateDriverDataSize);
5623 pRc->RcDesc.enmPool = D3DDDIPOOL_LOCALVIDMEM;
5624 pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
5625 pRc->RcDesc.MultisampleQuality = 0;
5626 pRc->RcDesc.MipLevels = 0;
5627 pRc->RcDesc.Fvf;
5628
5629 if (pData->NumAllocations != 1)
5630 {
5631 WARN(("NumAllocations is expected to be 1, but was %d", pData->NumAllocations));
5632 }
5633
5634 for (UINT i = 0; i < pData->NumAllocations; ++i)
5635 {
5636 PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[i];
5637 pAlloc->enmD3DIfType = VBOXDISP_D3DIFTYPE_SURFACE;
5638 pAlloc->pD3DIf = NULL;
5639 }
5640
5641 D3DDDI_OPENALLOCATIONINFO* pDdiAllocInfo = &pData->pOpenAllocationInfo[0];
5642 Assert(pDdiAllocInfo->pPrivateDriverData);
5643 Assert(pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO));
5644 if (pDdiAllocInfo->pPrivateDriverData && pDdiAllocInfo->PrivateDriverDataSize >= sizeof (VBOXWDDM_ALLOCINFO))
5645 {
5646 PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocInfo->pPrivateDriverData;
5647 switch(pAllocInfo->enmType)
5648 {
5649 case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
5650 pRc->RcDesc.fFlags.Primary = 1;
5651 case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
5652 case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
5653 pRc->RcDesc.enmFormat = pAllocInfo->SurfDesc.format;
5654 pRc->RcDesc.VidPnSourceId = pAllocInfo->SurfDesc.VidPnSourceId;
5655 pRc->RcDesc.RefreshRate = pAllocInfo->SurfDesc.RefreshRate;
5656 break;
5657 default:
5658 Assert(0);
5659 hr = E_INVALIDARG;
5660 }
5661 }
5662 else
5663 hr = E_INVALIDARG;
5664 }
5665 else
5666 {
5667 /* this is a "generic" resource whose creation is initiated by the UMD */
5668 Assert(pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO));
5669 if (pData->PrivateDriverDataSize == sizeof (VBOXWDDM_RCINFO))
5670 {
5671 VBOXWDDM_RCINFO *pRcInfo = (VBOXWDDM_RCINFO*)pData->pPrivateDriverData;
5672 Assert(pRcInfo->fFlags.Generic);
5673 Assert(!pRcInfo->fFlags.Opened);
5674 Assert(pRcInfo->cAllocInfos == pData->NumAllocations);
5675 pRc->fFlags.Value |= pRcInfo->fFlags.Value;
5676 pRc->fFlags.Generic = 1;
5677 pRc->RcDesc = pRcInfo->RcDesc;
5678 pRc->cAllocations = pData->NumAllocations;
5679 Assert(pRc->RcDesc.fFlags.SharedResource);
5680
5681 hr = VBoxD3DIfCreateForRc(pRc);
5682 if (!SUCCEEDED(hr))
5683 {
5684 WARN(("VBoxD3DIfCreateForRc failed, hr %d", hr));
5685 }
5686 }
5687 else
5688 hr = E_INVALIDARG;
5689 }
5690
5691 if (hr == S_OK)
5692 pData->hResource = pRc;
5693 else
5694 vboxResourceFree(pRc);
5695 }
5696 else
5697 {
5698 vboxVDbgPrintR((__FUNCTION__": vboxResourceAlloc failed for hDevice(0x%p), NumAllocations(%d)\n", hDevice, pData->NumAllocations));
5699 hr = E_OUTOFMEMORY;
5700 }
5701
5702 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5703 return hr;
5704}
5705static HRESULT APIENTRY vboxWddmDDevGetCaptureAllocationHandle(HANDLE hDevice, D3DDDIARG_GETCAPTUREALLOCATIONHANDLE* pData)
5706{
5707 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5708 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5709 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5710 Assert(pDevice);
5711 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5712
5713 Assert(0);
5714 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5715 return E_FAIL;
5716}
5717
5718static HRESULT APIENTRY vboxWddmDDevCaptureToSysMem(HANDLE hDevice, CONST D3DDDIARG_CAPTURETOSYSMEM* pData)
5719{
5720 VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
5721 vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5722 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
5723 Assert(pDevice);
5724 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5725
5726 Assert(0);
5727 vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
5728 return E_FAIL;
5729}
5730
5731static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIARG_CREATEDEVICE* pCreateData)
5732{
5733 VBOXDISP_DDI_PROLOGUE_ADP(hAdapter);
5734 HRESULT hr = S_OK;
5735 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), Interface(%d), Version(%d)\n", hAdapter, pCreateData->Interface, pCreateData->Version));
5736
5737// Assert(0);
5738 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5739
5740 PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_DEVICE, apRTs[pAdapter->D3D.cMaxSimRTs]));
5741 if (pDevice)
5742 {
5743 pDevice->cRTs = pAdapter->D3D.cMaxSimRTs;
5744 pDevice->hDevice = pCreateData->hDevice;
5745 pDevice->pAdapter = pAdapter;
5746 pDevice->u32IfVersion = pCreateData->Interface;
5747 pDevice->uRtVersion = pCreateData->Version;
5748 pDevice->RtCallbacks = *pCreateData->pCallbacks;
5749 pDevice->pvCmdBuffer = pCreateData->pCommandBuffer;
5750 pDevice->cbCmdBuffer = pCreateData->CommandBufferSize;
5751 pDevice->fFlags = pCreateData->Flags;
5752 /* Set Viewport to some default values */
5753 pDevice->ViewPort.X = 0;
5754 pDevice->ViewPort.Y = 0;
5755 pDevice->ViewPort.Width = 1;
5756 pDevice->ViewPort.Height = 1;
5757 pDevice->ViewPort.MinZ = 0.;
5758 pDevice->ViewPort.MaxZ = 1.;
5759
5760 RTListInit(&pDevice->DirtyAllocList);
5761
5762 Assert(!pCreateData->AllocationListSize);
5763 Assert(!pCreateData->PatchLocationListSize);
5764
5765 pCreateData->hDevice = pDevice;
5766
5767 pCreateData->pDeviceFuncs->pfnSetRenderState = vboxWddmDDevSetRenderState;
5768 pCreateData->pDeviceFuncs->pfnUpdateWInfo = vboxWddmDDevUpdateWInfo;
5769 pCreateData->pDeviceFuncs->pfnValidateDevice = vboxWddmDDevValidateDevice;
5770 pCreateData->pDeviceFuncs->pfnSetTextureStageState = vboxWddmDDevSetTextureStageState;
5771 pCreateData->pDeviceFuncs->pfnSetTexture = vboxWddmDDevSetTexture;
5772 pCreateData->pDeviceFuncs->pfnSetPixelShader = vboxWddmDDevSetPixelShader;
5773 pCreateData->pDeviceFuncs->pfnSetPixelShaderConst = vboxWddmDDevSetPixelShaderConst;
5774 pCreateData->pDeviceFuncs->pfnSetStreamSourceUm = vboxWddmDDevSetStreamSourceUm;
5775 pCreateData->pDeviceFuncs->pfnSetIndices = vboxWddmDDevSetIndices;
5776 pCreateData->pDeviceFuncs->pfnSetIndicesUm = vboxWddmDDevSetIndicesUm;
5777 pCreateData->pDeviceFuncs->pfnDrawPrimitive = vboxWddmDDevDrawPrimitive;
5778 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive = vboxWddmDDevDrawIndexedPrimitive;
5779 pCreateData->pDeviceFuncs->pfnDrawRectPatch = vboxWddmDDevDrawRectPatch;
5780 pCreateData->pDeviceFuncs->pfnDrawTriPatch = vboxWddmDDevDrawTriPatch;
5781 pCreateData->pDeviceFuncs->pfnDrawPrimitive2 = vboxWddmDDevDrawPrimitive2;
5782 pCreateData->pDeviceFuncs->pfnDrawIndexedPrimitive2 = vboxWddmDDevDrawIndexedPrimitive2;
5783 pCreateData->pDeviceFuncs->pfnVolBlt = vboxWddmDDevVolBlt;
5784 pCreateData->pDeviceFuncs->pfnBufBlt = vboxWddmDDevBufBlt;
5785 pCreateData->pDeviceFuncs->pfnTexBlt = vboxWddmDDevTexBlt;
5786 pCreateData->pDeviceFuncs->pfnStateSet = vboxWddmDDevStateSet;
5787 pCreateData->pDeviceFuncs->pfnSetPriority = vboxWddmDDevSetPriority;
5788 pCreateData->pDeviceFuncs->pfnClear = vboxWddmDDevClear;
5789 pCreateData->pDeviceFuncs->pfnUpdatePalette = vboxWddmDDevUpdatePalette;
5790 pCreateData->pDeviceFuncs->pfnSetPalette = vboxWddmDDevSetPalette;
5791 pCreateData->pDeviceFuncs->pfnSetVertexShaderConst = vboxWddmDDevSetVertexShaderConst;
5792 pCreateData->pDeviceFuncs->pfnMultiplyTransform = vboxWddmDDevMultiplyTransform;
5793 pCreateData->pDeviceFuncs->pfnSetTransform = vboxWddmDDevSetTransform;
5794 pCreateData->pDeviceFuncs->pfnSetViewport = vboxWddmDDevSetViewport;
5795 pCreateData->pDeviceFuncs->pfnSetZRange = vboxWddmDDevSetZRange;
5796 pCreateData->pDeviceFuncs->pfnSetMaterial = vboxWddmDDevSetMaterial;
5797 pCreateData->pDeviceFuncs->pfnSetLight = vboxWddmDDevSetLight;
5798 pCreateData->pDeviceFuncs->pfnCreateLight = vboxWddmDDevCreateLight;
5799 pCreateData->pDeviceFuncs->pfnDestroyLight = vboxWddmDDevDestroyLight;
5800 pCreateData->pDeviceFuncs->pfnSetClipPlane = vboxWddmDDevSetClipPlane;
5801 pCreateData->pDeviceFuncs->pfnGetInfo = vboxWddmDDevGetInfo;
5802 pCreateData->pDeviceFuncs->pfnLock = vboxWddmDDevLock;
5803 pCreateData->pDeviceFuncs->pfnUnlock = vboxWddmDDevUnlock;
5804 pCreateData->pDeviceFuncs->pfnCreateResource = vboxWddmDDevCreateResource;
5805 pCreateData->pDeviceFuncs->pfnDestroyResource = vboxWddmDDevDestroyResource;
5806 pCreateData->pDeviceFuncs->pfnSetDisplayMode = vboxWddmDDevSetDisplayMode;
5807 pCreateData->pDeviceFuncs->pfnPresent = vboxWddmDDevPresent;
5808 pCreateData->pDeviceFuncs->pfnFlush = vboxWddmDDevFlush;
5809 pCreateData->pDeviceFuncs->pfnCreateVertexShaderFunc = vboxWddmDDevCreateVertexShaderFunc;
5810 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderFunc = vboxWddmDDevDeleteVertexShaderFunc;
5811 pCreateData->pDeviceFuncs->pfnSetVertexShaderFunc = vboxWddmDDevSetVertexShaderFunc;
5812 pCreateData->pDeviceFuncs->pfnCreateVertexShaderDecl = vboxWddmDDevCreateVertexShaderDecl;
5813 pCreateData->pDeviceFuncs->pfnDeleteVertexShaderDecl = vboxWddmDDevDeleteVertexShaderDecl;
5814 pCreateData->pDeviceFuncs->pfnSetVertexShaderDecl = vboxWddmDDevSetVertexShaderDecl;
5815 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstI = vboxWddmDDevSetVertexShaderConstI;
5816 pCreateData->pDeviceFuncs->pfnSetVertexShaderConstB = vboxWddmDDevSetVertexShaderConstB;
5817 pCreateData->pDeviceFuncs->pfnSetScissorRect = vboxWddmDDevSetScissorRect;
5818 pCreateData->pDeviceFuncs->pfnSetStreamSource = vboxWddmDDevSetStreamSource;
5819 pCreateData->pDeviceFuncs->pfnSetStreamSourceFreq = vboxWddmDDevSetStreamSourceFreq;
5820 pCreateData->pDeviceFuncs->pfnSetConvolutionKernelMono = vboxWddmDDevSetConvolutionKernelMono;
5821 pCreateData->pDeviceFuncs->pfnComposeRects = vboxWddmDDevComposeRects;
5822 pCreateData->pDeviceFuncs->pfnBlt = vboxWddmDDevBlt;
5823 pCreateData->pDeviceFuncs->pfnColorFill = vboxWddmDDevColorFill;
5824 pCreateData->pDeviceFuncs->pfnDepthFill = vboxWddmDDevDepthFill;
5825 pCreateData->pDeviceFuncs->pfnCreateQuery = vboxWddmDDevCreateQuery;
5826 pCreateData->pDeviceFuncs->pfnDestroyQuery = vboxWddmDDevDestroyQuery;
5827 pCreateData->pDeviceFuncs->pfnIssueQuery = vboxWddmDDevIssueQuery;
5828 pCreateData->pDeviceFuncs->pfnGetQueryData = vboxWddmDDevGetQueryData;
5829 pCreateData->pDeviceFuncs->pfnSetRenderTarget = vboxWddmDDevSetRenderTarget;
5830 pCreateData->pDeviceFuncs->pfnSetDepthStencil = vboxWddmDDevSetDepthStencil;
5831 pCreateData->pDeviceFuncs->pfnGenerateMipSubLevels = vboxWddmDDevGenerateMipSubLevels;
5832 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstI = vboxWddmDDevSetPixelShaderConstI;
5833 pCreateData->pDeviceFuncs->pfnSetPixelShaderConstB = vboxWddmDDevSetPixelShaderConstB;
5834 pCreateData->pDeviceFuncs->pfnCreatePixelShader = vboxWddmDDevCreatePixelShader;
5835 pCreateData->pDeviceFuncs->pfnDeletePixelShader = vboxWddmDDevDeletePixelShader;
5836 pCreateData->pDeviceFuncs->pfnCreateDecodeDevice = vboxWddmDDevCreateDecodeDevice;
5837 pCreateData->pDeviceFuncs->pfnDestroyDecodeDevice = vboxWddmDDevDestroyDecodeDevice;
5838 pCreateData->pDeviceFuncs->pfnSetDecodeRenderTarget = vboxWddmDDevSetDecodeRenderTarget;
5839 pCreateData->pDeviceFuncs->pfnDecodeBeginFrame = vboxWddmDDevDecodeBeginFrame;
5840 pCreateData->pDeviceFuncs->pfnDecodeEndFrame = vboxWddmDDevDecodeEndFrame;
5841 pCreateData->pDeviceFuncs->pfnDecodeExecute = vboxWddmDDevDecodeExecute;
5842 pCreateData->pDeviceFuncs->pfnDecodeExtensionExecute = vboxWddmDDevDecodeExtensionExecute;
5843 pCreateData->pDeviceFuncs->pfnCreateVideoProcessDevice = vboxWddmDDevCreateVideoProcessDevice;
5844 pCreateData->pDeviceFuncs->pfnDestroyVideoProcessDevice = vboxWddmDDevDestroyVideoProcessDevice;
5845 pCreateData->pDeviceFuncs->pfnVideoProcessBeginFrame = vboxWddmDDevVideoProcessBeginFrame;
5846 pCreateData->pDeviceFuncs->pfnVideoProcessEndFrame = vboxWddmDDevVideoProcessEndFrame;
5847 pCreateData->pDeviceFuncs->pfnSetVideoProcessRenderTarget = vboxWddmDDevSetVideoProcessRenderTarget;
5848 pCreateData->pDeviceFuncs->pfnVideoProcessBlt = vboxWddmDDevVideoProcessBlt;
5849 pCreateData->pDeviceFuncs->pfnCreateExtensionDevice = vboxWddmDDevCreateExtensionDevice;
5850 pCreateData->pDeviceFuncs->pfnDestroyExtensionDevice = vboxWddmDDevDestroyExtensionDevice;
5851 pCreateData->pDeviceFuncs->pfnExtensionExecute = vboxWddmDDevExtensionExecute;
5852 pCreateData->pDeviceFuncs->pfnCreateOverlay = vboxWddmDDevCreateOverlay;
5853 pCreateData->pDeviceFuncs->pfnUpdateOverlay = vboxWddmDDevUpdateOverlay;
5854 pCreateData->pDeviceFuncs->pfnFlipOverlay = vboxWddmDDevFlipOverlay;
5855 pCreateData->pDeviceFuncs->pfnGetOverlayColorControls = vboxWddmDDevGetOverlayColorControls;
5856 pCreateData->pDeviceFuncs->pfnSetOverlayColorControls = vboxWddmDDevSetOverlayColorControls;
5857 pCreateData->pDeviceFuncs->pfnDestroyOverlay = vboxWddmDDevDestroyOverlay;
5858 pCreateData->pDeviceFuncs->pfnDestroyDevice = vboxWddmDDevDestroyDevice;
5859 pCreateData->pDeviceFuncs->pfnQueryResourceResidency = vboxWddmDDevQueryResourceResidency;
5860 pCreateData->pDeviceFuncs->pfnOpenResource = vboxWddmDDevOpenResource;
5861 pCreateData->pDeviceFuncs->pfnGetCaptureAllocationHandle = vboxWddmDDevGetCaptureAllocationHandle;
5862 pCreateData->pDeviceFuncs->pfnCaptureToSysMem = vboxWddmDDevCaptureToSysMem;
5863 pCreateData->pDeviceFuncs->pfnLockAsync = NULL; //vboxWddmDDevLockAsync;
5864 pCreateData->pDeviceFuncs->pfnUnlockAsync = NULL; //vboxWddmDDevUnlockAsync;
5865 pCreateData->pDeviceFuncs->pfnRename = NULL; //vboxWddmDDevRename;
5866
5867 VBOXDISPPROFILE_DDI_INIT_DEV(pDevice);
5868#ifdef VBOX_WDDMDISP_WITH_PROFILE
5869 pDevice->ProfileDdiPresentCb = VBoxDispProfileSet("pfnPresentCb");
5870#endif
5871
5872#ifdef VBOXWDDMDISP_DEBUG_TIMER
5873 pDevice->hTimerQueue = CreateTimerQueue();
5874 Assert(pDevice->hTimerQueue);
5875#endif
5876
5877 do
5878 {
5879 RTListInit(&pDevice->SwapchainList);
5880 Assert(!pCreateData->AllocationListSize
5881 && !pCreateData->PatchLocationListSize);
5882 if (!pCreateData->AllocationListSize
5883 && !pCreateData->PatchLocationListSize)
5884 {
5885 {
5886 VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
5887
5888 hr = vboxDispCmCtxCreate(pDevice, &pDevice->DefaultContext);
5889 Assert(hr == S_OK);
5890 if (hr == S_OK)
5891 {
5892 #ifdef VBOXDISP_EARLYCREATEDEVICE
5893 PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
5894 Assert(pRc);
5895 if (pRc)
5896 {
5897 D3DPRESENT_PARAMETERS params;
5898 memset(&params, 0, sizeof (params));
5899 // params.BackBufferWidth = 640;
5900 // params.BackBufferHeight = 480;
5901 params.BackBufferWidth = 0x400;
5902 params.BackBufferHeight = 0x300;
5903 params.BackBufferFormat = D3DFMT_A8R8G8B8;
5904 // params.BackBufferCount = 0;
5905 params.BackBufferCount = 1;
5906 params.MultiSampleType = D3DMULTISAMPLE_NONE;
5907 params.SwapEffect = D3DSWAPEFFECT_DISCARD;
5908 // params.hDeviceWindow = hWnd;
5909 /* @todo: it seems there should be a way to detect this correctly since
5910 * our vboxWddmDDevSetDisplayMode will be called in case we are using full-screen */
5911 params.Windowed = TRUE;
5912 // params.EnableAutoDepthStencil = FALSE;
5913 // params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
5914 // params.Flags;
5915 // params.FullScreen_RefreshRateInHz;
5916 // params.FullScreen_PresentationInterval;
5917
5918 hr = vboxWddmD3DDeviceCreate(pDevice, 0, pRc, &params, TRUE /*BOOL bLockable*/);
5919 Assert(hr == S_OK);
5920 if (hr == S_OK)
5921 break;
5922 vboxResourceFree(pRc);
5923 }
5924 else
5925 {
5926 hr = E_OUTOFMEMORY;
5927 }
5928 #else
5929//# define VBOXDISP_TEST_SWAPCHAIN
5930# ifdef VBOXDISP_TEST_SWAPCHAIN
5931 VBOXDISP_D3DEV(pDevice);
5932# endif
5933 break;
5934 #endif
5935
5936 HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
5937 Assert(tmpHr == S_OK);
5938 }
5939 }
5940 }
5941 else
5942 {
5943 vboxVDbgPrintR((__FUNCTION__": Not implemented: PatchLocationListSize(%d), AllocationListSize(%d)\n",
5944 pCreateData->PatchLocationListSize, pCreateData->AllocationListSize));
5945 //pCreateData->pAllocationList = ??
5946 hr = E_FAIL;
5947 }
5948
5949 RTMemFree(pDevice);
5950 } while (0);
5951 }
5952 else
5953 {
5954 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
5955 hr = E_OUTOFMEMORY;
5956 }
5957
5958 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5959
5960 return hr;
5961}
5962
5963static HRESULT APIENTRY vboxWddmDispCloseAdapter (IN HANDLE hAdapter)
5964{
5965 VBOXDISP_DDI_PROLOGUE_ADP(hAdapter);
5966 vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5967
5968 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)hAdapter;
5969 if (VBOXDISPMODE_IS_3D(pAdapter))
5970 {
5971 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
5972 VBoxDispD3DGlobalClose(&pAdapter->D3D, &pAdapter->Formats);
5973 }
5974#ifdef VBOX_WITH_VIDEOHWACCEL
5975 else
5976 {
5977 VBoxDispD3DGlobal2DFormatsTerm(pAdapter);
5978 }
5979#endif
5980
5981 VBOXDISPPROFILE_DDI_TERM(pAdapter);
5982
5983 RTMemFree(pAdapter);
5984
5985 vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
5986
5987 return S_OK;
5988}
5989
5990#define VBOXDISP_IS_MODULE_FUNC(_pvModule, _cbModule, _pfn) ( \
5991 (((uintptr_t)(_pfn)) >= ((uintptr_t)(_pvModule))) \
5992 && (((uintptr_t)(_pfn)) < (((uintptr_t)(_pvModule)) + ((DWORD)(_cbModule)))) \
5993 )
5994
5995static BOOL vboxDispIsDDraw(__inout D3DDDIARG_OPENADAPTER* pOpenData)
5996{
5997 /*if we are loaded by ddraw module, the Interface version should be 7
5998 * and pAdapterCallbacks should be ddraw-supplied, i.e. reside in ddraw module */
5999 if (pOpenData->Interface != 7)
6000 return FALSE;
6001
6002 HMODULE hDDraw = GetModuleHandleA("ddraw.dll");
6003 if (!hDDraw)
6004 return FALSE;
6005
6006 HANDLE hProcess = GetCurrentProcess();
6007 MODULEINFO ModuleInfo = {0};
6008
6009 if (!GetModuleInformation(hProcess, hDDraw, &ModuleInfo, sizeof (ModuleInfo)))
6010 {
6011 DWORD winEr = GetLastError();
6012 WARN(("GetModuleInformation failed, %d", winEr));
6013 return FALSE;
6014 }
6015
6016 if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb))
6017 return TRUE;
6018 if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage, pOpenData->pAdapterCallbacks->pfnGetMultisampleMethodListCb))
6019 return TRUE;
6020
6021 return FALSE;
6022}
6023
6024HRESULT APIENTRY OpenAdapter(__inout D3DDDIARG_OPENADAPTER* pOpenData)
6025{
6026 VBOXDISP_DDI_PROLOGUE_GLBL();
6027
6028 vboxVDbgPrint(("==> "__FUNCTION__"\n"));
6029
6030#if 0 //def DEBUG_misha
6031 DWORD dwVersion = 0;
6032 DWORD dwMajorVersion = 0;
6033 DWORD dwMinorVersion = 0;
6034 dwVersion = GetVersion();
6035 dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
6036 dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
6037
6038 if (dwMajorVersion == 6 && dwMinorVersion <= 1 && VBOXVDBG_IS_DWM())
6039 {
6040 exit(0);
6041 return E_FAIL;
6042 }
6043#endif
6044
6045// vboxDispLock();
6046
6047 HRESULT hr = E_FAIL;
6048
6049 do
6050 {
6051
6052 LOGREL(("Built %s %s", __DATE__, __TIME__));
6053
6054 VBOXWDDM_QI Query;
6055 D3DDDICB_QUERYADAPTERINFO DdiQuery;
6056 DdiQuery.PrivateDriverDataSize = sizeof(Query);
6057 DdiQuery.pPrivateDriverData = &Query;
6058 hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
6059 Assert(hr == S_OK);
6060 if (hr != S_OK)
6061 {
6062 vboxVDbgPrintR((__FUNCTION__": pfnQueryAdapterInfoCb failed, hr (%d)\n", hr));
6063 hr = E_FAIL;
6064 break;
6065 }
6066
6067 /* check the miniport version match display version */
6068 if (Query.u32Version != VBOXVIDEOIF_VERSION)
6069 {
6070 vboxVDbgPrintR((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
6071 VBOXVIDEOIF_VERSION,
6072 Query.u32Version));
6073 hr = E_FAIL;
6074 break;
6075 }
6076
6077#ifdef VBOX_WITH_VIDEOHWACCEL
6078 Assert(Query.cInfos >= 1);
6079 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_OFFSETOF(VBOXWDDMDISP_ADAPTER, aHeads[Query.cInfos]));
6080#else
6081 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof (VBOXWDDMDISP_ADAPTER));
6082#endif
6083 Assert(pAdapter);
6084 if (pAdapter)
6085 {
6086 pAdapter->hAdapter = pOpenData->hAdapter;
6087 pAdapter->uIfVersion = pOpenData->Interface;
6088 pAdapter->uRtVersion= pOpenData->Version;
6089 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
6090
6091 pAdapter->cHeads = Query.cInfos;
6092
6093
6094 pOpenData->hAdapter = pAdapter;
6095 pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
6096 pOpenData->pAdapterFuncs->pfnCreateDevice = vboxWddmDispCreateDevice;
6097 pOpenData->pAdapterFuncs->pfnCloseAdapter = vboxWddmDispCloseAdapter;
6098 pOpenData->DriverVersion = D3D_UMD_INTERFACE_VERSION;
6099 if (!vboxDispIsDDraw(pOpenData))
6100 {
6101 do
6102 {
6103 {
6104 VBOXDISPCRHGSMI_SCOPE_SET_GLOBAL();
6105 /* try enable the 3D */
6106 hr = VBoxDispD3DGlobalOpen(&pAdapter->D3D, &pAdapter->Formats);
6107 if (hr == S_OK)
6108 {
6109 LOG(("SUCCESS 3D Enabled, pAdapter (0x%p)", pAdapter));
6110 break;
6111 }
6112 else
6113 WARN(("VBoxDispD3DOpen failed, hr (%d)", hr));
6114
6115 }
6116 } while (0);
6117 }
6118#ifdef VBOX_WITH_VIDEOHWACCEL
6119 if (!VBOXDISPMODE_IS_3D(pAdapter))
6120 {
6121 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
6122 {
6123 pAdapter->aHeads[i].Vhwa.Settings = Query.aInfos[i];
6124 }
6125 hr = VBoxDispD3DGlobal2DFormatsInit(pAdapter);
6126 if (!SUCCEEDED(hr))
6127 {
6128 WARN(("VBoxDispD3DGlobal2DFormatsInit failed hr 0x%x", hr));
6129 }
6130 }
6131#endif
6132
6133 if (SUCCEEDED(hr))
6134 {
6135 VBOXDISPPROFILE_DDI_INIT_ADP(pAdapter);
6136 hr = S_OK;
6137 break;
6138 }
6139 else
6140 {
6141 WARN(("OpenAdapter failed hr 0x%x", hr));
6142 }
6143
6144 RTMemFree(pAdapter);
6145 }
6146 else
6147 {
6148 vboxVDbgPrintR((__FUNCTION__": RTMemAllocZ returned NULL\n"));
6149 hr = E_OUTOFMEMORY;
6150 }
6151
6152 } while (0);
6153
6154// vboxDispUnlock();
6155
6156 vboxVDbgPrint(("<== "__FUNCTION__", hr (%d)\n", hr));
6157
6158 return hr;
6159}
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