VirtualBox

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

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

wddm/2d: notify host on color fill FB update, bugfix

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