VirtualBox

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

Last change on this file since 37423 was 37423, checked in by vboxsync, 14 years ago

Ran the source code massager (scm).

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