VirtualBox

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

Last change on this file since 63026 was 63026, checked in by vboxsync, 8 years ago

GA/NT/Graphics: warnings

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