VirtualBox

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

Last change on this file since 72621 was 72621, checked in by vboxsync, 7 years ago

WDDM: display driver: handle the case when VBOXWDDMDISP_DEVICE::DefaultContext is not initialized

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

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