VirtualBox

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

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

VBoxVideo: When unmapping adapter memory, make sure interrupt handler will not blow up.

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