VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo-win.h@ 34349

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

Additions/WINNT/Graphics: more refactoring

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.4 KB
Line 
1/** @file
2 * VirtualBox Video miniport driver, Windows-specific header
3 *
4 * Copyright (C) 2006-2007 Oracle Corporation
5 *
6 * This file is part of VirtualBox Open Source Edition (OSE), as
7 * available from http://www.virtualbox.org. This file is free software;
8 * you can redistribute it and/or modify it under the terms of the GNU
9 * General Public License (GPL) as published by the Free Software
10 * Foundation, in version 2 as it comes in the "COPYING" file of the
11 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
12 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
13 */
14
15#ifndef VBOXVIDEO_WIN_H
16#define VBOXVIDEO_WIN_H
17
18#include "VBoxVideo.h"
19
20RT_C_DECLS_BEGIN
21#ifndef VBOX_WITH_WDDM
22#include "dderror.h"
23#include "devioctl.h"
24#include "miniport.h"
25#include "ntddvdeo.h"
26#include "video.h"
27#else
28# ifdef PAGE_SIZE
29# undef PAGE_SIZE
30# endif
31# ifdef PAGE_SHIFT
32# undef PAGE_SHIFT
33# endif
34# define VBOX_WITH_WORKAROUND_MISSING_PACK
35# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
36# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
37# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
38# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
39# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
40# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
41# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
42# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
43# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
44# pragma warning(disable : 4163)
45# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
46# pragma warning(disable : 4103)
47# endif
48# include <ntddk.h>
49# pragma warning(default : 4163)
50# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
51# pragma pack()
52# pragma warning(default : 4103)
53# endif
54# undef _InterlockedExchange
55# undef _InterlockedExchangeAdd
56# undef _InterlockedCompareExchange
57# undef _InterlockedAddLargeStatistic
58# undef _interlockedbittestandset
59# undef _interlockedbittestandreset
60# undef _interlockedbittestandset64
61# undef _interlockedbittestandreset64
62# else
63# include <ntddk.h>
64# endif
65#include "dispmprt.h"
66#include "ntddvdeo.h"
67#include "dderror.h"
68#endif
69RT_C_DECLS_END
70
71/* common API types */
72#ifdef VBOX_WITH_WDDM
73#define VBOX_WITH_GENERIC_MULTIMONITOR
74typedef struct _DEVICE_EXTENSION *PDEVICE_EXTENSION;
75#include <VBox/VBoxVideo.h>
76#include "wddm/VBoxVideoIf.h"
77#include "wddm/VBoxVideoMisc.h"
78#include "wddm/VBoxVideoShgsmi.h"
79#include "wddm/VBoxVideoCm.h"
80#include "wddm/VBoxVideoVdma.h"
81#include "wddm/VBoxVideoWddm.h"
82#include "wddm/VBoxVideoVidPn.h"
83#ifdef VBOXWDDM_WITH_VBVA
84# include "wddm/VBoxVideoVbva.h"
85#endif
86#ifdef VBOX_WITH_VIDEOHWACCEL
87# include "wddm/VBoxVideoVhwa.h"
88#endif
89
90#define VBOXWDDM_POINTER_ATTRIBUTES_SIZE VBOXWDDM_ROUNDBOUND( \
91 VBOXWDDM_ROUNDBOUND( sizeof (VIDEO_POINTER_ATTRIBUTES), 4 ) + \
92 VBOXWDDM_ROUNDBOUND(VBOXWDDM_C_POINTER_MAX_WIDTH * VBOXWDDM_C_POINTER_MAX_HEIGHT * 4, 4) + \
93 VBOXWDDM_ROUNDBOUND((VBOXWDDM_C_POINTER_MAX_WIDTH * VBOXWDDM_C_POINTER_MAX_HEIGHT + 7) >> 3, 4) \
94 , 8)
95
96typedef struct VBOXWDDM_POINTER_INFO
97{
98 uint32_t xPos;
99 uint32_t yPos;
100 union
101 {
102 VIDEO_POINTER_ATTRIBUTES data;
103 char buffer[VBOXWDDM_POINTER_ATTRIBUTES_SIZE];
104 } Attributes;
105} VBOXWDDM_POINTER_INFO, *PVBOXWDDM_POINTER_INFO;
106
107typedef struct VBOXWDDM_GLOBAL_POINTER_INFO
108{
109 uint32_t cVisible;
110} VBOXWDDM_GLOBAL_POINTER_INFO, *PVBOXWDDM_GLOBAL_POINTER_INFO;
111
112#ifdef VBOX_WITH_VIDEOHWACCEL
113typedef struct VBOXWDDM_VHWA
114{
115 VBOXVHWA_INFO Settings;
116 volatile uint32_t cOverlaysCreated;
117} VBOXWDDM_VHWA;
118#endif
119
120typedef struct VBOXWDDM_SOURCE
121{
122 struct VBOXWDDM_ALLOCATION * pPrimaryAllocation;
123#ifdef VBOXWDDM_RENDER_FROM_SHADOW
124 struct VBOXWDDM_ALLOCATION * pShadowAllocation;
125 VBOXVIDEOOFFSET offVram;
126 VBOXWDDM_SURFACE_DESC SurfDesc;
127 VBOXVBVAINFO Vbva;
128#endif
129#ifdef VBOX_WITH_VIDEOHWACCEL
130 /* @todo: in our case this seems more like a target property,
131 * but keep it here for now */
132 VBOXWDDM_VHWA Vhwa;
133 volatile uint32_t cOverlays;
134 LIST_ENTRY OverlayList;
135 KSPIN_LOCK OverlayListLock;
136#endif
137 POINT VScreenPos;
138 VBOXWDDM_POINTER_INFO PointerInfo;
139} VBOXWDDM_SOURCE, *PVBOXWDDM_SOURCE;
140
141typedef struct VBOXWDDM_TARGET
142{
143 uint32_t ScanLineState;
144 uint32_t HeightVisible;
145 uint32_t HeightTotal;
146} VBOXWDDM_TARGET, *PVBOXWDDM_TARGET;
147
148#endif
149
150typedef struct _DEVICE_EXTENSION
151{
152 struct _DEVICE_EXTENSION *pNext; /* Next extension in the DualView extension list.
153 * The primary extension is the first one.
154 */
155#ifndef VBOX_WITH_WDDM
156 struct _DEVICE_EXTENSION *pPrimary; /* Pointer to the primary device extension. */
157
158 ULONG iDevice; /* Device index: 0 for primary, otherwise a secondary device. */
159
160 ULONG CurrentMode; /* Saved information about video modes */
161 ULONG CurrentModeWidth;
162 ULONG CurrentModeHeight;
163 ULONG CurrentModeBPP;
164
165 ULONG ulFrameBufferOffset; /* The framebuffer position in the VRAM. */
166 ULONG ulFrameBufferSize; /* The size of the current framebuffer. */
167#endif
168 union {
169 /* Information that is only relevant to the primary device or is the same for all devices. */
170 struct {
171
172 void *pvReqFlush; /* Pointer to preallocated generic request structure for
173 * VMMDevReq_VideoAccelFlush. Allocated when VBVA status
174 * is changed. Deallocated on HwReset.
175 */
176
177
178 ULONG ulVbvaEnabled; /* Indicates that VBVA mode is enabled. */
179
180#ifdef VBOX_WITH_WDDM
181 VBOXVDMAINFO Vdma;
182# ifdef VBOXVDMA_WITH_VBVA
183 VBOXVBVAINFO Vbva;
184# endif
185#endif
186 ULONG ulMaxFrameBufferSize; /* The size of the VRAM allocated for the a single framebuffer. */
187
188 BOOLEAN fMouseHidden; /* Has the mouse cursor been hidden by the guest? */
189
190
191 VBOXVIDEO_COMMON commonInfo;
192#ifndef VBOX_WITH_WDDM
193 /* Video Port API dynamically picked up at runtime for binary backwards compatibility with older NT versions */
194 VBOXVIDEOPORTPROCS VideoPortProcs;
195#else
196 /* committed VidPn handle */
197 D3DKMDT_HVIDPN hCommittedVidPn;
198 /* Display Port handle and callbacks */
199 DXGKRNL_INTERFACE DxgkInterface;
200#endif
201 } primary;
202
203 /* Secondary device information. */
204 struct {
205 BOOLEAN bEnabled; /* Device enabled flag */
206 } secondary;
207 } u;
208
209 HGSMIAREA areaDisplay; /* Entire VRAM chunk for this display device. */
210
211#ifdef VBOX_WITH_WDDM
212 PDEVICE_OBJECT pPDO;
213 UNICODE_STRING RegKeyName;
214 UNICODE_STRING VideoGuid;
215
216 uint8_t * pvVisibleVram;
217
218 VBOXVIDEOCM_MGR CmMgr;
219 /* hgsmi allocation manager */
220 VBOXVIDEOCM_ALLOC_MGR AllocMgr;
221 VBOXVDMADDI_CMD_QUEUE DdiCmdQueue;
222 LIST_ENTRY SwapchainList3D;
223 /* mutex for context list operations */
224 FAST_MUTEX ContextMutex;
225 KSPIN_LOCK SynchLock;
226 volatile uint32_t cContexts3D;
227 volatile uint32_t cUnlockedVBVADisabled;
228
229 VBOXWDDM_GLOBAL_POINTER_INFO PointerInfo;
230
231 VBOXSHGSMILIST CtlList;
232 VBOXSHGSMILIST DmaCmdList;
233#ifdef VBOX_WITH_VIDEOHWACCEL
234 VBOXSHGSMILIST VhwaCmdList;
235#endif
236// BOOL bSetNotifyDxDpc;
237 BOOL bNotifyDxDpc;
238
239 VBOXWDDM_SOURCE aSources[VBOX_VIDEO_MAX_SCREENS];
240 VBOXWDDM_TARGET aTargets[VBOX_VIDEO_MAX_SCREENS];
241#endif
242 BOOLEAN fAnyX; /* Unrestricted horizontal resolution flag. */
243} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
244
245static inline PVBOXVIDEO_COMMON commonFromDeviceExt(PDEVICE_EXTENSION pExt)
246{
247#ifndef VBOX_WITH_WDDM
248 return &pExt->pPrimary->u.primary.commonInfo;
249#else
250 return &pExt->u.primary.commonInfo;
251#endif
252}
253
254static inline PDEVICE_EXTENSION commonToPrimaryExt(PVBOXVIDEO_COMMON pCommon)
255{
256 return RT_FROM_MEMBER(pCommon, DEVICE_EXTENSION, u.primary.commonInfo);
257}
258
259static inline bool vboxUpdatePointerShapeWrap(PVBOXVIDEO_COMMON pCommon,
260 PVIDEO_POINTER_ATTRIBUTES pointerAttr,
261 uint32_t cbLength)
262{
263 return vboxUpdatePointerShape(&pCommon->guestCtx,
264 pointerAttr->Enable & 0x0000FFFF,
265 (pointerAttr->Enable >> 16) & 0xFF,
266 (pointerAttr->Enable >> 24) & 0xFF,
267 pointerAttr->Width,
268 pointerAttr->Height,
269 pointerAttr->Pixels,
270 cbLength - sizeof(VIDEO_POINTER_ATTRIBUTES));
271}
272
273#ifndef VBOX_WITH_WDDM
274#define DEV_MOUSE_HIDDEN(dev) ((dev)->pPrimary->u.primary.fMouseHidden)
275#define DEV_SET_MOUSE_HIDDEN(dev) \
276do { \
277 (dev)->pPrimary->u.primary.fMouseHidden = TRUE; \
278} while (0)
279#define DEV_SET_MOUSE_SHOWN(dev) \
280do { \
281 (dev)->pPrimary->u.primary.fMouseHidden = FALSE; \
282} while (0)
283#else
284#define DEV_MOUSE_HIDDEN(dev) ((dev)->u.primary.fMouseHidden)
285#define DEV_SET_MOUSE_HIDDEN(dev) \
286do { \
287 (dev)->u.primary.fMouseHidden = TRUE; \
288} while (0)
289#define DEV_SET_MOUSE_SHOWN(dev) \
290do { \
291 (dev)->u.primary.fMouseHidden = FALSE; \
292} while (0)
293#endif
294
295extern "C"
296{
297#ifndef VBOX_WITH_WDDM
298
299RT_C_DECLS_BEGIN
300ULONG DriverEntry(IN PVOID Context1, IN PVOID Context2);
301RT_C_DECLS_END
302
303#else
304
305RT_C_DECLS_BEGIN
306NTSTATUS
307DriverEntry(
308 IN PDRIVER_OBJECT DriverObject,
309 IN PUNICODE_STRING RegistryPath
310 );
311RT_C_DECLS_END
312
313PVBOXWDDM_VIDEOMODES_INFO vboxWddmGetVideoModesInfo(PDEVICE_EXTENSION DeviceExtension, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
314PVBOXWDDM_VIDEOMODES_INFO vboxWddmGetAllVideoModesInfos(PDEVICE_EXTENSION DeviceExtension);
315PVBOXWDDM_VIDEOMODES_INFO vboxWddmUpdateVideoModesInfo(PDEVICE_EXTENSION DeviceExtension, PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo);
316
317void vboxVideoInitCustomVideoModes(PDEVICE_EXTENSION pDevExt);
318
319VOID vboxWddmInvalidateVideoModesInfo(PDEVICE_EXTENSION DeviceExtension);
320
321/* @return STATUS_BUFFER_TOO_SMALL - if buffer is too small, STATUS_SUCCESS - on success */
322NTSTATUS vboxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,
323 const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes, uint32_t cModes, uint32_t *pcModes, int32_t *piPreferrableMode);
324
325int vboxVideoModeFind(const VIDEO_MODE_INFORMATION *pModes, int cModes, const VIDEO_MODE_INFORMATION *pM);
326int vboxWddmVideoResolutionFind(const D3DKMDT_2DREGION *pResolutions, int cResolutions, const D3DKMDT_2DREGION *pRes);
327bool vboxWddmVideoResolutionsMatch(const D3DKMDT_2DREGION *pResolutions1, const D3DKMDT_2DREGION *pResolutions2, int cResolutions);
328bool vboxWddmVideoModesMatch(const VIDEO_MODE_INFORMATION *pModes1, const VIDEO_MODE_INFORMATION *pModes2, int cModes);
329
330D3DDDIFORMAT vboxWddmCalcPixelFormat(const VIDEO_MODE_INFORMATION *pInfo);
331bool vboxWddmFillMode(VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h);
332
333DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PDEVICE_EXTENSION pDevExt)
334{
335#ifdef VBOXWDDM_RENDER_FROM_SHADOW
336 /* all memory layout info should be initialized */
337 Assert(pDevExt->aSources[0].Vbva.offVBVA);
338 /* page aligned */
339 Assert(!(pDevExt->aSources[0].Vbva.offVBVA & 0xfff));
340
341 return (ULONG)(pDevExt->aSources[0].Vbva.offVBVA & ~0xfffULL);
342#else
343 /* all memory layout info should be initialized */
344 Assert(pDevExt->u.primary.Vdma.CmdHeap.area.offBase);
345 /* page aligned */
346 Assert(!(pDevExt->u.primary.Vdma.CmdHeap.area.offBase & 0xfff));
347
348 return pDevExt->u.primary.Vdma.CmdHeap.area.offBase & ~0xfffUL;
349#endif
350}
351
352DECLINLINE(ULONG) vboxWddmVramCpuVisibleSegmentSize(PDEVICE_EXTENSION pDevExt)
353{
354 return vboxWddmVramCpuVisibleSize(pDevExt);
355}
356
357#ifdef VBOXWDDM_RENDER_FROM_SHADOW
358DECLINLINE(ULONG) vboxWddmVramCpuInvisibleSegmentSize(PDEVICE_EXTENSION pDevExt)
359{
360 return vboxWddmVramCpuVisibleSegmentSize(pDevExt);
361}
362
363DECLINLINE(bool) vboxWddmCmpSurfDescsBase(VBOXWDDM_SURFACE_DESC *pDesc1, VBOXWDDM_SURFACE_DESC *pDesc2)
364{
365 if (pDesc1->width != pDesc2->width)
366 return false;
367 if (pDesc1->height != pDesc2->height)
368 return false;
369 if (pDesc1->format != pDesc2->format)
370 return false;
371 if (pDesc1->bpp != pDesc2->bpp)
372 return false;
373 if (pDesc1->pitch != pDesc2->pitch)
374 return false;
375 return true;
376}
377
378DECLINLINE(void) vboxWddmAssignShadow(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
379{
380 if (pSource->pShadowAllocation == pAllocation)
381 {
382 Assert(pAllocation->bAssigned);
383 return;
384 }
385
386 if (pSource->pShadowAllocation)
387 {
388 PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pShadowAllocation;
389 /* clear the visibility info fo the current primary */
390 pOldAlloc->bVisible = FALSE;
391 pOldAlloc->bAssigned = FALSE;
392 Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
393 /* release the shadow surface */
394 pOldAlloc->SurfDesc.VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
395 }
396
397 if (pAllocation)
398 {
399 Assert(!pAllocation->bAssigned);
400 Assert(!pAllocation->bVisible);
401 pAllocation->bVisible = FALSE;
402 /* this check ensures the shadow is not used for other source simultaneously */
403 Assert(pAllocation->SurfDesc.VidPnSourceId == D3DDDI_ID_UNINITIALIZED);
404 pAllocation->SurfDesc.VidPnSourceId = srcId;
405 pAllocation->bAssigned = TRUE;
406 if (!vboxWddmCmpSurfDescsBase(&pSource->SurfDesc, &pAllocation->SurfDesc))
407 pSource->offVram = VBOXVIDEOOFFSET_VOID; /* force guest->host notification */
408 pSource->SurfDesc = pAllocation->SurfDesc;
409 }
410
411 pSource->pShadowAllocation = pAllocation;
412}
413#endif
414
415DECLINLINE(VOID) vboxWddmAssignPrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
416{
417 if (pSource->pPrimaryAllocation == pAllocation)
418 return;
419
420 if (pSource->pPrimaryAllocation)
421 {
422 PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pPrimaryAllocation;
423 /* clear the visibility info fo the current primary */
424 pOldAlloc->bVisible = FALSE;
425 pOldAlloc->bAssigned = FALSE;
426 Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
427 }
428
429 if (pAllocation)
430 {
431 pAllocation->bVisible = FALSE;
432 Assert(pAllocation->SurfDesc.VidPnSourceId == srcId);
433 pAllocation->SurfDesc.VidPnSourceId = srcId;
434 pAllocation->bAssigned = TRUE;
435 }
436
437 pSource->pPrimaryAllocation = pAllocation;
438}
439
440
441#endif
442
443BOOLEAN FASTCALL VBoxVideoSetCurrentModePerform(PDEVICE_EXTENSION DeviceExtension,
444 USHORT width, USHORT height, USHORT bpp
445#ifdef VBOX_WITH_WDDM
446 , ULONG offDisplay
447#endif
448 );
449
450BOOLEAN FASTCALL VBoxVideoSetCurrentMode(
451 PDEVICE_EXTENSION DeviceExtension,
452 PVIDEO_MODE RequestedMode,
453 PSTATUS_BLOCK StatusBlock);
454
455BOOLEAN FASTCALL VBoxVideoResetDevice(
456 PDEVICE_EXTENSION DeviceExtension,
457 PSTATUS_BLOCK StatusBlock);
458
459BOOLEAN FASTCALL VBoxVideoMapVideoMemory(
460 PDEVICE_EXTENSION DeviceExtension,
461 PVIDEO_MEMORY RequestedAddress,
462 PVIDEO_MEMORY_INFORMATION MapInformation,
463 PSTATUS_BLOCK StatusBlock);
464
465BOOLEAN FASTCALL VBoxVideoUnmapVideoMemory(
466 PDEVICE_EXTENSION DeviceExtension,
467 PVIDEO_MEMORY VideoMemory,
468 PSTATUS_BLOCK StatusBlock);
469
470BOOLEAN FASTCALL VBoxVideoQueryNumAvailModes(
471 PDEVICE_EXTENSION DeviceExtension,
472 PVIDEO_NUM_MODES Modes,
473 PSTATUS_BLOCK StatusBlock);
474
475BOOLEAN FASTCALL VBoxVideoQueryAvailModes(
476 PDEVICE_EXTENSION DeviceExtension,
477 PVIDEO_MODE_INFORMATION ReturnedModes,
478 PSTATUS_BLOCK StatusBlock);
479
480BOOLEAN FASTCALL VBoxVideoQueryCurrentMode(
481 PDEVICE_EXTENSION DeviceExtension,
482 PVIDEO_MODE_INFORMATION VideoModeInfo,
483 PSTATUS_BLOCK StatusBlock);
484
485BOOLEAN FASTCALL VBoxVideoSetColorRegisters(
486 PDEVICE_EXTENSION DeviceExtension,
487 PVIDEO_CLUT ColorLookUpTable,
488 PSTATUS_BLOCK StatusBlock);
489
490void VBoxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension);
491} /* extern "C" */
492
493#endif /* VBOXVIDEO_WIN_H */
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