VirtualBox

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

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

wddm/3d: multi-swapchain fixes (for win7 & multi-monitor)

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