VirtualBox

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

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

WDDM: VBoxDispD3D: D3D backend creation cleanup.

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