VirtualBox

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

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

wddm: multimonitor support

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