VirtualBox

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

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

wddm/2d: 2D video accel support fixes

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette