VirtualBox

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

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