VirtualBox

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

Last change on this file since 42124 was 41858, checked in by vboxsync, 13 years ago

wddm/3d: better event query support

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

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