VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp@ 34440

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

iprt/list.h: RTListNodeGetFirst/Last -> RTListGetFirst/Last; added RTListGetNext, RTListGetPrev, RTListNodeInsertAfter and RTListNodeInsertBefore.

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

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