VirtualBox

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

Last change on this file since 28475 was 28382, checked in by vboxsync, 15 years ago

wddm: correctly report framebuffer offset to VGA device

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