VirtualBox

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

Last change on this file since 52804 was 52804, checked in by vboxsync, 11 years ago

wddm: typo fix

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

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