VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h@ 33628

Last change on this file since 33628 was 33628, 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: 28.0 KB
Line 
1/** @file
2 * VirtualBox Video miniport driver
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_H
16#define VBOXVIDEO_H
17
18#include <VBox/cdefs.h>
19#include <VBox/types.h>
20#include <iprt/assert.h>
21
22//#include <iprt/thread.h>
23
24#include <VBox/HGSMI/HGSMI.h>
25#include <VBox/HGSMI/HGSMIChSetup.h>
26#include <VBox/VBoxVideo.h>
27#include "VBoxHGSMI.h"
28
29RT_C_DECLS_BEGIN
30#ifndef VBOX_WITH_WDDM
31#include "dderror.h"
32#include "devioctl.h"
33#include "miniport.h"
34#include "ntddvdeo.h"
35#include "video.h"
36#else
37# ifdef PAGE_SIZE
38# undef PAGE_SIZE
39# endif
40# ifdef PAGE_SHIFT
41# undef PAGE_SHIFT
42# endif
43# define VBOX_WITH_WORKAROUND_MISSING_PACK
44# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
45# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
46# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
47# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
48# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
49# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
50# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
51# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
52# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
53# pragma warning(disable : 4163)
54# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
55# pragma warning(disable : 4103)
56# endif
57# include <ntddk.h>
58# pragma warning(default : 4163)
59# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
60# pragma pack()
61# pragma warning(default : 4103)
62# endif
63# undef _InterlockedExchange
64# undef _InterlockedExchangeAdd
65# undef _InterlockedCompareExchange
66# undef _InterlockedAddLargeStatistic
67# undef _interlockedbittestandset
68# undef _interlockedbittestandreset
69# undef _interlockedbittestandset64
70# undef _interlockedbittestandreset64
71# else
72# include <ntddk.h>
73# endif
74#include "dispmprt.h"
75#include "ntddvdeo.h"
76#include "dderror.h"
77#endif
78RT_C_DECLS_END
79
80#define VBE_DISPI_IOPORT_INDEX 0x01CE
81#define VBE_DISPI_IOPORT_DATA 0x01CF
82#define VBE_DISPI_INDEX_ID 0x0
83#define VBE_DISPI_INDEX_XRES 0x1
84#define VBE_DISPI_INDEX_YRES 0x2
85#define VBE_DISPI_INDEX_BPP 0x3
86#define VBE_DISPI_INDEX_ENABLE 0x4
87#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
88#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
89#define VBE_DISPI_INDEX_X_OFFSET 0x8
90#define VBE_DISPI_INDEX_Y_OFFSET 0x9
91#define VBE_DISPI_INDEX_VBOX_VIDEO 0xa
92
93#define VBE_DISPI_ID2 0xB0C2
94/* The VBOX interface id. Indicates support for VBE_DISPI_INDEX_VBOX_VIDEO. */
95#define VBE_DISPI_ID_VBOX_VIDEO 0xBE00
96#define VBE_DISPI_ID_HGSMI 0xBE01
97#define VBE_DISPI_ID_ANYX 0xBE02
98#define VBE_DISPI_DISABLED 0x00
99#define VBE_DISPI_ENABLED 0x01
100#define VBE_DISPI_LFB_ENABLED 0x40
101#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
102#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4
103#define VBE_DISPI_TOTAL_VIDEO_MEMORY_KB (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024)
104#define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)
105
106#define VGA_PORT_HGSMI_HOST 0x3b0
107#define VGA_PORT_HGSMI_GUEST 0x3d0
108
109/* common API types */
110#ifndef VBOX_WITH_WDDM
111typedef PSPIN_LOCK VBOXVCMNSPIN_LOCK, *PVBOXVCMNSPIN_LOCK;
112typedef UCHAR VBOXVCMNIRQL, *PVBOXVCMNIRQL;
113
114typedef PEVENT VBOXVCMNEVENT;
115typedef VBOXVCMNEVENT *PVBOXVCMNEVENT;
116
117typedef struct _DEVICE_EXTENSION * VBOXCMNREG;
118#else
119typedef struct _DEVICE_EXTENSION *PDEVICE_EXTENSION;
120#include <VBox/VBoxVideo.h>
121#include "wddm/VBoxVideoIf.h"
122#include "wddm/VBoxVideoMisc.h"
123#include "wddm/VBoxVideoShgsmi.h"
124#include "wddm/VBoxVideoCm.h"
125#include "wddm/VBoxVideoVdma.h"
126#include "wddm/VBoxVideoWddm.h"
127#include "wddm/VBoxVideoVidPn.h"
128#ifdef VBOXWDDM_WITH_VBVA
129# include "wddm/VBoxVideoVbva.h"
130#endif
131#ifdef VBOX_WITH_VIDEOHWACCEL
132# include "wddm/VBoxVideoVhwa.h"
133#endif
134
135
136typedef KSPIN_LOCK VBOXVCMNSPIN_LOCK, *PVBOXVCMNSPIN_LOCK;
137typedef KIRQL VBOXVCMNIRQL, *PVBOXVCMNIRQL;
138
139typedef KEVENT VBOXVCMNEVENT;
140typedef VBOXVCMNEVENT *PVBOXVCMNEVENT;
141
142typedef HANDLE VBOXCMNREG;
143
144#define VBOXWDDM_POINTER_ATTRIBUTES_SIZE VBOXWDDM_ROUNDBOUND( \
145 VBOXWDDM_ROUNDBOUND( sizeof (VIDEO_POINTER_ATTRIBUTES), 4 ) + \
146 VBOXWDDM_ROUNDBOUND(VBOXWDDM_C_POINTER_MAX_WIDTH * VBOXWDDM_C_POINTER_MAX_HEIGHT * 4, 4) + \
147 VBOXWDDM_ROUNDBOUND((VBOXWDDM_C_POINTER_MAX_WIDTH * VBOXWDDM_C_POINTER_MAX_HEIGHT + 7) >> 3, 4) \
148 , 8)
149
150typedef struct VBOXWDDM_POINTER_INFO
151{
152 uint32_t xPos;
153 uint32_t yPos;
154 union
155 {
156 VIDEO_POINTER_ATTRIBUTES data;
157 char buffer[VBOXWDDM_POINTER_ATTRIBUTES_SIZE];
158 } Attributes;
159} VBOXWDDM_POINTER_INFO, *PVBOXWDDM_POINTER_INFO;
160
161typedef struct VBOXWDDM_GLOBAL_POINTER_INFO
162{
163 uint32_t cVisible;
164} VBOXWDDM_GLOBAL_POINTER_INFO, *PVBOXWDDM_GLOBAL_POINTER_INFO;
165
166#ifdef VBOX_WITH_VIDEOHWACCEL
167typedef struct VBOXWDDM_VHWA
168{
169 VBOXVHWA_INFO Settings;
170 volatile uint32_t cOverlaysCreated;
171} VBOXWDDM_VHWA;
172#endif
173
174typedef struct VBOXWDDM_SOURCE
175{
176 struct VBOXWDDM_ALLOCATION * pPrimaryAllocation;
177#ifdef VBOXWDDM_RENDER_FROM_SHADOW
178 struct VBOXWDDM_ALLOCATION * pShadowAllocation;
179 VBOXVIDEOOFFSET offVram;
180 VBOXWDDM_SURFACE_DESC SurfDesc;
181 VBOXVBVAINFO Vbva;
182#endif
183#ifdef VBOX_WITH_VIDEOHWACCEL
184 /* @todo: in our case this seems more like a target property,
185 * but keep it here for now */
186 VBOXWDDM_VHWA Vhwa;
187 volatile uint32_t cOverlays;
188 LIST_ENTRY OverlayList;
189 KSPIN_LOCK OverlayListLock;
190#endif
191 POINT VScreenPos;
192 VBOXWDDM_POINTER_INFO PointerInfo;
193} VBOXWDDM_SOURCE, *PVBOXWDDM_SOURCE;
194
195typedef struct VBOXWDDM_TARGET
196{
197 uint32_t ScanLineState;
198 uint32_t HeightVisible;
199 uint32_t HeightTotal;
200} VBOXWDDM_TARGET, *PVBOXWDDM_TARGET;
201
202#endif
203
204typedef struct VBOXVIDEO_COMMON
205{
206 int cDisplays; /* Number of displays. */
207
208 ULONG cbVRAM; /* The VRAM size. */
209
210 ULONG cbMiniportHeap; /* The size of reserved VRAM for miniport driver heap.
211 * It is at offset:
212 * cbAdapterMemorySize - VBOX_VIDEO_ADAPTER_INFORMATION_SIZE - cbMiniportHeap
213 */
214 PVOID pvMiniportHeap; /* The pointer to the miniport heap VRAM.
215 * This is mapped by miniport separately.
216 */
217 volatile HGSMIHOSTFLAGS * pHostFlags; /* HGSMI host flags */
218 volatile bool bHostCmdProcessing;
219
220 PVOID pvAdapterInformation; /* The pointer to the last 4K of VRAM.
221 * This is mapped by miniport separately.
222 */
223
224 /** Host HGSMI capabilities the guest can handle */
225 uint32_t fCaps;
226
227 BOOLEAN bHGSMI; /* Whether HGSMI is enabled. */
228
229 HGSMIAREA areaHostHeap; /* Host heap VRAM area. */
230
231 HGSMICHANNELINFO channels;
232
233 HGSMIHEAP hgsmiAdapterHeap;
234
235 /* The IO Port Number for host commands. */
236 RTIOPORT IOPortHost;
237
238 /* The IO Port Number for guest commands. */
239 RTIOPORT IOPortGuest;
240} VBOXVIDEO_COMMON, *PVBOXVIDEO_COMMON;
241
242typedef struct _DEVICE_EXTENSION
243{
244 struct _DEVICE_EXTENSION *pNext; /* Next extension in the DualView extension list.
245 * The primary extension is the first one.
246 */
247#ifndef VBOX_WITH_WDDM
248 struct _DEVICE_EXTENSION *pPrimary; /* Pointer to the primary device extension. */
249
250 ULONG iDevice; /* Device index: 0 for primary, otherwise a secondary device. */
251
252 ULONG CurrentMode; /* Saved information about video modes */
253 ULONG CurrentModeWidth;
254 ULONG CurrentModeHeight;
255 ULONG CurrentModeBPP;
256
257 ULONG ulFrameBufferOffset; /* The framebuffer position in the VRAM. */
258 ULONG ulFrameBufferSize; /* The size of the current framebuffer. */
259#endif
260 union {
261 /* Information that is only relevant to the primary device or is the same for all devices. */
262 struct {
263
264 void *pvReqFlush; /* Pointer to preallocated generic request structure for
265 * VMMDevReq_VideoAccelFlush. Allocated when VBVA status
266 * is changed. Deallocated on HwReset.
267 */
268
269
270 ULONG ulVbvaEnabled; /* Indicates that VBVA mode is enabled. */
271
272#ifdef VBOX_WITH_WDDM
273 VBOXVDMAINFO Vdma;
274# ifdef VBOXVDMA_WITH_VBVA
275 VBOXVBVAINFO Vbva;
276# endif
277#endif
278 ULONG ulMaxFrameBufferSize; /* The size of the VRAM allocated for the a single framebuffer. */
279
280 BOOLEAN fMouseHidden; /* Has the mouse cursor been hidden by the guest? */
281
282
283 VBOXVIDEO_COMMON commonInfo;
284#ifndef VBOX_WITH_WDDM
285 /* Video Port API dynamically picked up at runtime for binary backwards compatibility with older NT versions */
286 VBOXVIDEOPORTPROCS VideoPortProcs;
287#else
288 /* committed VidPn handle */
289 D3DKMDT_HVIDPN hCommittedVidPn;
290 /* Display Port handle and callbacks */
291 DXGKRNL_INTERFACE DxgkInterface;
292#endif
293 } primary;
294
295 /* Secondary device information. */
296 struct {
297 BOOLEAN bEnabled; /* Device enabled flag */
298 } secondary;
299 } u;
300
301 HGSMIAREA areaDisplay; /* Entire VRAM chunk for this display device. */
302
303#ifdef VBOX_WITH_WDDM
304 PDEVICE_OBJECT pPDO;
305 UNICODE_STRING RegKeyName;
306 UNICODE_STRING VideoGuid;
307
308 uint8_t * pvVisibleVram;
309
310 VBOXVIDEOCM_MGR CmMgr;
311 /* hgsmi allocation manager */
312 VBOXVIDEOCM_ALLOC_MGR AllocMgr;
313 VBOXVDMADDI_CMD_QUEUE DdiCmdQueue;
314 LIST_ENTRY SwapchainList3D;
315 /* mutex for context list operations */
316 FAST_MUTEX ContextMutex;
317 KSPIN_LOCK SynchLock;
318 volatile uint32_t cContexts3D;
319 volatile uint32_t cUnlockedVBVADisabled;
320
321 VBOXWDDM_GLOBAL_POINTER_INFO PointerInfo;
322
323 VBOXSHGSMILIST CtlList;
324 VBOXSHGSMILIST DmaCmdList;
325#ifdef VBOX_WITH_VIDEOHWACCEL
326 VBOXSHGSMILIST VhwaCmdList;
327#endif
328// BOOL bSetNotifyDxDpc;
329 BOOL bNotifyDxDpc;
330
331 VBOXWDDM_SOURCE aSources[VBOX_VIDEO_MAX_SCREENS];
332 VBOXWDDM_TARGET aTargets[VBOX_VIDEO_MAX_SCREENS];
333#endif
334 BOOLEAN fAnyX; /* Unrestricted horizontal resolution flag. */
335} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
336
337static inline PVBOXVIDEO_COMMON commonFromDeviceExt(PDEVICE_EXTENSION pExt)
338{
339#ifndef VBOX_WITH_WDDM
340 return &pExt->pPrimary->u.primary.commonInfo;
341#else
342 return &pExt->u.primary.commonInfo;
343#endif
344}
345
346static inline PDEVICE_EXTENSION commonToPrimaryExt(PVBOXVIDEO_COMMON pCommon)
347{
348 return RT_FROM_MEMBER(pCommon, DEVICE_EXTENSION, u.primary.commonInfo);
349}
350
351#ifndef VBOX_WITH_WDDM
352#define DEV_MOUSE_HIDDEN(dev) ((dev)->pPrimary->u.primary.fMouseHidden)
353#define DEV_SET_MOUSE_HIDDEN(dev) \
354do { \
355 (dev)->pPrimary->u.primary.fMouseHidden = TRUE; \
356} while (0)
357#define DEV_SET_MOUSE_SHOWN(dev) \
358do { \
359 (dev)->pPrimary->u.primary.fMouseHidden = FALSE; \
360} while (0)
361#else
362#define DEV_MOUSE_HIDDEN(dev) ((dev)->u.primary.fMouseHidden)
363#define DEV_SET_MOUSE_HIDDEN(dev) \
364do { \
365 (dev)->u.primary.fMouseHidden = TRUE; \
366} while (0)
367#define DEV_SET_MOUSE_SHOWN(dev) \
368do { \
369 (dev)->u.primary.fMouseHidden = FALSE; \
370} while (0)
371#endif
372extern "C"
373{
374#ifndef VBOX_WITH_WDDM
375/* XPDM-WDDM common API */
376
377typedef PEVENT VBOXVCMNEVENT;
378typedef VBOXVCMNEVENT *PVBOXVCMNEVENT;
379
380DECLINLINE(VOID) VBoxVideoCmnPortWriteUchar(IN PUCHAR Port, IN UCHAR Value)
381{
382 VideoPortWritePortUchar(Port,Value);
383}
384
385DECLINLINE(VOID) VBoxVideoCmnPortWriteUshort(IN PUSHORT Port, IN USHORT Value)
386{
387 VideoPortWritePortUshort(Port,Value);
388}
389
390DECLINLINE(VOID) VBoxVideoCmnPortWriteUlong(IN PULONG Port, IN ULONG Value)
391{
392 VideoPortWritePortUlong(Port,Value);
393}
394
395DECLINLINE(UCHAR) VBoxVideoCmnPortReadUchar(IN PUCHAR Port)
396{
397 return VideoPortReadPortUchar(Port);
398}
399
400DECLINLINE(USHORT) VBoxVideoCmnPortReadUshort(IN PUSHORT Port)
401{
402 return VideoPortReadPortUshort(Port);
403}
404
405DECLINLINE(ULONG) VBoxVideoCmnPortReadUlong(IN PULONG Port)
406{
407 return VideoPortReadPortUlong(Port);
408}
409
410DECLINLINE(VOID) VBoxVideoCmnMemZero(PVOID pvMem, ULONG cbMem)
411{
412 VideoPortZeroMemory(pvMem, cbMem);
413}
414
415DECLINLINE(VOID) VBoxVideoCmnSpinLockAcquire(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock, OUT PVBOXVCMNIRQL OldIrql)
416{
417 pDeviceExtension->u.primary.VideoPortProcs.pfnAcquireSpinLock(pDeviceExtension, *SpinLock, OldIrql);
418}
419
420DECLINLINE(VOID) VBoxVideoCmnSpinLockAcquireAtDpcLevel(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
421{
422 pDeviceExtension->u.primary.VideoPortProcs.pfnAcquireSpinLockAtDpcLevel(pDeviceExtension, *SpinLock);
423}
424
425DECLINLINE(VOID) VBoxVideoCmnSpinLockRelease(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock, IN VBOXVCMNIRQL NewIrql)
426{
427 pDeviceExtension->u.primary.VideoPortProcs.pfnReleaseSpinLock(pDeviceExtension, *SpinLock, NewIrql);
428}
429
430DECLINLINE(VOID) VBoxVideoCmnSpinLockReleaseFromDpcLevel(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
431{
432 pDeviceExtension->u.primary.VideoPortProcs.pfnReleaseSpinLockFromDpcLevel(pDeviceExtension, *SpinLock);
433}
434
435DECLINLINE(VP_STATUS) VBoxVideoCmnSpinLockCreate(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
436{
437 return pDeviceExtension->u.primary.VideoPortProcs.pfnCreateSpinLock(pDeviceExtension, SpinLock);
438}
439
440DECLINLINE(VP_STATUS) VBoxVideoCmnSpinLockDelete(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
441{
442 return pDeviceExtension->u.primary.VideoPortProcs.pfnDeleteSpinLock(pDeviceExtension, *SpinLock);
443}
444
445DECLINLINE(LONG) VBoxVideoCmnEventSet(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent)
446{
447 return pDeviceExtension->u.primary.VideoPortProcs.pfnSetEvent(pDeviceExtension, (VBOXPEVENT)*pEvent); /** @todo slightly bogus cast */
448}
449
450DECLINLINE(VP_STATUS) VBoxVideoCmnEventCreateNotification(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent, IN BOOLEAN bSignaled)
451{
452 ULONG fFlags = NOTIFICATION_EVENT;
453 if(bSignaled)
454 fFlags |= INITIAL_EVENT_SIGNALED;
455
456 return pDeviceExtension->u.primary.VideoPortProcs.pfnCreateEvent(pDeviceExtension, fFlags, NULL, (VBOXPEVENT *)pEvent); /** @todo slightly bogus cast */
457}
458
459DECLINLINE(VP_STATUS) VBoxVideoCmnEventDelete(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent)
460{
461 return pDeviceExtension->u.primary.VideoPortProcs.pfnDeleteEvent(pDeviceExtension, (VBOXPEVENT)*pEvent); /** @todo slightly bogus cast */
462}
463
464DECLINLINE(PVOID) VBoxVideoCmnMemAllocNonPaged(IN PDEVICE_EXTENSION pDeviceExtension, IN SIZE_T NumberOfBytes, IN ULONG Tag)
465{
466 return pDeviceExtension->u.primary.VideoPortProcs.pfnAllocatePool(pDeviceExtension, (VBOXVP_POOL_TYPE)VpNonPagedPool, NumberOfBytes, Tag);
467}
468
469DECLINLINE(VOID) VBoxVideoCmnMemFree(IN PDEVICE_EXTENSION pDeviceExtension, IN PVOID Ptr)
470{
471 pDeviceExtension->u.primary.VideoPortProcs.pfnFreePool(pDeviceExtension, Ptr);
472}
473
474DECLINLINE(VP_STATUS) VBoxVideoCmnRegInit(IN PDEVICE_EXTENSION pDeviceExtension, OUT VBOXCMNREG *pReg)
475{
476 *pReg = pDeviceExtension->pPrimary;
477 return NO_ERROR;
478}
479
480DECLINLINE(VP_STATUS) VBoxVideoCmnRegFini(IN VBOXCMNREG Reg)
481{
482 return NO_ERROR;
483}
484
485VP_STATUS VBoxVideoCmnRegQueryDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t *pVal);
486
487VP_STATUS VBoxVideoCmnRegSetDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t Val);
488
489/* */
490
491RT_C_DECLS_BEGIN
492ULONG DriverEntry(IN PVOID Context1, IN PVOID Context2);
493RT_C_DECLS_END
494
495#else
496
497/* XPDM-WDDM common API */
498DECLINLINE(VOID) VBoxVideoCmnPortWriteUchar(IN PUCHAR Port, IN UCHAR Value)
499{
500 WRITE_PORT_UCHAR(Port,Value);
501}
502
503DECLINLINE(VOID) VBoxVideoCmnPortWriteUshort(IN PUSHORT Port, IN USHORT Value)
504{
505 WRITE_PORT_USHORT(Port,Value);
506}
507
508DECLINLINE(VOID) VBoxVideoCmnPortWriteUlong(IN PULONG Port, IN ULONG Value)
509{
510 WRITE_PORT_ULONG(Port,Value);
511}
512
513DECLINLINE(UCHAR) VBoxVideoCmnPortReadUchar(IN PUCHAR Port)
514{
515 return READ_PORT_UCHAR(Port);
516}
517
518DECLINLINE(USHORT) VBoxVideoCmnPortReadUshort(IN PUSHORT Port)
519{
520 return READ_PORT_USHORT(Port);
521}
522
523DECLINLINE(ULONG) VBoxVideoCmnPortReadUlong(IN PULONG Port)
524{
525 return READ_PORT_ULONG(Port);
526}
527
528DECLINLINE(VOID) VBoxVideoCmnMemZero(PVOID pvMem, ULONG cbMem)
529{
530 memset(pvMem, 0, cbMem);
531}
532
533DECLINLINE(VOID) VBoxVideoCmnSpinLockAcquire(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock, OUT PVBOXVCMNIRQL OldIrql)
534{
535 KeAcquireSpinLock(SpinLock, OldIrql);
536}
537
538DECLINLINE(VOID) VBoxVideoCmnSpinLockAcquireAtDpcLevel(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
539{
540 KeAcquireSpinLockAtDpcLevel(SpinLock);
541}
542
543DECLINLINE(VOID) VBoxVideoCmnSpinLockRelease(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock, IN VBOXVCMNIRQL NewIrql)
544{
545 KeReleaseSpinLock(SpinLock, NewIrql);
546}
547
548DECLINLINE(VOID) VBoxVideoCmnSpinLockReleaseFromDpcLevel(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
549{
550 KeReleaseSpinLockFromDpcLevel(SpinLock);
551}
552
553DECLINLINE(VP_STATUS) VBoxVideoCmnSpinLockCreate(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
554{
555 KeInitializeSpinLock(SpinLock);
556 return NO_ERROR;
557}
558
559DECLINLINE(VP_STATUS) VBoxVideoCmnSpinLockDelete(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNSPIN_LOCK SpinLock)
560{
561 return NO_ERROR;
562}
563
564DECLINLINE(LONG) VBoxVideoCmnEventSet(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent)
565{
566 return KeSetEvent(pEvent, 0, FALSE);
567}
568
569DECLINLINE(VP_STATUS) VBoxVideoCmnEventCreateNotification(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent, IN BOOLEAN bSignaled)
570{
571 KeInitializeEvent(pEvent, NotificationEvent, bSignaled);
572 return NO_ERROR;
573}
574
575DECLINLINE(VP_STATUS) VBoxVideoCmnEventDelete(IN PDEVICE_EXTENSION pDeviceExtension, IN PVBOXVCMNEVENT pEvent)
576{
577 return NO_ERROR;
578}
579
580DECLINLINE(PVOID) VBoxVideoCmnMemAllocNonPaged(IN PDEVICE_EXTENSION pDeviceExtension, IN SIZE_T NumberOfBytes, IN ULONG Tag)
581{
582 return ExAllocatePoolWithTag(NonPagedPool, NumberOfBytes, Tag);
583}
584
585DECLINLINE(VOID) VBoxVideoCmnMemFree(IN PDEVICE_EXTENSION pDeviceExtension, IN PVOID Ptr)
586{
587 ExFreePool(Ptr);
588}
589
590VP_STATUS VBoxVideoCmnRegInit(IN PDEVICE_EXTENSION pDeviceExtension, OUT VBOXCMNREG *pReg);
591
592DECLINLINE(VP_STATUS) VBoxVideoCmnRegFini(IN VBOXCMNREG Reg)
593{
594 if(!Reg)
595 return ERROR_INVALID_PARAMETER;
596
597 NTSTATUS Status = ZwClose(Reg);
598 return Status == STATUS_SUCCESS ? NO_ERROR : ERROR_INVALID_PARAMETER;
599}
600
601VP_STATUS VBoxVideoCmnRegQueryDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t *pVal);
602
603VP_STATUS VBoxVideoCmnRegSetDword(IN VBOXCMNREG Reg, PWSTR pName, uint32_t Val);
604
605/* */
606
607RT_C_DECLS_BEGIN
608NTSTATUS
609DriverEntry(
610 IN PDRIVER_OBJECT DriverObject,
611 IN PUNICODE_STRING RegistryPath
612 );
613RT_C_DECLS_END
614
615typedef struct VBOXWDDM_VIDEOMODES
616{
617 VIDEO_MODE_INFORMATION *pModes;
618 uint32_t cModes;
619 D3DKMDT_2DREGION pResolutions;
620 uint32_t cResolutions;
621 int32_t iPreferrableMode;
622 int32_t iCustomMode;
623} VBOXWDDM_VIDEOMODES;
624
625VOID VBoxWddmGetModesTable(PDEVICE_EXTENSION DeviceExtension, bool bRebuildTable,
626 VIDEO_MODE_INFORMATION ** ppModes, uint32_t * pcModes, int32_t * pPreferrableMode,
627 D3DKMDT_2DREGION **ppResolutions, uint32_t * pcResolutions);
628
629void vboxVideoInitCustomVideoModes(PDEVICE_EXTENSION pDevExt);
630
631VOID VBoxWddmInvalidateModesTable(PDEVICE_EXTENSION DeviceExtension);
632
633/* @return STATUS_BUFFER_TOO_SMALL - if buffer is too small, STATUS_SUCCESS - on success */
634NTSTATUS VBoxWddmGetModesForResolution(PDEVICE_EXTENSION DeviceExtension, bool bRebuildTable,
635 D3DKMDT_2DREGION *pResolution,
636 VIDEO_MODE_INFORMATION * pModes, uint32_t cModes, uint32_t *pcModes, int32_t * piPreferrableMode);
637
638D3DDDIFORMAT vboxWddmCalcPixelFormat(VIDEO_MODE_INFORMATION *pInfo);
639
640DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PDEVICE_EXTENSION pDevExt)
641{
642#ifdef VBOXWDDM_RENDER_FROM_SHADOW
643 /* all memory layout info should be initialized */
644 Assert(pDevExt->aSources[0].Vbva.offVBVA);
645 /* page aligned */
646 Assert(!(pDevExt->aSources[0].Vbva.offVBVA & 0xfff));
647
648 return (ULONG)(pDevExt->aSources[0].Vbva.offVBVA & ~0xfffULL);
649#else
650 /* all memory layout info should be initialized */
651 Assert(pDevExt->u.primary.Vdma.CmdHeap.area.offBase);
652 /* page aligned */
653 Assert(!(pDevExt->u.primary.Vdma.CmdHeap.area.offBase & 0xfff));
654
655 return pDevExt->u.primary.Vdma.CmdHeap.area.offBase & ~0xfffUL;
656#endif
657}
658
659DECLINLINE(ULONG) vboxWddmVramCpuVisibleSegmentSize(PDEVICE_EXTENSION pDevExt)
660{
661 return vboxWddmVramCpuVisibleSize(pDevExt);
662}
663
664#ifdef VBOXWDDM_RENDER_FROM_SHADOW
665DECLINLINE(ULONG) vboxWddmVramCpuInvisibleSegmentSize(PDEVICE_EXTENSION pDevExt)
666{
667 return vboxWddmVramCpuVisibleSegmentSize(pDevExt);
668}
669
670DECLINLINE(bool) vboxWddmCmpSurfDescsBase(VBOXWDDM_SURFACE_DESC *pDesc1, VBOXWDDM_SURFACE_DESC *pDesc2)
671{
672 if (pDesc1->width != pDesc2->width)
673 return false;
674 if (pDesc1->height != pDesc2->height)
675 return false;
676 if (pDesc1->format != pDesc2->format)
677 return false;
678 if (pDesc1->bpp != pDesc2->bpp)
679 return false;
680 if (pDesc1->pitch != pDesc2->pitch)
681 return false;
682 return true;
683}
684
685DECLINLINE(void) vboxWddmAssignShadow(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
686{
687 if (pSource->pShadowAllocation == pAllocation)
688 {
689 Assert(pAllocation->bAssigned);
690 return;
691 }
692
693 if (pSource->pShadowAllocation)
694 {
695 PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pShadowAllocation;
696 /* clear the visibility info fo the current primary */
697 pOldAlloc->bVisible = FALSE;
698 pOldAlloc->bAssigned = FALSE;
699 Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
700 /* release the shadow surface */
701 pOldAlloc->SurfDesc.VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
702 }
703
704 if (pAllocation)
705 {
706 Assert(!pAllocation->bAssigned);
707 Assert(!pAllocation->bVisible);
708 pAllocation->bVisible = FALSE;
709 /* this check ensures the shadow is not used for other source simultaneously */
710 Assert(pAllocation->SurfDesc.VidPnSourceId == D3DDDI_ID_UNINITIALIZED);
711 pAllocation->SurfDesc.VidPnSourceId = srcId;
712 pAllocation->bAssigned = TRUE;
713 if (!vboxWddmCmpSurfDescsBase(&pSource->SurfDesc, &pAllocation->SurfDesc))
714 pSource->offVram = VBOXVIDEOOFFSET_VOID; /* force guest->host notification */
715 pSource->SurfDesc = pAllocation->SurfDesc;
716 }
717
718 pSource->pShadowAllocation = pAllocation;
719}
720#endif
721
722DECLINLINE(VOID) vboxWddmAssignPrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
723{
724 if (pSource->pPrimaryAllocation == pAllocation)
725 return;
726
727 if (pSource->pPrimaryAllocation)
728 {
729 PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pPrimaryAllocation;
730 /* clear the visibility info fo the current primary */
731 pOldAlloc->bVisible = FALSE;
732 pOldAlloc->bAssigned = FALSE;
733 Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
734 }
735
736 if (pAllocation)
737 {
738 pAllocation->bVisible = FALSE;
739 Assert(pAllocation->SurfDesc.VidPnSourceId == srcId);
740 pAllocation->SurfDesc.VidPnSourceId = srcId;
741 pAllocation->bAssigned = TRUE;
742 }
743
744 pSource->pPrimaryAllocation = pAllocation;
745}
746
747
748#endif
749
750void* vboxHGSMIBufferAlloc(PVBOXVIDEO_COMMON pCommon,
751 HGSMISIZE cbData,
752 uint8_t u8Ch,
753 uint16_t u16Op);
754void vboxHGSMIBufferFree (PVBOXVIDEO_COMMON pCommon, void *pvBuffer);
755int vboxHGSMIBufferSubmit (PVBOXVIDEO_COMMON pCommon, void *pvBuffer);
756
757BOOLEAN FASTCALL VBoxVideoSetCurrentModePerform(PDEVICE_EXTENSION DeviceExtension,
758 USHORT width, USHORT height, USHORT bpp
759#ifdef VBOX_WITH_WDDM
760 , ULONG offDisplay
761#endif
762 );
763
764BOOLEAN FASTCALL VBoxVideoSetCurrentMode(
765 PDEVICE_EXTENSION DeviceExtension,
766 PVIDEO_MODE RequestedMode,
767 PSTATUS_BLOCK StatusBlock);
768
769BOOLEAN FASTCALL VBoxVideoResetDevice(
770 PDEVICE_EXTENSION DeviceExtension,
771 PSTATUS_BLOCK StatusBlock);
772
773BOOLEAN FASTCALL VBoxVideoMapVideoMemory(
774 PDEVICE_EXTENSION DeviceExtension,
775 PVIDEO_MEMORY RequestedAddress,
776 PVIDEO_MEMORY_INFORMATION MapInformation,
777 PSTATUS_BLOCK StatusBlock);
778
779BOOLEAN FASTCALL VBoxVideoUnmapVideoMemory(
780 PDEVICE_EXTENSION DeviceExtension,
781 PVIDEO_MEMORY VideoMemory,
782 PSTATUS_BLOCK StatusBlock);
783
784BOOLEAN FASTCALL VBoxVideoQueryNumAvailModes(
785 PDEVICE_EXTENSION DeviceExtension,
786 PVIDEO_NUM_MODES Modes,
787 PSTATUS_BLOCK StatusBlock);
788
789BOOLEAN FASTCALL VBoxVideoQueryAvailModes(
790 PDEVICE_EXTENSION DeviceExtension,
791 PVIDEO_MODE_INFORMATION ReturnedModes,
792 PSTATUS_BLOCK StatusBlock);
793
794BOOLEAN FASTCALL VBoxVideoQueryCurrentMode(
795 PDEVICE_EXTENSION DeviceExtension,
796 PVIDEO_MODE_INFORMATION VideoModeInfo,
797 PSTATUS_BLOCK StatusBlock);
798
799BOOLEAN FASTCALL VBoxVideoSetColorRegisters(
800 PDEVICE_EXTENSION DeviceExtension,
801 PVIDEO_CLUT ColorLookUpTable,
802 PSTATUS_BLOCK StatusBlock);
803
804int VBoxMapAdapterMemory (PVBOXVIDEO_COMMON pCommon,
805 void **ppv,
806 ULONG ulOffset,
807 ULONG ulSize);
808
809void VBoxUnmapAdapterMemory (PDEVICE_EXTENSION PrimaryExtension,
810 void **ppv);
811void VBoxUnmapAdapterInformation (PDEVICE_EXTENSION PrimaryExtension);
812
813void VBoxComputeFrameBufferSizes (PDEVICE_EXTENSION PrimaryExtension);
814
815
816/*
817 * Host and Guest port IO helpers.
818 */
819DECLINLINE(void) VBoxHGSMIHostWrite(PVBOXVIDEO_COMMON pCommon, ULONG data)
820{
821 VBoxVideoCmnPortWriteUlong((PULONG)pCommon->IOPortHost, data);
822}
823
824DECLINLINE(ULONG) VBoxHGSMIHostRead(PVBOXVIDEO_COMMON pCommon)
825{
826 return VBoxVideoCmnPortReadUlong((PULONG)pCommon->IOPortHost);
827}
828
829DECLINLINE(void) VBoxHGSMIGuestWrite(PVBOXVIDEO_COMMON pCommon, ULONG data)
830{
831 VBoxVideoCmnPortWriteUlong((PULONG)pCommon->IOPortGuest, data);
832}
833
834DECLINLINE(ULONG) VBoxHGSMIGuestRead(PVBOXVIDEO_COMMON pCommon)
835{
836 return VBoxVideoCmnPortReadUlong((PULONG)pCommon->IOPortGuest);
837}
838
839BOOLEAN VBoxHGSMIIsSupported (void);
840
841typedef int FNHGSMIFILLVIEWINFO (void *pvData, VBVAINFOVIEW *pInfo);
842typedef FNHGSMIFILLVIEWINFO *PFNHGSMIFILLVIEWINFO;
843
844int VBoxHGSMISendViewInfo(PVBOXVIDEO_COMMON pCommon, uint32_t u32Count, PFNHGSMIFILLVIEWINFO pfnFill, void *pvData);
845
846VOID VBoxSetupDisplaysHGSMI (PDEVICE_EXTENSION PrimaryExtension,
847 ULONG AdapterMemorySize, uint32_t fCaps);
848BOOLEAN vboxUpdatePointerShape (PDEVICE_EXTENSION DeviceExtension,
849 PVIDEO_POINTER_ATTRIBUTES pointerAttr,
850 uint32_t cbLength);
851
852void VBoxFreeDisplaysHGSMI(PDEVICE_EXTENSION PrimaryExtension);
853#ifndef VBOX_WITH_WDDM
854DECLCALLBACK(void) hgsmiHostCmdComplete (HVBOXVIDEOHGSMI hHGSMI, struct _VBVAHOSTCMD * pCmd);
855DECLCALLBACK(int) hgsmiHostCmdRequest (HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, struct _VBVAHOSTCMD ** ppCmd);
856#endif
857
858
859int vboxVBVAChannelDisplayEnable(PDEVICE_EXTENSION PrimaryExtension,
860 int iDisplay, /* negative would mean this is a miniport handler */
861 uint8_t u8Channel);
862
863void hgsmiProcessHostCommandQueue(PVBOXVIDEO_COMMON pCommon);
864
865void HGSMIClearIrq (PVBOXVIDEO_COMMON pCommon);
866
867} /* extern "C" */
868
869#endif /* VBOXVIDEO_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