VirtualBox

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

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

wddm/3d: gen hostid for primary surfaces

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